зеркало из https://github.com/mozilla/pjs.git
bug 404855 - crash reporter UI review, round 2--win32+strings changes. r=dcamp
This commit is contained in:
Родитель
00cad89ded
Коммит
0ad5517a64
Двоичный файл не отображается.
|
@ -6,7 +6,7 @@
|
|||
name="CrashReporter"
|
||||
type="win32"
|
||||
/>
|
||||
<description>Updater</description>
|
||||
<description>Crash Reporter</description>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#define MAX_COMMENT_LENGTH 500
|
||||
|
||||
#if defined(XP_WIN32)
|
||||
|
||||
#include <windows.h>
|
||||
|
@ -35,19 +37,27 @@ typedef std::map<std::string, std::string> StringTable;
|
|||
|
||||
#define ST_CRASHREPORTERTITLE "CrashReporterTitle"
|
||||
#define ST_CRASHREPORTERVENDORTITLE "CrashReporterVendorTitle"
|
||||
#define ST_CRASHREPORTERERROR "CrashReporterError"
|
||||
#define ST_CRASHREPORTERERROR "CrashReporterErrorText"
|
||||
#define ST_CRASHREPORTERPRODUCTERROR "CrashReporterProductError"
|
||||
#define ST_CRASHREPORTERHEADER "CrashReporterHeader"
|
||||
#define ST_CRASHREPORTERDESCRIPTION "CrashReporterDescription"
|
||||
#define ST_CRASHREPORTERHEADER "CrashReporterSorry"
|
||||
#define ST_CRASHREPORTERDESCRIPTION "CrashReporterDescriptionText"
|
||||
#define ST_CRASHREPORTERDEFAULT "CrashReporterDefault"
|
||||
#define ST_VIEWREPORT "ViewReport"
|
||||
#define ST_VIEWREPORT "Details"
|
||||
#define ST_VIEWREPORTTITLE "ViewReportTitle"
|
||||
#define ST_COMMENTGRAYTEXT "CommentGrayText"
|
||||
#define ST_EXTRAREPORTINFO "ExtraReportInfo"
|
||||
#define ST_CHECKSUBMIT "CheckSubmit"
|
||||
#define ST_CHECKURL "CheckURL"
|
||||
#define ST_CHECKEMAIL "CheckEmail"
|
||||
#define ST_CLOSE "Close"
|
||||
#define ST_CHECKSUBMIT "CheckSendReport"
|
||||
#define ST_CHECKURL "CheckIncludeURL"
|
||||
#define ST_CHECKEMAIL "CheckSendEmail"
|
||||
#define ST_EMAILGRAYTEXT "EmailGrayText"
|
||||
#define ST_REPORTPRESUBMIT "ReportPreSubmit"
|
||||
#define ST_REPORTDURINGSUBMIT "ReportDuringSubmit"
|
||||
#define ST_REPORTSUBMITSUCCESS "ReportSubmitSuccess"
|
||||
#define ST_SUBMITFAILED "ReportSubmitFailed"
|
||||
#define ST_QUIT "Quit"
|
||||
#define ST_RESTART "Restart"
|
||||
#define ST_SUBMITFAILED "SubmitFailed"
|
||||
#define ST_OK "Ok"
|
||||
#define ST_CLOSE "Close"
|
||||
|
||||
#define ST_ERROR_BADARGUMENTS "ErrorBadArguments"
|
||||
#define ST_ERROR_EXTRAFILEEXISTS "ErrorExtraFileExists"
|
||||
|
|
|
@ -54,30 +54,49 @@ END
|
|||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_DIALOG ICON "crashreporter.ico"
|
||||
IDI_MAINICON ICON "crashreporter.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AVI
|
||||
//
|
||||
|
||||
IDR_THROBBER AVI "Throbber-small.avi"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_SENDDIALOG DIALOGEX 0, 0, 241, 126
|
||||
IDD_SENDDIALOG DIALOGEX 0, 0, 241, 187
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_APPWINDOW
|
||||
CAPTION "Sending Crash Report..."
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "",IDC_DESCRIPTIONTEXT,"RichEdit20A",ES_MULTILINE | ES_READONLY,7,7,226,12,WS_EX_TRANSPARENT
|
||||
CONTROL "view report",IDC_VIEWREPORTCHECK,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP,12,24,54,12
|
||||
CONTROL "",IDC_VIEWREPORTTEXT,"RichEdit20A",ES_MULTILINE | ES_READONLY | NOT WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP,12,38,222,56
|
||||
CONTROL "submit a crash report to mozilla",IDC_SUBMITREPORTCHECK,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,42,222,10
|
||||
CONTROL "include the URL in the crash report",IDC_INCLUDEURLCHECK,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,57,222,10
|
||||
CONTROL "email me when the problem is fixed",IDC_EMAILMECHECK,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,70,222,10
|
||||
EDITTEXT IDC_EMAILTEXT,26,83,208,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "close",IDC_CLOSEBUTTON,111,105,50,14
|
||||
DEFPUSHBUTTON "restart firefox",IDC_RESTARTBUTTON,166,105,68,14
|
||||
CONTROL "",IDC_DESCRIPTIONTEXT,"RichEdit20A",ES_MULTILINE | ES_READONLY,8,7,226,12,WS_EX_TRANSPARENT
|
||||
CONTROL "tell mozilla about this crash so they can fix it",IDC_SUBMITREPORTCHECK,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,25,222,10
|
||||
CHECKBOX "details...",IDC_VIEWREPORTBUTTON,24,40,54,14,BS_PUSHLIKE
|
||||
EDITTEXT IDC_COMMENTTEXT,24,59,210,43,ES_MULTILINE | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
|
||||
CONTROL "include the address of the page i was on",IDC_INCLUDEURLCHECK,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,107,210,10
|
||||
CONTROL "tell mozilla to email me with more information",IDC_EMAILMECHECK,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,120,210,10
|
||||
EDITTEXT IDC_EMAILTEXT,36,133,198,14,ES_AUTOHSCROLL
|
||||
CONTROL "",IDC_THROBBER,"SysAnimate32",ACS_TRANSPARENT | NOT WS_VISIBLE | WS_TABSTOP,4,152,16,16
|
||||
LTEXT "your crash report will be submitted when you restart",IDC_PROGRESSTEXT,24,152,210,10,SS_NOPREFIX
|
||||
PUSHBUTTON "quit without sending",IDC_CLOSEBUTTON,84,166,77,14
|
||||
DEFPUSHBUTTON "restart firefox",IDC_RESTARTBUTTON,166,166,68,14
|
||||
END
|
||||
|
||||
IDD_VIEWREPORTDIALOG DIALOGEX 0, 0, 208, 126
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION
|
||||
CAPTION "view report"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "",IDC_VIEWREPORTTEXT,"RichEdit20A",ES_MULTILINE | ES_READONLY | WS_BORDER | WS_VSCROLL | WS_TABSTOP,7,7,194,92
|
||||
DEFPUSHBUTTON "OK",IDOK,151,105,50,14
|
||||
END
|
||||
|
||||
|
||||
|
@ -91,9 +110,17 @@ GUIDELINES DESIGNINFO
|
|||
BEGIN
|
||||
IDD_SENDDIALOG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
LEFTMARGIN, 8
|
||||
RIGHTMARGIN, 234
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 180
|
||||
END
|
||||
|
||||
IDD_VIEWREPORTDIALOG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 201
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 119
|
||||
END
|
||||
END
|
||||
|
|
|
@ -95,12 +95,14 @@ static set<UINT> gAttachedBottom;
|
|||
|
||||
// Default set of items for gAttachedBottom
|
||||
static const UINT kDefaultAttachedBottom[] = {
|
||||
IDC_VIEWREPORTCHECK,
|
||||
IDC_VIEWREPORTTEXT,
|
||||
IDC_SUBMITCRASHCHECK,
|
||||
IDC_SUBMITREPORTCHECK,
|
||||
IDC_VIEWREPORTBUTTON,
|
||||
IDC_COMMENTTEXT,
|
||||
IDC_INCLUDEURLCHECK,
|
||||
IDC_EMAILMECHECK,
|
||||
IDC_EMAILTEXT,
|
||||
IDC_PROGRESSTEXT,
|
||||
IDC_THROBBER,
|
||||
IDC_CLOSEBUTTON,
|
||||
IDC_RESTARTBUTTON,
|
||||
};
|
||||
|
@ -271,13 +273,8 @@ static void GetRelativeRect(HWND hwnd, HWND hwndParent, RECT* r)
|
|||
static void SetDlgItemVisible(HWND hwndDlg, UINT item, bool visible)
|
||||
{
|
||||
HWND hwnd = GetDlgItem(hwndDlg, item);
|
||||
LONG style = GetWindowLong(hwnd, GWL_STYLE);
|
||||
if (visible)
|
||||
style |= WS_VISIBLE;
|
||||
else
|
||||
style &= ~WS_VISIBLE;
|
||||
|
||||
SetWindowLong(hwnd, GWL_STYLE, style);
|
||||
ShowWindow(hwnd, visible ? SW_SHOW : SW_HIDE);
|
||||
}
|
||||
|
||||
static void SetDlgItemDisabled(HWND hwndDlg, UINT item, bool disabled)
|
||||
|
@ -375,6 +372,21 @@ static void MaybeSendReport(HWND hwndDlg)
|
|||
return;
|
||||
}
|
||||
|
||||
// disable all the form controls
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_SUBMITREPORTCHECK), false);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_VIEWREPORTBUTTON), false);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_COMMENTTEXT), false);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_INCLUDEURLCHECK), false);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILMECHECK), false);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT), false);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_CLOSEBUTTON), false);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_RESTARTBUTTON), false);
|
||||
|
||||
SetDlgItemText(hwndDlg, IDC_PROGRESSTEXT, Str(ST_REPORTDURINGSUBMIT).c_str());
|
||||
// start throbber
|
||||
// play entire AVI, and loop
|
||||
Animate_Play(GetDlgItem(hwndDlg, IDC_THROBBER), 0, -1, -1);
|
||||
SetDlgItemVisible(hwndDlg, IDC_THROBBER, true);
|
||||
gThreadHandle = NULL;
|
||||
gSendData.hDlg = hwndDlg;
|
||||
gSendData.queryParameters = gQueryParameters;
|
||||
|
@ -425,32 +437,6 @@ static void ShowReportInfo(HWND hwndDlg)
|
|||
SetDlgItemText(hwndDlg, IDC_VIEWREPORTTEXT, description.c_str());
|
||||
}
|
||||
|
||||
static void ShowHideReport(HWND hwndDlg)
|
||||
{
|
||||
// When resizing the dialog to show the report, these items should
|
||||
// stay put
|
||||
gAttachedBottom.erase(IDC_VIEWREPORTCHECK);
|
||||
gAttachedBottom.erase(IDC_VIEWREPORTTEXT);
|
||||
|
||||
RECT r;
|
||||
HWND hwnd = GetDlgItem(hwndDlg, IDC_VIEWREPORTTEXT);
|
||||
|
||||
GetWindowRect(hwnd, &r);
|
||||
int diff = (r.bottom - r.top) + 10;
|
||||
if (IsDlgButtonChecked(hwndDlg, IDC_VIEWREPORTCHECK)) {
|
||||
SetDlgItemVisible(hwndDlg, IDC_VIEWREPORTTEXT, true);
|
||||
} else {
|
||||
SetDlgItemVisible(hwndDlg, IDC_VIEWREPORTTEXT, false);
|
||||
diff = -diff;
|
||||
}
|
||||
|
||||
StretchDialog(hwndDlg, diff);
|
||||
|
||||
// set these back to normal
|
||||
gAttachedBottom.insert(IDC_VIEWREPORTCHECK);
|
||||
gAttachedBottom.insert(IDC_VIEWREPORTTEXT);
|
||||
}
|
||||
|
||||
static void UpdateURL(HWND hwndDlg)
|
||||
{
|
||||
if (IsDlgButtonChecked(hwndDlg, IDC_INCLUDEURLCHECK)) {
|
||||
|
@ -466,11 +452,173 @@ static void UpdateEmail(HWND hwndDlg)
|
|||
wchar_t email[MAX_EMAIL_LENGTH];
|
||||
GetDlgItemText(hwndDlg, IDC_EMAILTEXT, email, sizeof(email));
|
||||
gQueryParameters[L"Email"] = email;
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT), true);
|
||||
} else {
|
||||
gQueryParameters.erase(L"Email");
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT), false);
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateComment(HWND hwndDlg)
|
||||
{
|
||||
wchar_t comment[MAX_COMMENT_LENGTH + 1];
|
||||
GetDlgItemText(hwndDlg, IDC_COMMENTTEXT, comment, sizeof(comment));
|
||||
if (wcslen(comment) > 0)
|
||||
gQueryParameters[L"Comments"] = comment;
|
||||
else
|
||||
gQueryParameters.erase(L"Comments");
|
||||
}
|
||||
|
||||
/*
|
||||
* Dialog procedure for the "view report" dialog.
|
||||
*/
|
||||
static BOOL CALLBACK ViewReportDialogProc(HWND hwndDlg, UINT message,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_INITDIALOG: {
|
||||
SetWindowText(hwndDlg, Str(ST_VIEWREPORTTITLE).c_str());
|
||||
SetDlgItemText(hwndDlg, IDOK, Str(ST_OK).c_str());
|
||||
SendDlgItemMessage(hwndDlg, IDC_VIEWREPORTTEXT,
|
||||
EM_SETTARGETDEVICE, (WPARAM)NULL, 0);
|
||||
ShowReportInfo(hwndDlg);
|
||||
SetFocus(GetDlgItem(hwndDlg, IDOK));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
case WM_COMMAND: {
|
||||
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK)
|
||||
EndDialog(hwndDlg, 0);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Return the number of bytes this string will take encoded
|
||||
// in UTF-8
|
||||
static inline int BytesInUTF8(wchar_t* str)
|
||||
{
|
||||
// Just count size of buffer for UTF-8, minus one
|
||||
// (we don't need to count the null terminator)
|
||||
return WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL) - 1;
|
||||
}
|
||||
|
||||
// Calculate the length of the text in this edit control (in bytes,
|
||||
// in the UTF-8 encoding) after replacing the current selection
|
||||
// with |insert|.
|
||||
static int NewTextLength(HWND hwndEdit, wchar_t* insert)
|
||||
{
|
||||
wchar_t current[MAX_COMMENT_LENGTH + 1];
|
||||
|
||||
GetWindowText(hwndEdit, current, MAX_COMMENT_LENGTH + 1);
|
||||
DWORD selStart, selEnd;
|
||||
SendMessage(hwndEdit, EM_GETSEL, (WPARAM)&selStart, (LPARAM)&selEnd);
|
||||
|
||||
int selectionLength = 0;
|
||||
if (selEnd - selStart > 0) {
|
||||
wchar_t selection[MAX_COMMENT_LENGTH + 1];
|
||||
wcsncpy_s(selection, current + selStart, selEnd - selStart);
|
||||
selection[selEnd - selStart] = '\0';
|
||||
selectionLength = BytesInUTF8(selection);
|
||||
}
|
||||
|
||||
// current string length + replacement text length
|
||||
// - replaced selection length
|
||||
return BytesInUTF8(current) + BytesInUTF8(insert) - selectionLength;
|
||||
}
|
||||
|
||||
// Window procedure for subclassing edit controls
|
||||
static LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
static WNDPROC super = NULL;
|
||||
|
||||
if (super == NULL)
|
||||
super = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
|
||||
switch (uMsg) {
|
||||
case WM_PAINT: {
|
||||
HDC hdc;
|
||||
PAINTSTRUCT ps;
|
||||
RECT r;
|
||||
wchar_t windowText[1024];
|
||||
|
||||
GetWindowText(hwnd, windowText, 1024);
|
||||
// if the control contains text or is focused, draw it normally
|
||||
if (GetFocus() == hwnd || windowText[0] != '\0')
|
||||
return CallWindowProc(super, hwnd, uMsg, wParam, lParam);
|
||||
|
||||
GetClientRect(hwnd, &r);
|
||||
hdc = BeginPaint(hwnd, &ps);
|
||||
FillRect(hdc, &r, GetSysColorBrush(IsWindowEnabled(hwnd)
|
||||
? COLOR_WINDOW : COLOR_BTNFACE));
|
||||
SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
|
||||
SelectObject(hdc, (HFONT)GetStockObject(DEFAULT_GUI_FONT));
|
||||
SetBkMode(hdc, TRANSPARENT);
|
||||
wchar_t* txt = (wchar_t*)GetProp(hwnd, L"PROP_GRAYTEXT");
|
||||
// Get the actual edit control rect
|
||||
CallWindowProc(super, hwnd, EM_GETRECT, 0, (LPARAM)&r);
|
||||
if (txt)
|
||||
DrawText(hdc, txt, wcslen(txt), &r,
|
||||
DT_EDITCONTROL | DT_NOPREFIX | DT_WORDBREAK | DT_INTERNAL);
|
||||
EndPaint(hwnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We handle WM_CHAR and WM_PASTE to limit the comment box to 500
|
||||
// bytes in UTF-8.
|
||||
case WM_CHAR: {
|
||||
// Leave accelerator keys and non-printing chars (except LF) alone
|
||||
if (wParam & (1<<24) || wParam & (1<<29) ||
|
||||
(wParam < ' ' && wParam != '\n'))
|
||||
break;
|
||||
|
||||
wchar_t ch[2] = { (wchar_t)wParam, 0 };
|
||||
if (NewTextLength(hwnd, ch) > MAX_COMMENT_LENGTH)
|
||||
return 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_PASTE: {
|
||||
if (IsClipboardFormatAvailable(CF_UNICODETEXT) &&
|
||||
OpenClipboard(hwnd)) {
|
||||
HGLOBAL hg = GetClipboardData(CF_UNICODETEXT);
|
||||
wchar_t* pastedText = (wchar_t*)GlobalLock(hg);
|
||||
int newSize = 0;
|
||||
|
||||
if (pastedText)
|
||||
newSize = NewTextLength(hwnd, pastedText);
|
||||
|
||||
GlobalUnlock(hg);
|
||||
CloseClipboard();
|
||||
|
||||
if (newSize > MAX_COMMENT_LENGTH)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SETFOCUS:
|
||||
case WM_KILLFOCUS: {
|
||||
RECT r;
|
||||
GetClientRect(hwnd, &r);
|
||||
InvalidateRect(hwnd, &r, TRUE);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DESTROY: {
|
||||
// cleanup our property
|
||||
HGLOBAL hData = RemoveProp(hwnd, L"PROP_GRAYTEXT");
|
||||
if (hData)
|
||||
GlobalFree(hData);
|
||||
}
|
||||
}
|
||||
|
||||
return CallWindowProc(super, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
@ -486,6 +634,10 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
|
|||
sHeight = r.bottom - r.top;
|
||||
|
||||
SetWindowText(hwndDlg, Str(ST_CRASHREPORTERTITLE).c_str());
|
||||
HICON hIcon = LoadIcon(GetModuleHandle(NULL),
|
||||
MAKEINTRESOURCE(IDI_MAINICON));
|
||||
SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||
SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||
|
||||
SendDlgItemMessage(hwndDlg, IDC_DESCRIPTIONTEXT,
|
||||
EM_SETEVENTMASK, (WPARAM)NULL,
|
||||
|
@ -510,24 +662,33 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
|
|||
|
||||
// resize the "View Report" button based on the string length
|
||||
RECT viewRect;
|
||||
HWND hwndView = GetDlgItem(hwndDlg, IDC_VIEWREPORTCHECK);
|
||||
HWND hwndView = GetDlgItem(hwndDlg, IDC_VIEWREPORTBUTTON);
|
||||
GetRelativeRect(hwndView, hwndDlg, &viewRect);
|
||||
HDC hdc = GetDC(hwndView);
|
||||
const wstring viewButtonText = Str(ST_VIEWREPORT);
|
||||
SIZE size;
|
||||
wchar_t oldViewButtonText[1024];
|
||||
|
||||
GetDlgItemText(hwndDlg, IDC_VIEWREPORTBUTTON, oldViewButtonText, 1024);
|
||||
SIZE size, oldSize;
|
||||
|
||||
if (GetTextExtentPoint32(hdc, viewButtonText.c_str(),
|
||||
viewButtonText.length(), &size)) {
|
||||
// shift right by the amount the button should grow
|
||||
int sizeDiff = size.cx - (viewRect.right - viewRect.left);
|
||||
viewRect.right += sizeDiff;
|
||||
MoveWindow(hwndView, viewRect.left, viewRect.top,
|
||||
viewRect.right - viewRect.left,
|
||||
viewRect.bottom - viewRect.top,
|
||||
TRUE);
|
||||
viewButtonText.length(), &size) &&
|
||||
// default text on the button
|
||||
GetTextExtentPoint32(hdc, oldViewButtonText,
|
||||
wcslen(oldViewButtonText), &oldSize)) {
|
||||
// grow right right by the amount it changed
|
||||
int sizeDiff = size.cx - oldSize.cx;
|
||||
|
||||
// don't bother shrinking the button
|
||||
if (sizeDiff > 0) {
|
||||
viewRect.right += sizeDiff;
|
||||
MoveWindow(hwndView, viewRect.left, viewRect.top,
|
||||
viewRect.right - viewRect.left,
|
||||
viewRect.bottom - viewRect.top,
|
||||
TRUE);
|
||||
}
|
||||
}
|
||||
SetDlgItemText(hwndDlg, IDC_VIEWREPORTCHECK, viewButtonText.c_str());
|
||||
SendDlgItemMessage(hwndDlg, IDC_VIEWREPORTTEXT,
|
||||
EM_SETTARGETDEVICE, (WPARAM)NULL, 0);
|
||||
SetDlgItemText(hwndDlg, IDC_VIEWREPORTBUTTON, viewButtonText.c_str());
|
||||
|
||||
|
||||
SetDlgItemText(hwndDlg, IDC_SUBMITREPORTCHECK,
|
||||
|
@ -536,13 +697,29 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
|
|||
SUBMIT_REPORT_VALUE, &enabled) &&
|
||||
!enabled) {
|
||||
CheckDlgButton(hwndDlg, IDC_SUBMITREPORTCHECK, BST_UNCHECKED);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_VIEWREPORTBUTTON), enabled);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_COMMENTTEXT), enabled);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_INCLUDEURLCHECK), enabled);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILMECHECK), enabled);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT), enabled);
|
||||
SetDlgItemVisible(hwndDlg, IDC_PROGRESSTEXT, enabled);
|
||||
} else {
|
||||
CheckDlgButton(hwndDlg, IDC_SUBMITREPORTCHECK, BST_CHECKED);
|
||||
}
|
||||
|
||||
|
||||
HWND hwndComment = GetDlgItem(hwndDlg, IDC_COMMENTTEXT);
|
||||
WNDPROC OldWndProc = (WNDPROC)SetWindowLongPtr(hwndComment,
|
||||
GWLP_WNDPROC,
|
||||
(LONG_PTR)EditSubclassProc);
|
||||
|
||||
// Subclass comment edit control to get placeholder text
|
||||
SetWindowLongPtr(hwndComment, GWLP_USERDATA, (LONG_PTR)OldWndProc);
|
||||
wstring commentGrayText = Str(ST_COMMENTGRAYTEXT);
|
||||
wchar_t* hMem = (wchar_t*)GlobalAlloc(GPTR, (commentGrayText.length() + 1)*sizeof(wchar_t));
|
||||
wcscpy(hMem, commentGrayText.c_str());
|
||||
SetProp(hwndComment, L"PROP_GRAYTEXT", hMem);
|
||||
|
||||
SetDlgItemText(hwndDlg, IDC_INCLUDEURLCHECK, Str(ST_CHECKURL).c_str());
|
||||
// want this on by default
|
||||
if (CheckBoolKey(gCrashReporterKey.c_str(), INCLUDE_URL_VALUE, &enabled) &&
|
||||
|
@ -565,7 +742,19 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
|
|||
SetDlgItemText(hwndDlg, IDC_EMAILTEXT, email.c_str());
|
||||
}
|
||||
|
||||
SetDlgItemText(hwndDlg, IDC_CLOSEBUTTON, Str(ST_CLOSE).c_str());
|
||||
// Subclass email edit control to get placeholder text
|
||||
HWND hwndEmail = GetDlgItem(hwndDlg, IDC_EMAILTEXT);
|
||||
OldWndProc = (WNDPROC)SetWindowLongPtr(hwndEmail,
|
||||
GWLP_WNDPROC,
|
||||
(LONG_PTR)EditSubclassProc);
|
||||
SetWindowLongPtr(hwndEmail, GWLP_USERDATA, (LONG_PTR)OldWndProc);
|
||||
wstring emailGrayText = Str(ST_EMAILGRAYTEXT);
|
||||
hMem = (wchar_t*)GlobalAlloc(GPTR, (emailGrayText.length() + 1)*sizeof(wchar_t));
|
||||
wcscpy(hMem, emailGrayText.c_str());
|
||||
SetProp(hwndEmail, L"PROP_GRAYTEXT", hMem);
|
||||
|
||||
SetDlgItemText(hwndDlg, IDC_PROGRESSTEXT, Str(ST_REPORTPRESUBMIT).c_str());
|
||||
SetDlgItemText(hwndDlg, IDC_CLOSEBUTTON, Str(ST_QUIT).c_str());
|
||||
|
||||
RECT closeRect;
|
||||
HWND hwndClose = GetDlgItem(hwndDlg, IDC_CLOSEBUTTON);
|
||||
|
@ -616,22 +805,25 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
|
|||
|
||||
SetDlgItemVisible(hwndDlg, IDC_INCLUDEURLCHECK, false);
|
||||
|
||||
gAttachedBottom.erase(IDC_VIEWREPORTCHECK);
|
||||
gAttachedBottom.erase(IDC_VIEWREPORTTEXT);
|
||||
gAttachedBottom.erase(IDC_VIEWREPORTBUTTON);
|
||||
gAttachedBottom.erase(IDC_SUBMITREPORTCHECK);
|
||||
gAttachedBottom.erase(IDC_COMMENTTEXT);
|
||||
|
||||
StretchDialog(hwndDlg, urlCheckRect.top - emailCheckRect.top);
|
||||
|
||||
gAttachedBottom.insert(IDC_VIEWREPORTCHECK);
|
||||
gAttachedBottom.insert(IDC_VIEWREPORTTEXT);
|
||||
gAttachedBottom.insert(IDC_VIEWREPORTBUTTON);
|
||||
gAttachedBottom.insert(IDC_SUBMITREPORTCHECK);
|
||||
gAttachedBottom.insert(IDC_COMMENTTEXT);
|
||||
}
|
||||
|
||||
// Open the AVI resource for the throbber
|
||||
Animate_Open(GetDlgItem(hwndDlg, IDC_THROBBER),
|
||||
MAKEINTRESOURCE(IDR_THROBBER));
|
||||
|
||||
UpdateURL(hwndDlg);
|
||||
UpdateEmail(hwndDlg);
|
||||
ShowReportInfo(hwndDlg);
|
||||
|
||||
SetFocus(GetDlgItem(hwndDlg, IDC_EMAILTEXT));
|
||||
SetFocus(GetDlgItem(hwndDlg, IDC_SUBMITREPORTCHECK));
|
||||
return FALSE;
|
||||
}
|
||||
case WM_SIZE: {
|
||||
|
@ -662,33 +854,31 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
|
|||
case WM_COMMAND: {
|
||||
if (HIWORD(wParam) == BN_CLICKED) {
|
||||
switch(LOWORD(wParam)) {
|
||||
case IDC_VIEWREPORTCHECK:
|
||||
ShowHideReport(hwndDlg);
|
||||
case IDC_VIEWREPORTBUTTON:
|
||||
DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_VIEWREPORTDIALOG), hwndDlg,
|
||||
(DLGPROC)ViewReportDialogProc, 0);
|
||||
break;
|
||||
case IDC_SUBMITREPORTCHECK:
|
||||
enabled = (IsDlgButtonChecked(hwndDlg, IDC_SUBMITREPORTCHECK) != 0);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_VIEWREPORTBUTTON), enabled);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_COMMENTTEXT), enabled);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_INCLUDEURLCHECK), enabled);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILMECHECK), enabled);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT), enabled);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT),
|
||||
enabled && (IsDlgButtonChecked(hwndDlg, IDC_EMAILMECHECK)
|
||||
!= 0));
|
||||
SetDlgItemVisible(hwndDlg, IDC_PROGRESSTEXT, enabled);
|
||||
break;
|
||||
case IDC_INCLUDEURLCHECK:
|
||||
UpdateURL(hwndDlg);
|
||||
ShowReportInfo(hwndDlg);
|
||||
break;
|
||||
case IDC_EMAILMECHECK:
|
||||
UpdateEmail(hwndDlg);
|
||||
ShowReportInfo(hwndDlg);
|
||||
break;
|
||||
case IDC_CLOSEBUTTON:
|
||||
// Hide the dialog after "closing", but leave it around to coordinate
|
||||
// with the upload thread
|
||||
ShowWindow(hwndDlg, SW_HIDE);
|
||||
MaybeSendReport(hwndDlg);
|
||||
EndCrashReporterDialog(hwndDlg, 0);
|
||||
break;
|
||||
case IDC_RESTARTBUTTON:
|
||||
// Hide the dialog after "closing", but leave it around to coordinate
|
||||
// with the upload thread
|
||||
ShowWindow(hwndDlg, SW_HIDE);
|
||||
RestartApplication();
|
||||
MaybeSendReport(hwndDlg);
|
||||
break;
|
||||
|
@ -696,13 +886,10 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
|
|||
} else if (HIWORD(wParam) == EN_CHANGE) {
|
||||
switch(LOWORD(wParam)) {
|
||||
case IDC_EMAILTEXT:
|
||||
wchar_t email[MAX_EMAIL_LENGTH];
|
||||
if (GetDlgItemText(hwndDlg, IDC_EMAILTEXT, email, sizeof(email)) > 0)
|
||||
CheckDlgButton(hwndDlg, IDC_EMAILMECHECK, BST_CHECKED);
|
||||
else
|
||||
CheckDlgButton(hwndDlg, IDC_EMAILMECHECK, BST_UNCHECKED);
|
||||
UpdateEmail(hwndDlg);
|
||||
ShowReportInfo(hwndDlg);
|
||||
break;
|
||||
case IDC_COMMENTTEXT:
|
||||
UpdateComment(hwndDlg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -712,15 +899,41 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
|
|||
WaitForSingleObject(gThreadHandle, INFINITE);
|
||||
success = (wParam == 1);
|
||||
SendCompleted(success, WideToUTF8(gSendData.serverResponse));
|
||||
if (!success) {
|
||||
MessageBox(hwndDlg,
|
||||
Str(ST_SUBMITFAILED).c_str(),
|
||||
Str(ST_CRASHREPORTERTITLE).c_str(),
|
||||
MB_OK | MB_ICONERROR);
|
||||
}
|
||||
EndCrashReporterDialog(hwndDlg, success ? 1 : 0);
|
||||
// hide throbber
|
||||
Animate_Stop(GetDlgItem(hwndDlg, IDC_THROBBER));
|
||||
SetDlgItemVisible(hwndDlg, IDC_THROBBER, false);
|
||||
|
||||
SetDlgItemText(hwndDlg, IDC_PROGRESSTEXT,
|
||||
success ?
|
||||
Str(ST_REPORTSUBMITSUCCESS).c_str() :
|
||||
Str(ST_SUBMITFAILED).c_str());
|
||||
// close dialog after 5 seconds
|
||||
SetTimer(hwndDlg, success ? 1 : 0, 5000, NULL);
|
||||
//
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_LBUTTONDOWN: {
|
||||
HWND hwndEmail = GetDlgItem(hwndDlg, IDC_EMAILTEXT);
|
||||
POINT p = { LOWORD(lParam), HIWORD(lParam) };
|
||||
// if the email edit control is clicked, enable it,
|
||||
// check the email checkbox, and focus the email edit control
|
||||
if (ChildWindowFromPoint(hwndDlg, p) == hwndEmail &&
|
||||
!IsWindowEnabled(hwndEmail) &&
|
||||
IsDlgButtonChecked(hwndDlg, IDC_SUBMITREPORTCHECK) != 0) {
|
||||
CheckDlgButton(hwndDlg, IDC_EMAILMECHECK, BST_CHECKED);
|
||||
UpdateEmail(hwndDlg);
|
||||
SetFocus(hwndEmail);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_TIMER: {
|
||||
// wParam is the second parameter from SetTimer above
|
||||
EndCrashReporterDialog(hwndDlg, wParam);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
case WM_CLOSE: {
|
||||
EndCrashReporterDialog(hwndDlg, 0);
|
||||
return FALSE;
|
||||
|
@ -796,6 +1009,7 @@ bool UIInit()
|
|||
}
|
||||
|
||||
DoInitCommonControls();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,27 +3,29 @@
|
|||
// Used by crashreporter.rc
|
||||
//
|
||||
#define IDD_SENDDIALOG 102
|
||||
#define IDR_THROBBER 103
|
||||
#define IDD_VIEWREPORTDIALOG 104
|
||||
#define IDI_MAINICON 105
|
||||
#define IDC_PROGRESS 1003
|
||||
#define IDC_DESCRIPTIONTEXT 1004
|
||||
#define IDC_CLOSEBUTTON 1005
|
||||
#define IDC_VIEWREPORTBUTTON 1006
|
||||
#define IDC_SUBMITCRASHCHECK 1007
|
||||
#define IDC_SUBMITREPORTCHECK 1007
|
||||
#define IDC_EMAILMECHECK 1008
|
||||
#define IDC_EMAILTEXT 1009
|
||||
#define IDC_HEADERLABEL 1010
|
||||
#define IDC_INCLUDEURLCHECK 1010
|
||||
#define IDC_COMMENTTEXT 1011
|
||||
#define IDC_RESTARTBUTTON 1012
|
||||
#define IDC_DESCRIPTIONLABEL 1013
|
||||
#define IDC_VIEWREPORTTEXT 1015
|
||||
#define IDC_VIEWREPORTCHECK 1016
|
||||
#define IDC_PROGRESSLABEL -1
|
||||
#define IDC_PROGRESSTEXT 1014
|
||||
#define IDC_THROBBER 1015
|
||||
#define IDC_VIEWREPORTTEXT 1016
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 103
|
||||
#define _APS_NEXT_RESOURCE_VALUE 106
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1017
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
|
|
|
@ -3,24 +3,33 @@
|
|||
CrashReporterTitle=Crash Reporter
|
||||
# LOCALIZATION NOTE (CrashReporterVendorTitle): %s is replaced with the vendor name. (i.e. "Mozilla")
|
||||
CrashReporterVendorTitle=%s Crash Reporter
|
||||
# LOCALIZATION NOTE (CrashReporterError): %s is replaced with another string containing detailed information.
|
||||
CrashReporterError=We're sorry, but the application hit an unexpected problem and crashed.\n\nUnfortunately the crash reporter is unable to submit a report for this crash.\n\nDetails: %s
|
||||
# LOCALIZATION NOTE (CrashReporterProductError): The first %s is replaced with the product name (i.e. "Firefox"), the second is replaced with another string containing detailed information. These two substitutions can not be reordered!
|
||||
CrashReporterProductError=We're sorry, but %s hit an unexpected problem and crashed. We'll try to restore your tabs and windows when it restarts.\n\nUnfortunately the crash reporter is unable to submit a crash report.\n\nDetails: %s
|
||||
CrashReporterHeader=Crash! Bang! Boom!
|
||||
# LOCALIZATION NOTE (CrashReporterDescription): The %s is replaced with the product name.
|
||||
CrashReporterDescription=We're sorry, but %s hit an unexpected problem and crashed. We'll try to restore your tabs and windows when it restarts.\n\nTo help us diagnose and repair this problem, you can send us a crash report.
|
||||
# LOCALIZATION NOTE (CrashReporterErrorText): %s is replaced with another string containing detailed information.
|
||||
CrashReporterErrorText=The application had problem and crashed.\n\nUnfortunately the crash reporter is unable to submit a report for this crash.\n\nDetails: %s
|
||||
# LOCALIZATION NOTE (CrashReporterProductErrorText): The first %s is replaced with the product name (i.e. "Firefox"), the second is replaced with another string containing detailed information. These two substitutions can not be reordered!
|
||||
CrashReporterProductError=%s had a problem and crashed. We'll try to restore your tabs and windows when it restarts.\n\nUnfortunately the crash reporter is unable to submit a crash report.\n\nDetails: %s
|
||||
CrashReporterSorry=We're Sorry
|
||||
# LOCALIZATION NOTE (CrashReporterDescriptionText): The %s is replaced with the product name.
|
||||
CrashReporterDescriptionText=%s hit an unexpected problem and crashed. We'll try to restore your tabs and windows when it restarts.\n\nTo help us diagnose and fix the problem, you can send us a crash report.
|
||||
CrashReporterDefault=This application is run after a crash to report the problem to the application vendor. It should not be run directly.
|
||||
ViewReport=View Report
|
||||
ExtraReportInfo=This report also contains information about the state of the application when it crashed.
|
||||
# LOCALIZATION NOTE (CheckSubmit): The %s is replaced with the vendor name.
|
||||
CheckSubmit=Submit crash report to %s
|
||||
CheckURL=Include the URL in the crash report
|
||||
CheckEmail=Email me when the problem is fixed
|
||||
Close=Close
|
||||
Details=Details…
|
||||
ViewReportTitle=Report Contents
|
||||
CommentGrayText=Add a comment. Note: Comments are publicly visible
|
||||
ExtraReportInfo=This report also contains technical information about the state of the application when it crashed.
|
||||
# LOCALIZATION NOTE (CheckSendReport): The %s is replaced with the vendor name.
|
||||
CheckSendReport=Tell %s about this crash so they can fix it
|
||||
CheckIncludeURL=Include the address of the page I was on
|
||||
CheckSendEmail=Email me when more information is available
|
||||
EmailGrayText=Enter your email address here
|
||||
ReportPreSubmit=Your crash report will be submitted when you restart.
|
||||
ReportDuringSubmit=Submitting your report and restarting…
|
||||
ReportSubmitSuccess=Report submitted successfully!
|
||||
ReportSubmitFailed=There was a problem submitting your report.
|
||||
Quit=Quit without sending
|
||||
# LOCALIZATION NOTE (Restart): The %s is replaced with the product name.
|
||||
Restart=Restart %s
|
||||
SubmitFailed=Failed to submit crash report
|
||||
Ok=OK
|
||||
Close=Close
|
||||
|
||||
# LOCALIZATION NOTE (CrashID): The %s is replaced with the Crash ID from the server, which is a string like abc12345-6789-0abc-def1-23456abcdef1
|
||||
CrashID=Crash ID: %s
|
||||
# LOCALIZATION NOTE (CrashDetailsURL): The %s is replaced with a URL that the user can visit to view the crash details.
|
||||
|
@ -35,4 +44,3 @@ ErrorNoProductName=The application did not identify itself.
|
|||
ErrorNoServerURL=The application did not specify a crash reporting server.
|
||||
ErrorNoSettingsPath=Couldn't find the crash reporter's settings.
|
||||
ErrorCreateDumpDir=Couldn't create pending dump directory.
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче