2 * The dialog that displays after a crash
4 * Copyright 2008 Mikolaj Zalewski
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "wine/debug.h"
27 #include "wine/unicode.h"
31 #define MAX_PROGRAM_NAME_LENGTH 80
33 int msgbox_res_id(HWND hwnd
, UINT textId
, UINT captionId
, UINT uType
)
37 LoadStringW(GetModuleHandleW(NULL
), captionId
, caption
, sizeof(caption
)/sizeof(caption
[0]));
38 LoadStringW(GetModuleHandleW(NULL
), textId
, text
, sizeof(text
)/sizeof(text
[0]));
39 return MessageBoxW(hwnd
, text
, caption
, uType
);
42 static WCHAR
*get_program_name(HANDLE hProcess
)
44 WCHAR image_name
[MAX_PATH
];
48 /* GetProcessImageFileNameW gives no way to query the correct buffer size,
49 * but programs with a path longer than MAX_PATH can't be started by the
50 * shell, so we expect they don't happen often */
51 if (!GetProcessImageFileNameW(hProcess
, image_name
, MAX_PATH
))
53 static WCHAR unidentified
[MAX_PROGRAM_NAME_LENGTH
];
54 LoadStringW(GetModuleHandleW(NULL
), IDS_UNIDENTIFIED
,
55 unidentified
, MAX_PROGRAM_NAME_LENGTH
);
59 programname
= strrchrW(image_name
, '\\');
60 if (programname
!= NULL
)
63 programname
= image_name
;
65 /* TODO: if the image has a VERSIONINFO, we could try to find there a more
66 * user-friendly program name */
68 /* don't display a too long string to the user */
69 if (strlenW(programname
) >= MAX_PROGRAM_NAME_LENGTH
)
71 programname
[MAX_PROGRAM_NAME_LENGTH
- 4] = '.';
72 programname
[MAX_PROGRAM_NAME_LENGTH
- 3] = '.';
73 programname
[MAX_PROGRAM_NAME_LENGTH
- 2] = '.';
74 programname
[MAX_PROGRAM_NAME_LENGTH
- 1] = 0;
77 output
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*(lstrlenW(programname
) + 1));
78 lstrcpyW(output
, programname
);
83 static LPWSTR g_ProgramName
;
84 static HFONT g_hBoldFont
;
85 static HMENU g_hDebugMenu
= NULL
;
87 static void set_bold_font(HWND hDlg
)
89 HFONT hNormalFont
= (HFONT
)SendDlgItemMessageW(hDlg
, IDC_STATIC_TXT1
,
92 GetObjectW(hNormalFont
, sizeof(LOGFONTW
), &font
);
93 font
.lfWeight
= FW_BOLD
;
94 g_hBoldFont
= CreateFontIndirectW(&font
);
95 SendDlgItemMessageW(hDlg
, IDC_STATIC_TXT1
, WM_SETFONT
, (WPARAM
)g_hBoldFont
, TRUE
);
98 static void set_message_with_filename(HWND hDlg
)
100 WCHAR originalText
[1000];
101 WCHAR newText
[1000 + MAX_PROGRAM_NAME_LENGTH
];
103 GetDlgItemTextW(hDlg
, IDC_STATIC_TXT1
, originalText
,
104 sizeof(originalText
)/sizeof(originalText
[0]));
105 wsprintfW(newText
, originalText
, g_ProgramName
);
106 SetDlgItemTextW(hDlg
, IDC_STATIC_TXT1
, newText
);
109 static INT_PTR WINAPI
DlgProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
116 set_message_with_filename(hwnd
);
119 case WM_CTLCOLORSTATIC
:
121 /* WM_CTLCOLOR* don't use DWLP_MSGRESULT */
122 INT_PTR id
= GetDlgCtrlID((HWND
)lParam
);
123 if (id
== IDC_STATIC_BG
|| id
== IDC_STATIC_TXT1
)
124 return (LONG_PTR
)GetSysColorBrush(COLOR_WINDOW
);
131 if (!(wParam
& MK_SHIFT
))
133 if (g_hDebugMenu
== NULL
)
134 g_hDebugMenu
= LoadMenuW(GetModuleHandleW(NULL
), MAKEINTRESOURCEW(IDM_DEBUG_POPUP
));
135 GetCursorPos(&mousePos
);
136 TrackPopupMenu(GetSubMenu(g_hDebugMenu
, 0), TPM_RIGHTBUTTON
, mousePos
.x
, mousePos
.y
,
141 switch (LOWORD(wParam
))
146 EndDialog(hwnd
, LOWORD(wParam
));
154 BOOL
display_crash_dialog(void)
156 static const WCHAR winedeviceW
[] = {'w','i','n','e','d','e','v','i','c','e','.','e','x','e',0};
159 /* dbg_curr_process->handle is not set */
162 if (!DBG_IVAR(ShowCrashDialog
))
165 hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, dbg_curr_pid
);
166 g_ProgramName
= get_program_name(hProcess
);
167 CloseHandle(hProcess
);
168 if (!strcmpW( g_ProgramName
, winedeviceW
)) return TRUE
;
169 result
= DialogBoxW(GetModuleHandleW(NULL
), MAKEINTRESOURCEW(IDD_CRASH_DLG
), NULL
, DlgProc
);
170 if (result
== ID_DEBUG
) {