LRESULT CErrorReportDlg::OnCompleteCollectCrashInfo(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // This method is called when the worker thread has finished with collection // of crash report data. Now we display the "Error Report" dialog // and offer user to send error report. CErrorReportSender* pSender = CErrorReportSender::GetInstance(); if(pSender->GetCrashInfo()->m_bSendErrorReport) // If we should send error report now { // Get the total size of the report. LONG64 lTotalSize = pSender->GetCrashInfo()->GetReport(0)->GetTotalSize(); CString sTotalSize = Utility::FileSizeToStr(lTotalSize); // Format the text for dialog subheader. CString sSubHeader; sSubHeader.Format(pSender->GetLangStr(_T("MainDlg"), _T("SubHeaderText")), sTotalSize); // Update the subheader text m_statSubHeader.SetWindowText(sSubHeader); // Show "Error Report" dialog ShowWindow(SW_SHOW); } else // If we shouldn't send error report now. { // Exit the app. SendMessage(WM_CLOSE); } return 0; }
LRESULT CVideoRecDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { m_statText = GetDlgItem(IDC_TEXT); m_btnAllow = GetDlgItem(IDOK); m_btnCancel = GetDlgItem(IDCANCEL); CErrorReportSender* pSender = CErrorReportSender::GetInstance(); // Set dialog caption. CString sMsg; sMsg.Format(pSender->GetLangStr(_T("VideoRecDlg"), _T("DlgCaption")), pSender->GetCrashInfo()->m_sAppName); SetWindowText(sMsg); sMsg.Format(pSender->GetLangStr(_T("VideoRecDlg"), _T("Text")), pSender->GetCrashInfo()->m_sAppName); m_statText.SetWindowText(sMsg); m_btnAllow.SetWindowText(pSender->GetLangStr(_T("VideoRecDlg"), _T("Allow"))); m_btnCancel.SetWindowText(pSender->GetLangStr(_T("VideoRecDlg"), _T("Cancel"))); // Center the dialog on the screen. CenterWindow(); return TRUE; }
void CDetailDlg::FillFileItemList() { // Walk through files included into error report // Insert items to the list m_iconList.RemoveAll(); m_list.DeleteAllItems(); CErrorReportSender* pSender = CErrorReportSender::GetInstance(); int nCount = pSender->GetCrashInfo()->GetReport(m_nCurReport)->GetFileItemCount(); int i; for (i = 0; i<nCount; i++) { ERIFileItem* pfi = pSender->GetCrashInfo()->GetReport(m_nCurReport)->GetFileItemByIndex(i); CString sDestFile = pfi->m_sDestFile; CString sSrcFile = pfi->m_sSrcFile; CString sFileDesc = pfi->m_sDesc; HICON hIcon = NULL; CString sTypeName; LONGLONG lFileSize = 0; CString sSize; // Get file info pfi->GetFileInfo(hIcon, sTypeName, lFileSize); int iImage = -1; if(hIcon!=NULL) { // If icon loaded, add its copy to imagelist iImage = m_iconList.AddIcon(hIcon); // and destroy the original icon. DestroyIcon(hIcon); } // Insert an item to the list control int nItem = m_list.InsertItem(i, sDestFile, iImage); m_list.SetItemData(nItem, i); m_list.SetItemText(nItem, 1, sFileDesc); sSize = Utility::FileSizeToStr(lFileSize); m_list.SetItemText(nItem, 2, sSize); } // Select the first list item m_list.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED); }
void CProgressDlg::Start(BOOL bCollectInfo, BOOL bMakeVisible) { // This method displays the progress dialog and starts the timer // that will update the dialog periodically and react on // incoming events. CErrorReportSender* pSender = CErrorReportSender::GetInstance(); // Set up correct dialog caption if(bCollectInfo) { CString sCaption; sCaption.Format(pSender->GetLangStr(_T("ProgressDlg"), _T("DlgCaption2")), pSender->GetCrashInfo()->m_sAppName); SetWindowText(sCaption); } else { CString sCaption; sCaption.Format(pSender->GetLangStr(_T("ProgressDlg"), _T("DlgCaption")), pSender->GetCrashInfo()->m_sAppName); SetWindowText(sCaption); } // Show the window on top of other windows SetWindowPos(HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); // Center the dialog on the screen CenterWindow(); // Check if we need to make the dialog visible if(bMakeVisible) { // Show the dialog and set focus on it ShowWindow(SW_SHOW); SetFocus(); } if(!bCollectInfo) { // If we are not collecting crash information now, than hide this dialog in 3 sec. SetTimer(1, 3000); } // Update this dialog each 200 ms. SetTimer(0, 200); // If user clicks the Close button (x), do not close the window. m_ActionOnCancel = DONT_CLOSE; }
LRESULT CDetailDlg::OnItemDblClicked(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) { // This method is called when user double-clicks an item in the list control. // We need to open the file with an appropriate program. LPNMLISTVIEW lpItem = (LPNMLISTVIEW)pnmh; int iItem = lpItem->iItem; DWORD_PTR dwRet = 0; CErrorReportSender* pSender = CErrorReportSender::GetInstance(); CCrashInfoReader* pCrashInfo = pSender->GetCrashInfo(); // Check if double-clicked on empty space. if (iItem < 0) { // Do nothing return 0; } // Look for n-th item ERIFileItem* pFileItem = pCrashInfo->GetReport(m_nCurReport)->GetFileItemByIndex(iItem); if(pFileItem==NULL) return 0; // Get file name CString sFileName = pFileItem->m_sSrcFile; // Open the file with shell-provided functionality dwRet = (DWORD_PTR)::ShellExecute(0, _T("open"), sFileName, 0, 0, SW_SHOWNORMAL); ATLASSERT(dwRet > 32); return 0; }
LRESULT CDetailDlg::OnExport(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { // This method is called when user clicks the "Export" button. // We should export crash report contents as a ZIP archive to // user-specified folder. CErrorReportSender* pSender = CErrorReportSender::GetInstance(); CCrashInfoReader* pCrashInfo = pSender->GetCrashInfo(); // Format file name for the output ZIP archive. CString sFileName = pCrashInfo->GetReport(m_nCurReport)->GetCrashGUID() + _T(".zip"); // Display "Save File" dialog. CFileDialog dlg(FALSE, _T("*.zip"), sFileName, OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT, _T("ZIP Files (*.zip)\0*.zip\0All Files (*.*)\0*.*\0\0"), m_hWnd); INT_PTR result = dlg.DoModal(); if(result==IDOK) { // Determine what destination user chosen CString sExportFileName = dlg.m_szFileName; // Export crash report assynchronously pSender->ExportReport(sExportFileName); } return 0; }
LRESULT CErrorReportDlg::OnPopupSendReportLater(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { // User has clicked the popup menu's "Close the program and send report later". // Update our remind policy to "Remind me later". CErrorReportSender* pSender = CErrorReportSender::GetInstance(); pSender->GetCrashInfo()->SetRemindPolicy(REMIND_LATER); CloseDialog(wID); return 0; }
LRESULT CErrorReportDlg::OnSendClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { // This method is called when user clicks the "Send Report" button TCHAR szBuffer[1024] = _T(""); CString sEmail; CString sDesc; // Get E-mail field's text m_editEmail.GetWindowText(szBuffer, 1024); sEmail = szBuffer; // Get description field's text m_editDesc.GetWindowText(szBuffer, 1024); sDesc = szBuffer; // Update those fields in crash report data and check the result CErrorReportSender* pSender = CErrorReportSender::GetInstance(); if(!pSender->GetCrashInfo()->UpdateUserInfo(sEmail, sDesc)) { // Failure - display alert message and repeat again // Check window mirroring settings DWORD dwFlags = 0; CString sRTL = pSender->GetLangStr(_T("Settings"), _T("RTLReading")); if(sRTL.CompareNoCase(_T("1"))==0) dwFlags = MB_RTLREADING; // Alert user MessageBox( pSender->GetLangStr(_T("MainDlg"), _T("InvalidEmailText")), pSender->GetLangStr(_T("MainDlg"), _T("InvalidEmailCaption")), MB_OK|dwFlags); // Set focus to Email field ::SetFocus(m_editEmail); return 0; } /* Now we are ready to send error report in background. */ // Hide the dialog ShowWindow(SW_HIDE); // Display tray icon CreateTrayIcon(true, m_hWnd); // Show progress dialog m_dlgProgress.Start(FALSE); // Run worker thread that will compress and send error report. pSender->Run(); return 0; }
LRESULT CErrorReportDlg::OnPopupCloseTheProgram(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { // User has clicked the popup menu's "Close the program". CErrorReportSender* pSender = CErrorReportSender::GetInstance(); // The following line will prevent from queueing the report pSender->GetCrashInfo()->m_bQueueEnabled = FALSE; CloseDialog(wID); return 0; }
LRESULT CErrorReportDlg::OnRestartClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { // This method is called when user clicks the "Restart the application" checkbox. // Determine checkbox state BOOL bRestart = m_chkRestart.GetCheck()==BST_CHECKED?TRUE:FALSE; // Update the restart flag CErrorReportSender* pSender = CErrorReportSender::GetInstance(); pSender->GetCrashInfo()->m_bAppRestart = bRestart; return 0; }
LRESULT CDetailDlg::OnPopupDeleteSelected(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { CErrorReportSender* pSender = CErrorReportSender::GetInstance(); // Walk through selected list items std::vector<CString> asFilesToRemove; int i; for(i=0; i<m_list.GetItemCount(); i++) { // If list item is not selected if(m_list.GetItemState(i, LVIS_SELECTED)==0) continue; // Determine appropriate file item int nItem = (int)m_list.GetItemData(i); ERIFileItem* pfi = pSender->GetCrashInfo()->GetReport(m_nCurReport)->GetFileItemByIndex(nItem); if(pfi) { // Add this file to remove list asFilesToRemove.push_back(pfi->m_sDestFile); } } // Reset preview control to avoid locking the file being previewed. m_filePreview.SetFile(NULL); // Delete selected files from error report pSender->GetCrashInfo()->RemoveFilesFromCrashReport(m_nCurReport, asFilesToRemove); // Update file items list FillFileItemList(); // Force parent to recalculate report size HWND hWndParent = GetParent(); if(::IsWindow(hWndParent)) ::SendMessage(hWndParent, WM_REPORTSIZECHANGED, m_nCurReport, 0); return 0; }
LRESULT CProgressDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // Check if current UI language is an RTL language CErrorReportSender* pSender = CErrorReportSender::GetInstance(); CString sRTL = pSender->GetLangStr(_T("Settings"), _T("RTLReading")); if(sRTL.CompareNoCase(_T("1"))==0) { // Mirror this window Utility::SetLayoutRTL(m_hWnd); } HICON hIcon = NULL; // Try to load custom icon hIcon = pSender->GetCrashInfo()->GetCustomIcon(); // If there is no custom icon, load the default one if(hIcon==NULL) hIcon = ::LoadIcon(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME)); // Set dialog icon SetIcon(hIcon, FALSE); SetIcon(hIcon, TRUE); // Set status text m_statText = GetDlgItem(IDC_TEXT); m_statText.SetWindowText(pSender->GetLangStr(_T("ProgressDlg"), _T("CollectingCrashInfo"))); // Set progress bar style m_prgProgress = GetDlgItem(IDC_PROGRESS); m_prgProgress.SetRange(0, 100); m_prgProgress.ModifyStyle(0, PBS_MARQUEE); // Set up list view m_listView = GetDlgItem(IDC_LIST); m_listView.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); m_listView.InsertColumn(0, _T("Status"), LVCFMT_LEFT, 2048); // Set up Cancel button m_btnCancel = GetDlgItem(IDCANCEL); m_btnCancel.SetWindowText(pSender->GetLangStr(_T("ProgressDlg"), _T("Cancel"))); // Init flags m_ActionOnCancel = DONT_CLOSE; m_ActionOnClose = CLOSE_MYSELF; // Init dialog resize functionality DlgResize_Init(); return TRUE; }
LRESULT CErrorReportDlg::OnEraseBkgnd(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // Here we want to draw a white header of the dialog CErrorReportSender* pSender = CErrorReportSender::GetInstance(); CDCHandle dc((HDC)wParam); RECT rcClient; GetClientRect(&rcClient); RECT rc; CStatic statUpperHorzLine = GetDlgItem(IDC_UPPERHORZ); statUpperHorzLine.GetWindowRect(&rc); ScreenToClient(&rc); COLORREF cr = GetSysColor(COLOR_3DFACE); CBrush brush; brush.CreateSolidBrush(cr); RECT rcHeading = {0, 0, rcClient.right, rc.bottom}; dc.FillRect(&rcHeading, (HBRUSH)GetStockObject(WHITE_BRUSH)); RECT rcBody = {0, rc.bottom, rcClient.right, rcClient.bottom}; dc.FillRect(&rcBody, brush); rcHeading.left = 60; rcHeading.right -= 10; // Draw header text over background CString sHeading; sHeading.Format(pSender->GetLangStr(_T("MainDlg"), _T("HeaderText")), pSender->GetCrashInfo()->m_sAppName); dc.SelectFont(m_HeadingFont); dc.DrawTextEx(sHeading.GetBuffer(0), sHeading.GetLength(), &rcHeading, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS); // Check if we should draw the icon on the header area if(m_HeadingIcon) { // Draw the icon left to the text ICONINFO ii; m_HeadingIcon.GetIconInfo(&ii); dc.DrawIcon(16, rcHeading.bottom/2 - ii.yHotspot, m_HeadingIcon); } return TRUE; }
LRESULT CErrorReportDlg::OnReportSizeChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { CErrorReportSender* pSender = CErrorReportSender::GetInstance(); // Get the total size of the report. LONG64 lTotalSize = pSender->GetCrashInfo()->GetReport(0)->GetTotalSize(); CString sTotalSize = Utility::FileSizeToStr(lTotalSize); // Format the text for dialog subheader. CString sSubHeader; sSubHeader.Format(pSender->GetLangStr(_T("MainDlg"), _T("SubHeaderText")), sTotalSize); // Update the subheader text m_statSubHeader.SetWindowText(sSubHeader); return 0; }
void CDetailDlg::SelectItem(int iItem) { // This method is called when user selects an item. // We need to open the item for preview. CErrorReportSender* pSender = CErrorReportSender::GetInstance(); CCrashInfoReader* pCrashInfo = pSender->GetCrashInfo(); // Look for n-th item ERIFileItem* pFileItem = pCrashInfo->GetReport(m_nCurReport)->GetFileItemByIndex(iItem); if(pFileItem==NULL) return; // Update preview control m_previewMode = PREVIEW_AUTO; m_textEncoding = ENC_AUTO; m_filePreview.SetFile(pFileItem->m_sSrcFile, m_previewMode); }
LRESULT CErrorReportDlg::OnEmailKillFocus(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { // This method is called when user removes focus from "Your E-mail" field. TCHAR szBuffer[1024] = _T(""); CString sEmail; CString sDesc; // Get E-mail field's text m_editEmail.GetWindowText(szBuffer, 1024); sEmail = szBuffer; // Get description field's text m_editDesc.GetWindowText(szBuffer, 1024); sDesc = szBuffer; // Update those fields in crash report data CErrorReportSender* pSender = CErrorReportSender::GetInstance(); pSender->GetCrashInfo()->UpdateUserInfo(sEmail, sDesc); return 0; }
LRESULT CErrorReportDlg::OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { // This method is called when user clicks "Close the program" or "Other actions..." button // (the button is the same, its caption may differ) CErrorReportSender* pSender = CErrorReportSender::GetInstance(); if(pSender->GetCrashInfo()->m_bQueueEnabled) { // Show popup menu on "Other actions..." button click. CPoint pt; GetCursorPos(&pt); CMenu menu = LoadMenu(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_POPUPMENU)); CMenu submenu = menu.GetSubMenu(4); strconv_t strconv; CString sSendLater = pSender->GetLangStr(_T("MainDlg"), _T("SendReportLater")); CString sCloseTheProgram = pSender->GetLangStr(_T("MainDlg"), _T("CloseTheProgram")); MENUITEMINFO mii; memset(&mii, 0, sizeof(MENUITEMINFO)); mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_STRING; mii.dwTypeData = sSendLater.GetBuffer(0); submenu.SetMenuItemInfo(ID_MENU5_SENDREPORTLATER, FALSE, &mii); mii.dwTypeData = sCloseTheProgram.GetBuffer(0); submenu.SetMenuItemInfo(ID_MENU5_CLOSETHEPROGRAM, FALSE, &mii); submenu.TrackPopupMenu(0, pt.x, pt.y, m_hWnd); } else // "Close the program" button clicked { // Close dialog. CloseDialog(wID); } return 0; }
LRESULT CDetailDlg::OnPopupOpen(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { CErrorReportSender* pSender = CErrorReportSender::GetInstance(); CCrashInfoReader* pCrashInfo = pSender->GetCrashInfo(); // Get count of selected list items int nItem = -1; int nSelected = 0; int i; for(i=0; i<m_list.GetItemCount(); i++) { // If list item selected if(m_list.GetItemState(i, LVIS_SELECTED)!=0) { nItem=i; nSelected++; } } if(nSelected!=1) return 0; // Should be exactly one item selected // Look for n-th item ERIFileItem* pFileItem = pCrashInfo->GetReport(m_nCurReport)->GetFileItemByIndex(nItem); if(pFileItem==NULL) return 0; // Get file name CString sFileName = pFileItem->m_sSrcFile; // Open the file with shell-provided functionality DWORD_PTR dwRet = (DWORD_PTR)::ShellExecute(0, _T("open"), sFileName, 0, 0, SW_SHOWNORMAL); ATLASSERT(dwRet > 32); dwRet; return 0; }
int CErrorReportDlg::CreateTrayIcon(bool bCreate, HWND hWndParent) { // This method creates (bCreate==TRUE) or destroys (bCreate==FALSE) // the tray icon. CErrorReportSender* pSender = CErrorReportSender::GetInstance(); // Prepare icon info NOTIFYICONDATA nf; memset(&nf,0,sizeof(NOTIFYICONDATA)); nf.cbSize = sizeof(NOTIFYICONDATA); nf.hWnd = hWndParent; nf.uID = 0; if(bCreate==true) // add icon to tray { nf.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; nf.uCallbackMessage = WM_TRAYICON; #if _MSC_VER>=1300 nf.uVersion = NOTIFYICON_VERSION; #endif // Try to load custom icon HICON hIcon = pSender->GetCrashInfo()->GetCustomIcon(); if(hIcon==NULL) hIcon = ::LoadIcon(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME)); nf.hIcon = hIcon; _TCSCPY_S(nf.szTip, 128, _T("Sending Error Report")); Shell_NotifyIcon(NIM_ADD, &nf); } else // delete icon { Shell_NotifyIcon(NIM_DELETE, &nf); } return 0; }
LRESULT CProgressDlg::OnTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // This method is called when a timer ticks. WORD wTimerId = (WORD)wParam; CErrorReportSender* pSender = CErrorReportSender::GetInstance(); if(wTimerId==0) // Dialog update timer { // Get current progress int nProgressPct = 0; std::vector<CString> messages; pSender->GetCurOpStatus(nProgressPct, messages); // Update progress bar m_prgProgress.SetPos(nProgressPct); int attempt = 0; // Sending attempt // Walk through incoming messages and look for special ones (enclosed in [ ]) unsigned i; for(i=0; i<messages.size(); i++) { if(messages[i].CompareNoCase(_T("[creating_dump]"))==0) { // Creating minidump m_ActionOnCancel = DONT_CLOSE; m_ActionOnClose = CLOSE_MYSELF_AND_PARENT; m_statText.SetWindowText(pSender->GetLangStr(_T("ProgressDlg"), _T("CollectingCrashInfo"))); } else if(messages[i].CompareNoCase(_T("[copying_files]"))==0) { // Copying files m_ActionOnCancel = DONT_CLOSE; m_ActionOnClose = CLOSE_MYSELF_AND_PARENT; // Remove marquee style from progress bar m_prgProgress.ModifyStyle(PBS_MARQUEE, 0); } else if(messages[i].CompareNoCase(_T("[confirm_send_report]"))==0) { // User should consent to send error report, so we hide this dialog // and send a message to our parent dialog that will receive user input. m_ActionOnCancel = CLOSE_MYSELF_AND_PARENT; ShowWindow(SW_HIDE); HWND hWndParent = ::GetParent(m_hWnd); ::PostMessage(hWndParent, WM_COMPLETECOLLECT, 0, 0); } else if(messages[i].CompareNoCase(_T("[exporting_report]"))==0) { // Exporting error report as a ZIP archive m_ActionOnCancel = DONT_CLOSE; m_ActionOnClose = DONT_CLOSE; CString sCaption; sCaption.Format(pSender->GetLangStr(_T("ProgressDlg"), _T("DlgCaptionExport")), pSender->GetCrashInfo()->m_sAppName); SetWindowText(sCaption); m_statText.SetWindowText(pSender->GetLangStr(_T("ProgressDlg"), _T("CompressingFiles"))); m_btnCancel.SetWindowText(pSender->GetLangStr(_T("ProgressDlg"), _T("Cancel"))); ShowWindow(SW_SHOW); } else if(messages[i].CompareNoCase(_T("[end_exporting_report_ok]"))==0) { // End exporting error report m_ActionOnCancel = CLOSE_MYSELF; ShowWindow(SW_HIDE); } else if(messages[i].CompareNoCase(_T("[end_exporting_report_failed]"))==0) { // Failed to export error report m_ActionOnCancel = CLOSE_MYSELF; m_ActionOnClose = CLOSE_MYSELF; m_statText.SetWindowText(pSender->GetLangStr(_T("ProgressDlg"), _T("ExportedWithErrors"))); m_btnCancel.EnableWindow(1); m_btnCancel.SetWindowText(pSender->GetLangStr(_T("ProgressDlg"), _T("Close"))); } else if(messages[i].CompareNoCase(_T("[compressing_files]"))==0) { // Compressing error report files m_ActionOnCancel = DONT_CLOSE; m_ActionOnClose = CLOSE_MYSELF; m_statText.SetWindowText(pSender->GetLangStr(_T("ProgressDlg"), _T("CompressingFiles"))); m_btnCancel.SetWindowText(pSender->GetLangStr(_T("ProgressDlg"), _T("Cancel"))); } else if(messages[i].CompareNoCase(_T("[end_compressing_files]"))==0) { // File compression finished if(!pSender->GetCrashInfo()->m_bSendErrorReport && pSender->GetCrashInfo()->m_bStoreZIPArchives) { m_ActionOnCancel = CLOSE_MYSELF; m_ActionOnClose = CLOSE_MYSELF; HWND hWndParent = ::GetParent(m_hWnd); ::PostMessage(hWndParent, WM_CLOSE, 0, 0); } } else if(messages[i].CompareNoCase(_T("[status_success]"))==0) { // Error report has been delivered ok m_ActionOnCancel = CLOSE_MYSELF_AND_PARENT; m_ActionOnClose = CLOSE_MYSELF_AND_PARENT; // Close the parent dialog. HWND hWndParent = ::GetParent(m_hWnd); ::PostMessage(hWndParent, WM_CLOSE, 0, 0); } else if(messages[i].CompareNoCase(_T("[status_failed]"))==0) { // Error report delivery has failed m_ActionOnCancel = CLOSE_MYSELF_AND_PARENT; m_ActionOnClose = CLOSE_MYSELF_AND_PARENT; // Stop timer KillTimer(1); // Update status text. m_statText.SetWindowText(pSender->GetLangStr(_T("ProgressDlg"), _T("CompletedWithErrors"))); // Enable "Close" button m_btnCancel.EnableWindow(1); m_btnCancel.SetWindowText(pSender->GetLangStr(_T("ProgressDlg"), _T("Close"))); // Show the dialog ShowWindow(SW_SHOW); } else if(messages[i].CompareNoCase(_T("[exit_silently]"))==0) { // Silent exit m_ActionOnCancel = CLOSE_MYSELF_AND_PARENT; m_ActionOnClose = CLOSE_MYSELF_AND_PARENT; // Stop timer KillTimer(1); // Close the parent dialog. HWND hWndParent = ::GetParent(m_hWnd); ::PostMessage(hWndParent, WM_CLOSE, 0, 0); } else if(messages[i].CompareNoCase(_T("[cancelled_by_user]"))==0) { // The operation was cancelled by user m_statText.SetWindowText(pSender->GetLangStr(_T("ProgressDlg"), _T("Cancelling"))); } else if(messages[i].CompareNoCase(_T("[sending_attempt]"))==0) { // Trying to send error report using another method attempt ++; CString str; str.Format(pSender->GetLangStr(_T("ProgressDlg"), _T("StatusText")), attempt); m_statText.SetWindowText(str); } else if(messages[i].CompareNoCase(_T("[confirm_launch_email_client]"))==0) { // User should confirm he allows to launch email client KillTimer(1); // Show the dialog ShowWindow(SW_SHOW); // Determine window mirroring settings. DWORD dwFlags = 0; CString sRTL = pSender->GetLangStr(_T("Settings"), _T("RTLReading")); if(sRTL.CompareNoCase(_T("1"))==0) dwFlags = MB_RTLREADING; // Display the message box, so user to be able to confirm. CString sMailClientName; CMailMsg::DetectMailClient(sMailClientName); CString msg; msg.Format(pSender->GetLangStr(_T("ProgressDlg"), _T("ConfirmLaunchEmailClient")), sMailClientName); CString sCaption = pSender->GetLangStr(_T("ProgressDlg"), _T("DlgCaption")); CString sTitle; sTitle.Format(sCaption, pSender->GetCrashInfo()->m_sAppName); INT_PTR result = MessageBox(msg, sTitle, MB_OKCANCEL|MB_ICONQUESTION|dwFlags); // Unblock worker thread. pSender->FeedbackReady(result==IDOK?0:1); // Hide the dialog ShowWindow(SW_HIDE); } // Ensure the last item of the log is visible int count = m_listView.GetItemCount(); int indx = m_listView.InsertItem(count, messages[i]); m_listView.EnsureVisible(indx, TRUE); } } else if(wTimerId==1) // The timer that hides this window { // Hide the window smoothly AnimateWindow(m_hWnd, 200, AW_HIDE|AW_BLEND); // Stop the timer KillTimer(1); } return 0; }
LRESULT CDetailDlg::OnPopupAddMoreFiles(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { // Display "Open File" dialog. CFileDialog dlg(TRUE, _T("*.*"), NULL, OFN_PATHMUSTEXIST|OFN_ALLOWMULTISELECT, _T("All Files (*.*)\0*.*\0\0"), m_hWnd); INT_PTR result = dlg.DoModal(); if(result==IDOK) { // Parse the list of files TCHAR* str = dlg.m_ofn.lpstrFile; std::vector<CString> asItems; CString sItem; int i; for(i=0; ; i++) { if(str[i]==0) { // End of item if(sItem.IsEmpty()) break; // End of multi-string asItems.push_back(sItem); sItem.Empty(); continue; } sItem += str[i]; } std::vector<ERIFileItem> aFiles; if(asItems.size()==1) { // Single file to add CString sFileName = asItems[0]; ERIFileItem fi; fi.m_bAllowDelete = true; fi.m_bMakeCopy = true; fi.m_sDestFile = Utility::GetFileName(sFileName); fi.m_sSrcFile = sFileName; aFiles.push_back(fi); } else if(asItems.size()>1) { // Several files to add unsigned j; for(j=1; j<asItems.size(); j++) { CString sFileName = asItems[0]+_T("\\")+asItems[j]; ERIFileItem fi; fi.m_bAllowDelete = true; fi.m_bMakeCopy = true; fi.m_sDestFile = Utility::GetFileName(sFileName); fi.m_sSrcFile = sFileName; aFiles.push_back(fi); } } // Add files to crash report CErrorReportSender* pSender = CErrorReportSender::GetInstance(); CCrashInfoReader* pCrashInfo = pSender->GetCrashInfo(); pCrashInfo->AddFilesToCrashReport(m_nCurReport, aFiles); // Update file items list FillFileItemList(); // Force parent to recalculate report size HWND hWndParent = GetParent(); if(::IsWindow(hWndParent)) ::SendMessage(hWndParent, WM_REPORTSIZECHANGED, m_nCurReport, 0); } return 0; }
LRESULT CDetailDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // The dialog will be resizable, init resize map now. DlgResize_Init(); CErrorReportSender* pSender = CErrorReportSender::GetInstance(); // Mirror this window if RTL language is in use CString sRTL = pSender->GetLangStr(_T("Settings"), _T("RTLReading")); if(sRTL.CompareNoCase(_T("1"))==0) { Utility::SetLayoutRTL(m_hWnd); } // Set dialog caption text. SetWindowText(pSender->GetLangStr(_T("DetailDlg"), _T("DlgCaption"))); // Set up file preview control. m_previewMode = PREVIEW_AUTO; m_filePreview.SubclassWindow(GetDlgItem(IDC_PREVIEW)); m_filePreview.SetBytesPerLine(10); m_filePreview.SetEmptyMessage(pSender->GetLangStr(_T("DetailDlg"), _T("NoDataToDisplay"))); // Init "Privacy Policy" link. m_linkPrivacyPolicy.SubclassWindow(GetDlgItem(IDC_PRIVACYPOLICY)); m_linkPrivacyPolicy.SetHyperLink(pSender->GetCrashInfo()->m_sPrivacyPolicyURL); m_linkPrivacyPolicy.SetLabel(pSender->GetLangStr(_T("DetailDlg"), _T("PrivacyPolicy"))); if(!pSender->GetCrashInfo()->m_sPrivacyPolicyURL.IsEmpty()) m_linkPrivacyPolicy.ShowWindow(SW_SHOW); else m_linkPrivacyPolicy.ShowWindow(SW_HIDE); // Set up header text CStatic statHeader = GetDlgItem(IDC_HEADERTEXT); statHeader.SetWindowText(pSender->GetLangStr(_T("DetailDlg"), _T("DoubleClickAnItem"))); // Set up the list control m_list = GetDlgItem(IDC_FILE_LIST); m_list.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); m_list.InsertColumn(0, pSender->GetLangStr(_T("DetailDlg"), _T("FieldName")), LVCFMT_LEFT, 150); m_list.InsertColumn(1, pSender->GetLangStr(_T("DetailDlg"), _T("FieldDescription")), LVCFMT_LEFT, 180); m_list.InsertColumn(3, pSender->GetLangStr(_T("DetailDlg"), _T("FieldSize")), LVCFMT_RIGHT, 60); // Init icons for the list m_iconList.Create(16, 16, ILC_COLOR32|ILC_MASK, 3, 1); m_list.SetImageList(m_iconList, LVSIL_SMALL); FillFileItemList(); // Init "Preview" static control m_statPreview = GetDlgItem(IDC_PREVIEWTEXT); m_statPreview.SetWindowText(pSender->GetLangStr(_T("DetailDlg"), _T("Preview"))); // Init "OK" button m_btnClose = GetDlgItem(IDOK); m_btnClose.SetWindowText(pSender->GetLangStr(_T("DetailDlg"), _T("Close"))); // Init "Export..." button m_btnExport = GetDlgItem(IDC_EXPORT); m_btnExport.SetWindowText(pSender->GetLangStr(_T("DetailDlg"), _T("Export"))); // center the dialog on the screen CenterWindow(); return TRUE; }
LRESULT CDetailDlg::OnListRClick(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) { CErrorReportSender* pSender = CErrorReportSender::GetInstance(); CPoint pt; GetCursorPos(&pt); CMenu menu = LoadMenu(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_POPUPMENU)); CMenu submenu = menu.GetSubMenu(6); strconv_t strconv; CString sOpen = pSender->GetLangStr(_T("DetailDlg"), _T("Open")); CString sDeleteSelected = pSender->GetLangStr(_T("DetailDlg"), _T("DeleteSelected")); CString sAttachMoreFiles = pSender->GetLangStr(_T("DetailDlg"), _T("AttachMoreFiles")); MENUITEMINFO mii; memset(&mii, 0, sizeof(MENUITEMINFO)); mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_STRING; mii.dwTypeData = sOpen.GetBuffer(0); submenu.SetMenuItemInfo(ID_MENU7_OPEN, FALSE, &mii); mii.dwTypeData = sDeleteSelected.GetBuffer(0); submenu.SetMenuItemInfo(ID_MENU7_DELETESELECTEDFILE, FALSE, &mii); mii.dwTypeData = sAttachMoreFiles.GetBuffer(0); submenu.SetMenuItemInfo(ID_MENU7_ATTACHMOREFILES, FALSE, &mii); // Get count of selected list items int nItems = 0; int nSelected = 0; BOOL bAllowDelete = TRUE; int i; for(i=0; i<m_list.GetItemCount(); i++) { nItems++; // If list item checked if(m_list.GetItemState(i, LVIS_SELECTED)!=0) nSelected++; else continue; // Find file item in error report int nItem = (int)m_list.GetItemData(i); ERIFileItem* pfi = pSender->GetCrashInfo()->GetReport(m_nCurReport)->GetFileItemByIndex(nItem); if(!pfi->m_bAllowDelete) bAllowDelete = FALSE; } submenu.EnableMenuItem(ID_MENU7_OPEN, (nSelected==1)?MF_ENABLED:MF_DISABLED); submenu.EnableMenuItem(ID_MENU7_DELETESELECTEDFILE, (nSelected>0 && bAllowDelete)?MF_ENABLED:MF_DISABLED); if(!pSender->GetCrashInfo()->m_bAllowAttachMoreFiles) { submenu.DeleteMenu(ID_MENU7_ATTACHMOREFILES, MF_BYCOMMAND); } submenu.TrackPopupMenu(0, pt.x, pt.y, m_hWnd); return 0; }
LRESULT CErrorReportDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { CErrorReportSender* pSender = CErrorReportSender::GetInstance(); CCrashInfoReader* pCrashInfo = pSender->GetCrashInfo(); // Mirror this window if RTL language is in use. CString sRTL = pSender->GetLangStr(_T("Settings"), _T("RTLReading")); if(sRTL.CompareNoCase(_T("1"))==0) { Utility::SetLayoutRTL(m_hWnd); } // Set dialog caption. SetWindowText(pSender->GetLangStr(_T("MainDlg"), _T("DlgCaption"))); // Center the dialog on the screen. CenterWindow(); HICON hIcon = NULL; // Get custom icon. hIcon = pCrashInfo->GetCustomIcon(); if(hIcon==NULL) { // Use default icon, if custom icon is not provided. hIcon = ::LoadIcon(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME)); } // Set window icon. SetIcon(hIcon, 0); // Get the first icon in the EXE image and use it for header. m_HeadingIcon = ExtractIcon(NULL, pCrashInfo->GetReport(0)->GetImageName(), 0); // If there is no icon in crashed EXE module, use default IDI_APPLICATION system icon. if(m_HeadingIcon == NULL) { m_HeadingIcon = ::LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION)); } // Init controls. m_statSubHeader = GetDlgItem(IDC_SUBHEADER); m_link.SubclassWindow(GetDlgItem(IDC_LINK)); m_link.SetHyperLinkExtendedStyle(HLINK_COMMANDBUTTON); m_link.SetLabel(pSender->GetLangStr(_T("MainDlg"), _T("WhatDoesReportContain"))); m_linkMoreInfo.SubclassWindow(GetDlgItem(IDC_MOREINFO)); m_linkMoreInfo.SetHyperLinkExtendedStyle(HLINK_COMMANDBUTTON); m_linkMoreInfo.SetLabel(pSender->GetLangStr(_T("MainDlg"), _T("ProvideAdditionalInfo"))); m_statEmail = GetDlgItem(IDC_STATMAIL); m_statEmail.SetWindowText(pSender->GetLangStr(_T("MainDlg"), _T("YourEmail"))); m_editEmail = GetDlgItem(IDC_EMAIL); m_editEmail.SetWindowText(pSender->GetCrashInfo()->GetPersistentUserEmail()); m_statDesc = GetDlgItem(IDC_DESCRIBE); m_statDesc.SetWindowText(pSender->GetLangStr(_T("MainDlg"), _T("DescribeProblem"))); m_editDesc = GetDlgItem(IDC_DESCRIPTION); m_statIndent = GetDlgItem(IDC_INDENT); m_chkRestart = GetDlgItem(IDC_RESTART); CString sCaption; sCaption.Format(pSender->GetLangStr(_T("MainDlg"), _T("RestartApp")), pSender->GetCrashInfo()->m_sAppName); m_chkRestart.SetWindowText(sCaption); m_chkRestart.SetCheck(BST_CHECKED); m_chkRestart.ShowWindow(pSender->GetCrashInfo()->m_bAppRestart?SW_SHOW:SW_HIDE); m_statConsent = GetDlgItem(IDC_CONSENT); // Init font for consent string. LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); lf.lfHeight = 11; lf.lfWeight = FW_NORMAL; lf.lfQuality = ANTIALIASED_QUALITY; _TCSCPY_S(lf.lfFaceName, 32, _T("Tahoma")); CFontHandle hConsentFont; hConsentFont.CreateFontIndirect(&lf); m_statConsent.SetFont(hConsentFont); // Set text of the static if(pSender->GetCrashInfo()->m_sPrivacyPolicyURL.IsEmpty()) m_statConsent.SetWindowText(pSender->GetLangStr(_T("MainDlg"), _T("MyConsent2"))); else m_statConsent.SetWindowText(pSender->GetLangStr(_T("MainDlg"), _T("MyConsent"))); // Init Privacy Policy link m_linkPrivacyPolicy.SubclassWindow(GetDlgItem(IDC_PRIVACYPOLICY)); m_linkPrivacyPolicy.SetHyperLink(pSender->GetCrashInfo()->m_sPrivacyPolicyURL); m_linkPrivacyPolicy.SetLabel(pSender->GetLangStr(_T("MainDlg"), _T("PrivacyPolicy"))); BOOL bShowPrivacyPolicy = !pSender->GetCrashInfo()->m_sPrivacyPolicyURL.IsEmpty(); m_linkPrivacyPolicy.ShowWindow(bShowPrivacyPolicy?SW_SHOW:SW_HIDE); m_statCrashRpt = GetDlgItem(IDC_CRASHRPT); m_statHorzLine = GetDlgItem(IDC_HORZLINE); // Init OK button m_btnOk = GetDlgItem(IDOK); m_btnOk.SetWindowText(pSender->GetLangStr(_T("MainDlg"), _T("SendReport"))); // Init Cancel button m_btnCancel = GetDlgItem(IDC_CANCEL); if(pSender->GetCrashInfo()->m_bQueueEnabled) m_btnCancel.SetWindowText(pSender->GetLangStr(_T("MainDlg"), _T("OtherActions"))); else m_btnCancel.SetWindowText(pSender->GetLangStr(_T("MainDlg"), _T("CloseTheProgram"))); // If send procedure is mandatory... if(pSender->GetCrashInfo()->m_bSendMandatory) { // Hide Cancel button m_btnCancel.ShowWindow(SW_HIDE); // Remove Close button SetWindowLong(GWL_STYLE, GetWindowLong(GWL_STYLE) & ~WS_SYSMENU); } // Init font for heading text memset(&lf, 0, sizeof(LOGFONT)); lf.lfHeight = 25; lf.lfWeight = FW_NORMAL; lf.lfQuality = ANTIALIASED_QUALITY; _TCSCPY_S(lf.lfFaceName, 32, _T("Tahoma")); m_HeadingFont.CreateFontIndirect(&lf); // Init control positions m_Layout.SetContainerWnd(m_hWnd); m_Layout.Insert(m_linkMoreInfo); m_Layout.Insert(m_statIndent); m_Layout.Insert(m_statEmail, TRUE); m_Layout.Insert(m_editEmail, TRUE); m_Layout.Insert(m_statDesc, TRUE); m_Layout.Insert(m_editDesc, TRUE); m_Layout.Insert(m_chkRestart); m_Layout.Insert(m_statConsent); m_Layout.Insert(m_linkPrivacyPolicy); m_Layout.Insert(m_statCrashRpt); m_Layout.Insert(m_statHorzLine, TRUE); m_Layout.Insert(m_btnOk); m_Layout.Insert(m_btnCancel, TRUE); // By default, hide the email & description fields. // But user may override the default. ShowMoreInfo(pSender->GetCrashInfo()->m_bShowAdditionalInfoFields); // Create progress dialog m_dlgProgress.Create(m_hWnd); m_dlgProgress.Start(TRUE); // register object for message filtering and idle updates CMessageLoop* pLoop = _Module.GetMessageLoop(); ATLASSERT(pLoop != NULL); if(pLoop) { pLoop->AddMessageFilter(this); } UIAddChildWindowContainer(m_hWnd); return TRUE; }
int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int /*nCmdShow*/ = SW_SHOWDEFAULT) { int nRet = 0; // Return code CErrorReportDlg dlgErrorReport; // Error Report dialog CResendDlg dlgResend; // Resend dialog // Get command line parameters. LPCWSTR szCommandLine = GetCommandLineW(); // Split command line. int argc = 0; LPWSTR* argv = CommandLineToArgvW(szCommandLine, &argc); // Check parameter count. if(argc!=2) return 1; // No arguments passed, exit. if(_tcscmp(argv[1], _T("/terminate"))==0) { // User wants us to find and terminate all instances of CrashSender.exe return CErrorReportSender::TerminateAllCrashSenderProcesses(); } // Extract file mapping name from command line arg. CString sFileMappingName = CString(argv[1]); // Create the sender model that will collect crash report data // and send error report(s). CErrorReportSender* pSender = CErrorReportSender::GetInstance(); // Init the sender object BOOL bInit = pSender->Init(sFileMappingName.GetBuffer(0)); if(!bInit) { // Failed to init return 0; } // Determine what to do next // (either run in GUI more or run in silent mode). if(!pSender->GetCrashInfo()->m_bSilentMode) { // GUI mode. // Create message loop. CMessageLoop theLoop; _Module.AddMessageLoop(&theLoop); if(!pSender->GetCrashInfo()->m_bSendRecentReports) { // Create "Error Report" dialog if(dlgErrorReport.Create(NULL) == NULL) { ATLTRACE(_T("Error report dialog creation failed!\n")); return 1; } } else { // Create "Send Error Reports" dialog. if(dlgResend.Create(NULL) == NULL) { ATLTRACE(_T("Resend dialog creation failed!\n")); return 1; } } // Process window messages. nRet = theLoop.Run(); _Module.RemoveMessageLoop(); } else { // Silent (non-GUI mode). // Run the sender and wait until it exits. pSender->Run(); pSender->WaitForCompletion(); // Get return status nRet = pSender->GetStatus(); } // Delete sender object. delete pSender; // Exit. return nRet; }