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
28 #include "wine/debug.h"
29 #include "wine/unicode.h"
33 #define MAX_PROGRAM_NAME_LENGTH 80
35 int msgbox_res_id(HWND hwnd
, UINT textId
, UINT captionId
, UINT uType
)
39 LoadStringW(GetModuleHandleW(NULL
), captionId
, caption
, sizeof(caption
)/sizeof(caption
[0]));
40 LoadStringW(GetModuleHandleW(NULL
), textId
, text
, sizeof(text
)/sizeof(text
[0]));
41 return MessageBoxW(hwnd
, text
, caption
, uType
);
44 static WCHAR
*get_program_name(HANDLE hProcess
)
46 WCHAR image_name
[MAX_PATH
];
50 /* GetProcessImageFileNameW gives no way to query the correct buffer size,
51 * but programs with a path longer than MAX_PATH can't be started by the
52 * shell, so we expect they don't happen often */
53 if (!GetProcessImageFileNameW(hProcess
, image_name
, MAX_PATH
))
55 static WCHAR unidentified
[MAX_PROGRAM_NAME_LENGTH
];
56 LoadStringW(GetModuleHandleW(NULL
), IDS_UNIDENTIFIED
,
57 unidentified
, MAX_PROGRAM_NAME_LENGTH
);
61 programname
= strrchrW(image_name
, '\\');
62 if (programname
!= NULL
)
65 programname
= image_name
;
67 /* TODO: if the image has a VERSIONINFO, we could try to find there a more
68 * user-friendly program name */
70 /* don't display a too long string to the user */
71 if (strlenW(programname
) >= MAX_PROGRAM_NAME_LENGTH
)
73 programname
[MAX_PROGRAM_NAME_LENGTH
- 4] = '.';
74 programname
[MAX_PROGRAM_NAME_LENGTH
- 3] = '.';
75 programname
[MAX_PROGRAM_NAME_LENGTH
- 2] = '.';
76 programname
[MAX_PROGRAM_NAME_LENGTH
- 1] = 0;
79 output
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*(lstrlenW(programname
) + 1));
80 lstrcpyW(output
, programname
);
85 static LPWSTR g_ProgramName
;
86 static HFONT g_hBoldFont
;
87 static HMENU g_hDebugMenu
= NULL
;
89 static void set_bold_font(HWND hDlg
)
91 HFONT hNormalFont
= (HFONT
)SendDlgItemMessageW(hDlg
, IDC_STATIC_TXT1
,
94 GetObjectW(hNormalFont
, sizeof(LOGFONTW
), &font
);
95 font
.lfWeight
= FW_BOLD
;
96 g_hBoldFont
= CreateFontIndirectW(&font
);
97 SendDlgItemMessageW(hDlg
, IDC_STATIC_TXT1
, WM_SETFONT
, (WPARAM
)g_hBoldFont
, TRUE
);
100 static void set_message_with_filename(HWND hDlg
)
102 WCHAR originalText
[1000];
103 WCHAR newText
[1000 + MAX_PROGRAM_NAME_LENGTH
];
105 GetDlgItemTextW(hDlg
, IDC_STATIC_TXT1
, originalText
,
106 sizeof(originalText
)/sizeof(originalText
[0]));
107 wsprintfW(newText
, originalText
, g_ProgramName
);
108 SetDlgItemTextW(hDlg
, IDC_STATIC_TXT1
, newText
);
111 static INT_PTR WINAPI
DlgProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
113 static const WCHAR openW
[] = {'o','p','e','n',0};
119 set_message_with_filename(hwnd
);
122 case WM_CTLCOLORSTATIC
:
124 /* WM_CTLCOLOR* don't use DWLP_MSGRESULT */
125 INT_PTR id
= GetDlgCtrlID((HWND
)lParam
);
126 if (id
== IDC_STATIC_BG
|| id
== IDC_STATIC_TXT1
)
127 return (LONG_PTR
)GetSysColorBrush(COLOR_WINDOW
);
134 if (!(wParam
& MK_SHIFT
))
136 if (g_hDebugMenu
== NULL
)
137 g_hDebugMenu
= LoadMenuW(GetModuleHandleW(NULL
), MAKEINTRESOURCEW(IDM_DEBUG_POPUP
));
138 GetCursorPos(&mousePos
);
139 TrackPopupMenu(GetSubMenu(g_hDebugMenu
, 0), TPM_RIGHTBUTTON
, mousePos
.x
, mousePos
.y
,
144 switch (((NMHDR
*)lParam
)->code
)
148 if (wParam
== IDC_STATIC_TXT2
)
149 ShellExecuteW( NULL
, openW
, ((NMLINK
*)lParam
)->item
.szUrl
, NULL
, NULL
, SW_SHOW
);
155 switch (LOWORD(wParam
))
160 EndDialog(hwnd
, LOWORD(wParam
));
168 BOOL
display_crash_dialog(void)
170 static const WCHAR winedeviceW
[] = {'w','i','n','e','d','e','v','i','c','e','.','e','x','e',0};
171 static const INITCOMMONCONTROLSEX init
= { sizeof(init
), ICC_LINK_CLASS
};
174 /* dbg_curr_process->handle is not set */
177 if (!DBG_IVAR(ShowCrashDialog
))
180 hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, dbg_curr_pid
);
181 g_ProgramName
= get_program_name(hProcess
);
182 CloseHandle(hProcess
);
183 if (!strcmpW( g_ProgramName
, winedeviceW
)) return TRUE
;
184 InitCommonControlsEx( &init
);
185 result
= DialogBoxW(GetModuleHandleW(NULL
), MAKEINTRESOURCEW(IDD_CRASH_DLG
), NULL
, DlgProc
);
186 if (result
== ID_DEBUG
) {