Use TaskDialog if possible
[TortoiseGit.git] / src / Utils / MiscUI / MessageBox.cpp
blob1fe3e558c6fea8a324af736a5ef580b5456c88a8
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2012-2016 - TortoiseGit
4 // Copyright (C) 2003-2008,2010 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program 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
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "resource.h" //if you defined some IDS_MSGBOX_xxxx this include is needed!
22 #include "messagebox.h"
23 #include "ClipboardHelper.h"
24 #include "SmartHandle.h"
25 #include <afxtaskdialog.h>
27 #define BTN_OFFSET 100 // use an offset in order to not interfere with IDYES and so on...
29 CMessageBox::CMessageBox(void)
30 : m_hIcon(nullptr)
31 , m_uButton1Ret(1)
32 , m_uButton2Ret(2)
33 , m_uButton3Ret(3)
34 , m_uCancelRet(0)
35 , m_bShowCheck(FALSE)
36 , m_bDestroyIcon(FALSE)
37 , m_nDefButton(0)
38 , m_uType(0)
39 , m_bChecked(FALSE)
41 SecureZeroMemory(&m_LogFont, sizeof(LOGFONT));
44 CMessageBox::~CMessageBox(void)
46 if (m_bDestroyIcon)
47 ::DestroyIcon(m_hIcon);
50 UINT CMessageBox::ShowCheck(HWND hWnd, UINT nMessage, UINT nCaption, int nDef, LPCTSTR icon, UINT nButton1, UINT nButton2, UINT nButton3, LPCTSTR lpRegistry, UINT nCheckMessage/* = nullptr*/, BOOL* bChecked)
52 CString sButton1;
53 CString sButton2;
54 CString sButton3;
55 CString sMessage;
56 CString sCaption;
57 CString nCheckMsg;
58 sButton1.LoadString(nButton1);
59 sButton2.LoadString(nButton2);
60 sButton3.LoadString(nButton3);
61 sMessage.LoadString(nMessage);
62 sCaption.LoadString(nCaption);
63 nCheckMsg.LoadString(nCheckMessage);
64 return CMessageBox::ShowCheck(hWnd, sMessage, sCaption, nDef, icon, sButton1, sButton2, sButton3, lpRegistry, nCheckMsg, bChecked);
67 UINT CMessageBox::ShowCheck(HWND hWnd, LPCTSTR lpMessage, LPCTSTR lpCaption, int nDef, LPCTSTR icon, LPCTSTR lpButton1, LPCTSTR lpButton2, LPCTSTR lpButton3, LPCTSTR lpRegistry, LPCTSTR lpCheckMessage/* = nullptr*/, BOOL* bChecked)
69 //check the registry if we have to show the box or just return with the last used return value
70 //this would be the case if the user pressed "do not show again".
71 DWORD dwRetVal;
72 HKEY hKey;
73 CString path;
74 #ifdef XMESSAGEBOX_APPREGPATH
75 path = XMESSAGEBOX_APPREGPATH;
76 #else
77 path = "Software\\TortoiseGit\\";
78 path += AfxGetApp()->m_pszProfileName;
79 #endif
80 if (lpRegistry && *lpRegistry && RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_EXECUTE, &hKey)==ERROR_SUCCESS)
82 int size = sizeof(dwRetVal);
83 DWORD type;
84 if (RegQueryValueEx(hKey, lpRegistry, nullptr, &type, (BYTE*)&dwRetVal,(LPDWORD)&size) == ERROR_SUCCESS)
86 ASSERT(type==REG_DWORD);
87 RegCloseKey(hKey);
88 CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Using stored value %ld for \"%s\"\n"), dwRetVal, lpMessage);
89 return (UINT)dwRetVal; //return with the last saved value
91 else
93 RegCloseKey(hKey);
97 if (CTaskDialog::IsSupported())
99 CTaskDialog taskdlg(lpMessage, L"", lpCaption, 0, TDF_USE_COMMAND_LINKS | TDF_POSITION_RELATIVE_TO_WINDOW);
100 taskdlg.AddCommandControl(BTN_OFFSET + 1, lpButton1);
101 if (lpButton2 && *lpButton2)
102 taskdlg.AddCommandControl(BTN_OFFSET + 2, lpButton2);
103 if (lpButton3 && *lpButton3)
104 taskdlg.AddCommandControl(BTN_OFFSET + 3, lpButton3);
105 taskdlg.SetDefaultCommandControl(BTN_OFFSET + nDef);
106 taskdlg.SetMainIcon(icon);
107 if (!lpCheckMessage)
109 #ifndef IDS_MSGBOX_DONOTSHOWAGAIN
110 taskdlg.SetVerificationCheckboxText(L"do not show again");
111 #else
112 CString m_i18l;
113 m_i18l.LoadString(IDS_MSGBOX_DONOTSHOWAGAIN);
114 taskdlg.SetVerificationCheckboxText(m_i18l);
115 #endif
117 else
118 taskdlg.SetVerificationCheckboxText(lpCheckMessage);
119 int result = (int)taskdlg.DoModal(hWnd) - BTN_OFFSET;
120 if (bChecked)
121 *bChecked = taskdlg.GetVerificationCheckboxState();
122 if (lpRegistry && *lpRegistry && taskdlg.GetVerificationCheckboxState())
123 SetRegistryValue(lpRegistry, result);
125 return result;
128 CMessageBox box;
129 box.m_bShowCheck = TRUE;
130 box.m_sRegistryValue = lpRegistry;
131 if (!lpCheckMessage)
133 #ifndef IDS_MSGBOX_DONOTSHOWAGAIN
134 box.m_sCheckbox = _T("do not show again");
135 #else
136 CString m_i18l;
137 m_i18l.LoadString(IDS_MSGBOX_DONOTSHOWAGAIN);
138 box.m_sCheckbox = m_i18l;
139 #endif
141 else
142 box.m_sCheckbox = lpCheckMessage;
143 box.m_bChecked = bChecked ? *bChecked : FALSE;
144 box.m_sButton1 = lpButton1;
145 box.m_sButton2 = lpButton2;
146 box.m_sButton3 = lpButton3;
147 box.m_hIcon = (HICON)::LoadImage(AfxGetResourceHandle(), icon, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
148 if (!box.m_hIcon)
149 box.m_hIcon = (HICON)::LoadImage(nullptr, icon, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
150 else
151 box.m_bDestroyIcon = TRUE;
152 if (!IsWindow(hWnd))
153 hWnd = nullptr;
154 int result = box.GoModal(CWnd::FromHandle(hWnd), lpCaption, lpMessage, nDef);
155 if (bChecked)
156 *bChecked = box.m_bChecked;
157 return result;
160 UINT CMessageBox::Show(HWND hWnd, LPCTSTR lpMessage, LPCTSTR lpCaption, int nDef, LPCTSTR icon, LPCTSTR lpButton1, LPCTSTR lpButton2/* = nullptr*/, LPCTSTR lpButton3/* = nullptr*/)
162 if (CTaskDialog::IsSupported())
164 CTaskDialog taskdlg(lpMessage, L"", lpCaption, 0, TDF_USE_COMMAND_LINKS | TDF_POSITION_RELATIVE_TO_WINDOW);
165 taskdlg.AddCommandControl(BTN_OFFSET + 1, lpButton1);
166 if (lpButton2 && *lpButton2)
167 taskdlg.AddCommandControl(BTN_OFFSET + 2, lpButton2);
168 if (lpButton3 && *lpButton3)
169 taskdlg.AddCommandControl(BTN_OFFSET + 3, lpButton3);
170 taskdlg.SetDefaultCommandControl(BTN_OFFSET + nDef);
171 taskdlg.SetMainIcon(icon);
172 return (UINT)taskdlg.DoModal(hWnd) - BTN_OFFSET;
174 CMessageBox box;
175 box.m_sButton1 = lpButton1;
176 box.m_sButton2 = lpButton2;
177 box.m_sButton3 = lpButton3;
178 box.m_hIcon = (HICON)::LoadImage(AfxGetResourceHandle(), icon, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
179 if (!box.m_hIcon)
180 box.m_hIcon = (HICON)::LoadImage(nullptr, icon, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
181 else
182 box.m_bDestroyIcon = TRUE;
183 if (!IsWindow(hWnd))
184 hWnd = nullptr;
185 return box.GoModal(CWnd::FromHandle(hWnd), lpCaption, lpMessage, nDef);
188 UINT CMessageBox::Show(HWND hWnd, UINT nMessage, UINT nCaption, int nDef, LPCTSTR icon, UINT nButton1, UINT nButton2, UINT nButton3)
190 CString sButton1;
191 CString sButton2;
192 CString sButton3;
193 CString sMessage;
194 CString sCaption;
195 sButton1.LoadString(nButton1);
196 sButton2.LoadString(nButton2);
197 sButton3.LoadString(nButton3);
198 sMessage.LoadString(nMessage);
199 sCaption.LoadString(nCaption);
200 return CMessageBox::Show(hWnd, sMessage, sCaption, nDef, icon, sButton1, sButton2, sButton3);
203 UINT CMessageBox::ShowCheck(HWND hWnd, UINT nMessage, UINT nCaption, UINT uType, LPCTSTR lpRegistry, UINT nCheckMessage, BOOL *bChecked)
205 CString sMessage;
206 CString sCaption;
207 CString sCheckMsg;
208 sMessage.LoadString(nMessage);
209 sCaption.LoadString(nCaption);
210 sCheckMsg.LoadString(nCheckMessage);
211 return CMessageBox::ShowCheck(hWnd, sMessage, sCaption, uType, lpRegistry, sCheckMsg, bChecked);
214 UINT CMessageBox::ShowCheck(HWND hWnd, LPCTSTR lpMessage, LPCTSTR lpCaption, UINT uType, LPCTSTR lpRegistry, LPCTSTR lpCheckMessage, BOOL *bChecked)
216 //check the registry if we have to show the box or just return with the last used return value
217 //this would be the case if the user pressed "do not show again".
218 DWORD dwRetVal;
219 HKEY hKey;
220 CString path;
221 #ifdef XMESSAGEBOX_APPREGPATH
222 path = XMESSAGEBOX_APPREGPATH;
223 #else
224 path = "Software\\TortoiseGit\\";
225 path += AfxGetApp()->m_pszProfileName;
226 #endif
227 if (lpRegistry && *lpRegistry && RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_EXECUTE, &hKey)==ERROR_SUCCESS)
229 int size = sizeof(dwRetVal);
230 DWORD type;
231 if (RegQueryValueEx(hKey, lpRegistry, nullptr, &type, (BYTE*)&dwRetVal,(LPDWORD)&size) == ERROR_SUCCESS)
233 ASSERT(type==REG_DWORD);
234 RegCloseKey(hKey);
235 CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Using stored value %ld for \"%s\"\n"), dwRetVal, lpMessage);
236 return (UINT)dwRetVal; //return with the last saved value
238 else
240 RegCloseKey(hKey);
243 if (CTaskDialog::IsSupported() && !(uType & MB_HELP) && !((uType & 0xf) == MB_ABORTRETRYIGNORE) && !((uType & 0xf) == MB_CANCELTRYCONTINUE))
245 CTaskDialog taskdlg(lpMessage, L"", lpCaption, 0, TDF_POSITION_RELATIVE_TO_WINDOW);
246 // set up icon
247 switch (uType & 0xf0)
249 case MB_ICONEXCLAMATION:
250 taskdlg.SetMainIcon(IDI_EXCLAMATION);
251 break;
252 case MB_ICONASTERISK:
253 taskdlg.SetMainIcon(IDI_ASTERISK);
254 break;
255 case MB_ICONQUESTION:
256 taskdlg.SetMainIcon(IDI_QUESTION);
257 break;
258 case MB_ICONHAND:
259 taskdlg.SetMainIcon(IDI_HAND);
260 break;
262 // set up the buttons
263 switch (uType & 0xf)
265 case MB_ABORTRETRYIGNORE:
266 ASSERT(FALSE);
267 break;
268 case MB_CANCELTRYCONTINUE:
269 ASSERT(FALSE);
270 break;
271 case MB_OKCANCEL:
272 taskdlg.SetCommonButtons(TDCBF_OK_BUTTON | TDCBF_CANCEL_BUTTON);
273 switch (uType & 0xf00)
275 case MB_DEFBUTTON2:
276 taskdlg.SetDefaultCommandControl(IDCANCEL);
277 break;
279 break;
280 case MB_RETRYCANCEL:
281 taskdlg.SetCommonButtons(TDCBF_RETRY_BUTTON | TDCBF_CANCEL_BUTTON);
282 switch (uType & 0xf00)
284 case MB_DEFBUTTON2:
285 taskdlg.SetDefaultCommandControl(IDCANCEL);
286 break;
288 break;
289 case MB_YESNO:
290 taskdlg.SetCommonButtons(TDCBF_YES_BUTTON | TDCBF_NO_BUTTON);
291 switch (uType & 0xf00)
293 case MB_DEFBUTTON2:
294 taskdlg.SetDefaultCommandControl(IDNO);
295 break;
297 break;
298 case MB_YESNOCANCEL:
299 taskdlg.SetCommonButtons(TDCBF_YES_BUTTON | TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON);
300 switch (uType & 0xf00)
302 case MB_DEFBUTTON2:
303 taskdlg.SetDefaultCommandControl(IDNO);
304 break;
305 case MB_DEFBUTTON3:
306 taskdlg.SetDefaultCommandControl(IDCANCEL);
307 break;
309 break;
310 case MB_OK:
311 default:
312 taskdlg.SetCommonButtons(TDCBF_OK_BUTTON);
315 if (!lpCheckMessage)
317 #ifndef IDS_MSGBOX_DONOTSHOWAGAIN
318 taskdlg.SetVerificationCheckboxText(L"do not show again");
319 #else
320 CString m_i18l;
321 m_i18l.LoadString(IDS_MSGBOX_DONOTSHOWAGAIN);
322 taskdlg.SetVerificationCheckboxText(m_i18l);
323 #endif
325 else
326 taskdlg.SetVerificationCheckboxText(lpCheckMessage);
327 int result = (int)taskdlg.DoModal(hWnd) - BTN_OFFSET;
328 if (bChecked)
329 *bChecked = taskdlg.GetVerificationCheckboxState();
330 if (lpRegistry && *lpRegistry && taskdlg.GetVerificationCheckboxState())
331 SetRegistryValue(lpRegistry, result);
333 return result;
336 CMessageBox box;
337 box.m_bShowCheck = TRUE;
338 box.m_sRegistryValue = lpRegistry;
339 if (!lpCheckMessage)
341 #ifndef IDS_MSGBOX_DONOTSHOWAGAIN
342 box.m_sCheckbox = _T("do not show again");
343 #else
344 CString m_i18l;
345 m_i18l.LoadString(IDS_MSGBOX_DONOTSHOWAGAIN);
346 box.m_sCheckbox = m_i18l;
347 #endif
349 else
350 box.m_sCheckbox = lpCheckMessage;
351 box.m_bChecked = bChecked ? *bChecked : FALSE;
352 if (!IsWindow(hWnd))
353 hWnd = nullptr;
354 int result = box.GoModal(CWnd::FromHandle(hWnd), lpCaption, lpMessage, box.FillBoxStandard(uType));
355 if (bChecked)
356 *bChecked = box.m_bChecked;
357 return result;
360 UINT CMessageBox::Show(HWND hWnd, UINT nMessage, UINT nCaption, UINT uType, LPCTSTR sHelpPath)
362 CString sMessage;
363 CString sCaption;
364 sMessage.LoadString(nMessage);
365 sCaption.LoadString(nCaption);
366 return CMessageBox::Show(hWnd, sMessage, sCaption, uType, sHelpPath);
369 UINT CMessageBox::Show(HWND hWnd, LPCTSTR lpMessage, LPCTSTR lpCaption, UINT uType, LPCTSTR sHelpPath)
371 if (!IsWindow(hWnd))
372 hWnd = nullptr;
373 if (sHelpPath)
375 CMessageBox box;
376 box.SetHelpPath(sHelpPath);
377 return box.GoModal(CWnd::FromHandle(hWnd), lpCaption, lpMessage, box.FillBoxStandard(uType));
379 return ::MessageBox(hWnd, lpMessage, lpCaption, uType);
382 UINT CMessageBox::Show(HWND hWnd, UINT nMessage, UINT nCaption, UINT uType, UINT nHelpID)
384 CString sMessage;
385 CString sCaption;
386 sMessage.LoadString(nMessage);
387 sCaption.LoadString(nCaption);
389 if (!IsWindow(hWnd))
390 hWnd = nullptr;
391 if (nHelpID)
393 CMessageBox box;
394 box.SetHelpID(nHelpID);
395 return box.GoModal(CWnd::FromHandle(hWnd), sCaption, sMessage, box.FillBoxStandard(uType));
398 return ::MessageBox(hWnd, sMessage, sCaption, uType);
401 bool CMessageBox::RemoveRegistryKey(LPCTSTR lpRegistry)
403 HKEY hKey;
404 CString path;
405 #ifdef XMESSAGEBOX_APPREGPATH
406 path = XMESSAGEBOX_APPREGPATH;
407 #else
408 path = "Software\\TortoiseGit\\";
409 path += AfxGetApp()->m_pszProfileName;
410 #endif
411 if (RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_WRITE, &hKey) == ERROR_SUCCESS)
413 bool ret = !!RegDeleteValue(hKey, lpRegistry);
414 RegCloseKey(hKey);
415 return ret;
417 return false;
420 int CMessageBox::FillBoxStandard(UINT uType)
422 int ret = 1;
423 m_uType = uType;
424 m_uCancelRet = IDCANCEL;
425 //load the icons according to uType
426 switch (uType & 0xf0)
428 case MB_ICONEXCLAMATION:
429 m_hIcon = (HICON)::LoadImage(nullptr, IDI_EXCLAMATION, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
430 ::MessageBeep(MB_ICONEXCLAMATION);
431 break;
432 case MB_ICONASTERISK:
433 m_hIcon = (HICON)::LoadImage(nullptr, IDI_ASTERISK, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
434 ::MessageBeep(MB_ICONASTERISK);
435 break;
436 case MB_ICONQUESTION:
437 m_hIcon = (HICON)::LoadImage(nullptr, IDI_QUESTION, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
438 ::MessageBeep(MB_ICONQUESTION);
439 break;
440 case MB_ICONHAND:
441 m_hIcon = (HICON)::LoadImage(nullptr, IDI_HAND, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
442 ::MessageBeep(MB_ICONHAND);
443 break;
445 //set up the button texts
446 switch (uType & 0xf)
448 case MB_ABORTRETRYIGNORE:
449 #ifndef IDS_MSGBOX_ABORT
450 m_sButton1 = "&Abort";
451 #else
452 m_i18l.LoadString(IDS_MSGBOX_ABORT);
453 m_sButton1 = m_i18l;
454 #endif
455 m_uButton1Ret = IDABORT;
456 #ifndef IDS_MSGBOX_RETRY
457 m_sButton2 = "&Retry";
458 #else
459 m_i18l.LoadString(IDS_MSGBOX_RETRY);
460 m_sButton2 = m_i18l;
461 #endif
462 m_uButton2Ret = IDRETRY;
463 #ifndef IDS_MSGBOX_IGNORE
464 m_sButton3 = "&Ignore";
465 #else
466 m_i18l.LoadString(IDS_MSGBOX_IGNORE);
467 m_sButton3 = m_i18l;
468 #endif
469 m_uButton3Ret = IDIGNORE;
470 break;
471 case MB_CANCELTRYCONTINUE:
472 #ifndef IDS_MSGBOX_CANCEL
473 m_sButton1 = "Cancel";
474 #else
475 m_i18l.LoadString(IDS_MSGBOX_CANCEL);
476 m_sButton1 = m_i18l;
477 #endif
478 m_uButton1Ret = IDCANCEL;
479 #ifndef IDS_MSGBOX_TRYAGAIN
480 m_sButton2 = "&Try Again";
481 #else
482 m_i18l.LoadString(IDS_MSGBOX_TRYAGAIN);
483 m_sButton2 = m_i18l;
484 #endif
485 m_uButton2Ret = IDTRYAGAIN;
486 #ifndef IDS_MSGBOX_CONTINUE
487 m_sButton3 = "&Continue";
488 #else
489 m_i18l.LoadString(IDS_MSGBOX_CONTINUE);
490 m_sButton3 = m_i18l;
491 #endif
492 m_uButton3Ret = IDCONTINUE;
493 break;
494 case MB_OKCANCEL:
495 #ifndef IDS_MSGBOX_OK
496 m_sButton1 = "OK";
497 #else
498 m_i18l.LoadString(IDS_MSGBOX_OK);
499 m_sButton1 = m_i18l;
500 #endif
501 m_uButton1Ret = IDOK;
502 #ifndef IDS_MSGBOX_CANCEL
503 m_sButton2 = "Cancel";
504 #else
505 m_i18l.LoadString(IDS_MSGBOX_CANCEL);
506 m_sButton2 = m_i18l;
507 #endif
508 m_uButton2Ret = IDCANCEL;
509 break;
510 case MB_RETRYCANCEL:
511 #ifndef IDS_MSGBOX_RETRY
512 m_sButton1 = "&Retry";
513 #else
514 m_i18l.LoadString(IDS_MSGBOX_RETRY);
515 m_sButton1 = m_i18l;
516 #endif
517 m_uButton1Ret = IDRETRY;
518 #ifndef IDS_MSGBOX_CANCEL
519 m_sButton2 = "Cancel";
520 #else
521 m_i18l.LoadString(IDS_MSGBOX_CANCEL);
522 m_sButton2 = m_i18l;
523 #endif
524 m_uButton2Ret = IDCANCEL;
525 break;
526 case MB_YESNO:
527 #ifndef IDS_MSGBOX_YES
528 m_sButton1 = "&Yes";
529 #else
530 m_i18l.LoadString(IDS_MSGBOX_YES);
531 m_sButton1 = m_i18l;
532 #endif
533 m_uButton1Ret = IDYES;
534 #ifndef IDS_MSGBOX_NO
535 m_sButton2 = "&No";
536 #else
537 m_i18l.LoadString(IDS_MSGBOX_NO);
538 m_sButton2 = m_i18l;
539 #endif
540 m_uButton2Ret = IDNO;
541 break;
542 case MB_YESNOCANCEL:
543 #ifndef IDS_MSGBOX_YES
544 m_sButton1 = "&Yes";
545 #else
546 m_i18l.LoadString(IDS_MSGBOX_YES);
547 m_sButton1 = m_i18l;
548 #endif
549 m_uButton1Ret = IDYES;
550 #ifndef IDS_MSGBOX_NO
551 m_sButton2 = "&No";
552 #else
553 m_i18l.LoadString(IDS_MSGBOX_NO);
554 m_sButton2 = m_i18l;
555 #endif
556 m_uButton2Ret = IDNO;
557 #ifndef IDS_MSGBOX_CANCEL
558 m_sButton3 = "Cancel";
559 #else
560 m_i18l.LoadString(IDS_MSGBOX_CANCEL);
561 m_sButton3 = m_i18l;
562 #endif
563 m_uButton3Ret = IDCANCEL;
564 break;
565 case MB_OK:
566 default:
567 #ifndef IDS_MSGBOX_OK
568 m_sButton1 = "OK";
569 #else
570 m_i18l.LoadString(IDS_MSGBOX_OK);
571 m_sButton1 = m_i18l;
572 #endif
574 //now set the default button
575 switch (uType & 0xf00)
577 case MB_DEFBUTTON2:
578 ret = 2;
579 break;
580 case MB_DEFBUTTON3:
581 ret = 3;
582 break;
584 // do we need to add a help button?
585 if (uType & MB_HELP)
587 CString sHelpText;
588 #ifndef IDS_MSGBOX_HELP
589 sHelpText = _T("Help");
590 #else
591 m_i18l.LoadString(IDS_MSGBOX_HELP);
592 sHelpText = m_i18l;
593 #endif
594 if (m_sButton2.IsEmpty())
596 m_sButton2 = sHelpText;
597 m_uButton2Ret = IDHELP;
599 else if (m_sButton3.IsEmpty())
601 m_sButton3 = sHelpText;
602 m_uButton3Ret = IDHELP;
605 return ret;
608 UINT CMessageBox::GoModal(CWnd * pWnd, const CString& title, const CString& msg, int nDefaultButton)
610 // pre Vista struct, needed for Windows XP
611 struct OLD_NONCLIENTMETRICS
613 UINT cbSize;
614 int iBorderWidth;
615 int iScrollWidth;
616 int iScrollHeight;
617 int iCaptionWidth;
618 int iCaptionHeight;
619 LOGFONT lfCaptionFont;
620 int iSmCaptionWidth;
621 int iSmCaptionHeight;
622 LOGFONT lfSmCaptionFont;
623 int iMenuWidth;
624 int iMenuHeight;
625 LOGFONT lfMenuFont;
626 LOGFONT lfStatusFont;
627 LOGFONT lfMessageFont;
629 const UINT cbProperSize = sizeof(OLD_NONCLIENTMETRICS);
631 NONCLIENTMETRICS ncm = { 0 };
632 ncm.cbSize = cbProperSize;
633 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);
635 memcpy(&m_LogFont, &(ncm.lfMessageFont), sizeof(LOGFONT));
637 //the problem with the LOGFONT lfHeight is that it is not in pixels,
638 //but the dialog template needs the height in pixels.
639 //We need to convert those values first:
640 CDC * pDC;
641 if (pWnd)
642 pDC = pWnd->GetDC();
643 else
644 pDC = GetDesktopWindow()->GetDC();
645 HDC hdc;
646 if (pDC)
647 hdc = pDC->m_hDC;
648 else
649 hdc = ::GetDC(nullptr);
650 if (!hdc)
652 HWND hw = pWnd ? pWnd->m_hWnd : nullptr;
653 int defButton = nDefaultButton == 1 ? MB_DEFBUTTON1 : nDefaultButton == 2 ? MB_DEFBUTTON2 : nDefaultButton == 3 ? MB_DEFBUTTON3 : 0;
654 return ::MessageBox(hw, msg, title, m_uType | defButton);
657 int pix = -MulDiv(m_LogFont.lfHeight, 72, GetDeviceCaps(hdc, LOGPIXELSY));
658 CDlgTemplate dialogTemplate = CDlgTemplate(title, WS_CAPTION | DS_CENTER,
659 0, 0, 0, 0, m_LogFont.lfFaceName, pix);
660 dialogTemplate.AddButton(_T("Button1"), WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | ((nDefaultButton == 1) ? BS_DEFPUSHBUTTON : 0), 0,
661 2 + 3, 62, 56, 13, IDC_MESSAGEBOX_BUTTON1);
662 dialogTemplate.AddButton(_T("Button2"), WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | ((nDefaultButton == 2) ? BS_DEFPUSHBUTTON : 0), 0,
663 2 + 3, 62, 56, 13, IDC_MESSAGEBOX_BUTTON2);
664 dialogTemplate.AddButton(_T("Button3"), WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | ((nDefaultButton == 3) ? BS_DEFPUSHBUTTON : 0), 0,
665 2 + 3, 62, 56, 13, IDC_MESSAGEBOX_BUTTON3);
666 dialogTemplate.AddButton(_T("Checkbox"), WS_CHILD | WS_TABSTOP | BS_AUTOCHECKBOX, 0,
667 0, 0, 0, 0, IDC_MESSAGEBOX_CHECKBOX);
669 m_nDefButton = nDefaultButton;
670 m_sMessage = msg;
671 InitModalIndirect(dialogTemplate, pWnd);
673 return (UINT)DoModal();
676 void CMessageBox::SetRegistryValue(const CString& sValue, DWORD value)
678 if (sValue.IsEmpty())
679 return;
681 CString path;
682 #ifdef XMESSAGEBOX_APPREGPATH
683 path = XMESSAGEBOX_APPREGPATH;
684 #else
685 path = "Software\\TortoiseGit\\";
686 path += AfxGetApp()->m_pszProfileName;
687 #endif
688 DWORD disp;
689 HKEY hKey;
690 if (RegCreateKeyEx(HKEY_CURRENT_USER, path, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, nullptr, &hKey, &disp) != ERROR_SUCCESS)
692 return;
694 RegSetValueEx(hKey, sValue, 0, REG_DWORD,(const BYTE*) &value, sizeof(value));
695 RegCloseKey(hKey);
698 CSize CMessageBox::GetTextSize(const CString& str)
700 CRect rect;
701 GetWindowRect(&rect);
703 CDC * pDC = GetDC();
705 CDC memDC;
706 CBitmap bitmap;
707 memDC.CreateCompatibleDC(pDC);
708 bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
709 CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
711 //get the minimum size of the rectangle of the tooltip
712 CSize sz = DrawHTML(&memDC, rect, str, m_LogFont, TRUE);
714 memDC.SelectObject(pOldBitmap);
715 memDC.DeleteDC();
716 bitmap.DeleteObject();
718 ReleaseDC(pDC);
720 return sz;
723 CSize CMessageBox::GetIconSize(HICON hIcon)
725 CSize sz (0, 0);
727 if (hIcon)
729 ICONINFO ii = { 0 };
730 //get icon dimensions
731 if (::GetIconInfo(hIcon, &ii))
733 sz.cx = (DWORD)(ii.xHotspot * 2);
734 sz.cy = (DWORD)(ii.yHotspot * 2);
735 //release icon mask bitmaps
736 if(ii.hbmMask)
737 ::DeleteObject(ii.hbmMask);
738 if(ii.hbmColor)
739 ::DeleteObject(ii.hbmColor);
742 m_szIcon = sz;
743 return sz;
746 CSize CMessageBox::GetButtonSize()
748 CSize sz;
749 int nButtons = 0; //number of buttons - 1
751 SetDlgItemText(IDC_MESSAGEBOX_BUTTON1, m_sButton1);
752 SetDlgItemText(IDC_MESSAGEBOX_BUTTON2, m_sButton2);
753 //GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->SendMessage(BM_SETSTYLE, BS_DEFPUSHBUTTON, 1);
754 SetDlgItemText(IDC_MESSAGEBOX_BUTTON3, m_sButton3);
755 SetDlgItemText(IDC_MESSAGEBOX_CHECKBOX, m_sCheckbox);
757 CSize sz1 = GetTextSize(m_sButton1);
758 CSize sz2 = GetTextSize(m_sButton2);
759 CSize sz3 = GetTextSize(m_sButton3);
761 sz1.cx += 2*MESSAGEBOX_BUTTONX;
762 sz1.cy += 2*MESSAGEBOX_BUTTONY;
764 if (sz2.cx)
766 sz2.cx += 2*MESSAGEBOX_BUTTONX;
767 sz2.cy += 2*MESSAGEBOX_BUTTONY;
768 nButtons++;
770 if (sz3.cx)
772 sz3.cx += 2*MESSAGEBOX_BUTTONX;
773 sz3.cy += 2*MESSAGEBOX_BUTTONY;
774 nButtons++;
777 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->MoveWindow(0, 0, sz1.cx, sz1.cy);
778 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->MoveWindow(0, 0, sz2.cx, sz2.cy);
779 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->MoveWindow(0, 0, sz3.cx, sz3.cy);
781 sz.cx = sz1.cx + sz2.cx + sz3.cx + (nButtons * MESSAGEBOX_BUTTONMARGIN);
782 sz.cy = max(sz1.cy, sz2.cy);
783 sz.cy = max(sz.cy, sz3.cy);
784 m_szButtons = sz;
785 if (m_bShowCheck)
787 CSize szCheck = GetTextSize(m_sCheckbox);
788 szCheck.cx += 2*GetSystemMetrics(SM_CXMENUCHECK);
789 szCheck.cy += 2*MESSAGEBOX_BUTTONY;
790 sz.cx = max(sz.cx, szCheck.cx);
791 sz.cy += szCheck.cy + MESSAGEBOX_BUTTONCHECKMARGIN;
792 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->MoveWindow(0, 0, szCheck.cx, szCheck.cy);
794 m_szAllButtons = sz;
795 return sz;
798 BEGIN_MESSAGE_MAP(CMessageBox, CDialog)
799 ON_WM_PAINT()
800 ON_WM_MOUSEMOVE()
801 ON_WM_LBUTTONUP()
802 ON_BN_CLICKED(IDC_MESSAGEBOX_BUTTON1, OnButton1)
803 ON_BN_CLICKED(IDC_MESSAGEBOX_BUTTON2, OnButton2)
804 ON_BN_CLICKED(IDC_MESSAGEBOX_BUTTON3, OnButton3)
805 END_MESSAGE_MAP()
807 void CMessageBox::OnPaint()
809 CPaintDC dc(this); // device context for painting
811 CRect rect;
812 CRect drawrect;
813 GetClientRect(&rect);
814 GetClientRect(&drawrect);
816 //create a memory device-context. This is done to help reduce
817 //screen flicker, since we will paint the entire control to the
818 //off screen device context first.
819 CDC memDC;
820 CBitmap bitmap;
821 memDC.CreateCompatibleDC(&dc);
822 bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
823 CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
825 memDC.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dc, 0,0, SRCCOPY);
827 memDC.SetBkMode(TRANSPARENT);
828 memDC.SetBkColor(GetSysColor(COLOR_WINDOW));
829 memDC.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
831 //OnDrawBackground();
832 drawrect.DeflateRect(MESSAGEBOX_BORDERMARGINX, MESSAGEBOX_BORDERMARGINY);
833 if (m_hIcon)
835 DrawIconEx(memDC.m_hDC, drawrect.left, max(drawrect.top, drawrect.top +
836 ((drawrect.Height() - m_szAllButtons.cy - MESSAGEBOX_TEXTBUTTONMARGIN - m_szIcon.cy) / 2)),
837 m_hIcon, m_szIcon.cx, m_szIcon.cy, 0, nullptr, DI_NORMAL);
839 drawrect.left += m_szIcon.cx + MESSAGEBOX_ICONMARGIN;
840 if (m_szIcon.cy > m_szText.cy)
841 drawrect.top += (m_szIcon.cy - m_szText.cy) / 2;
844 DrawHTML(&memDC, drawrect, m_sMessage, m_LogFont);
846 //Copy the memory device context back into the original DC.
847 dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, 0,0, SRCCOPY);
849 //Cleanup resources.
850 memDC.SelectObject(pOldBitmap);
851 memDC.DeleteDC();
852 bitmap.DeleteObject();
855 void CMessageBox::OnMouseMove(UINT nFlags, CPoint point)
857 if (IsPointOverALink(point))
858 m_Cursor.SetCursor(IDC_HAND);
859 else
860 m_Cursor.Restore();
862 __super::OnMouseMove(nFlags, point);
865 void CMessageBox::OnLButtonUp(UINT nFlags, CPoint point)
867 if (IsPointOverALink(point))
869 CString url = GetLinkForPoint(point);
870 ShellExecute(nullptr, _T("open"), url, nullptr, nullptr, SW_HIDE);
873 __super::OnLButtonUp(nFlags, point);
876 void CMessageBox::OnButton1()
878 if (GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->SendMessage(BM_GETCHECK, 0, 0)==BST_CHECKED)
880 m_bChecked = TRUE;
881 SetRegistryValue(m_sRegistryValue, m_uButton1Ret);
883 else
884 m_bChecked = FALSE;
885 EndDialog(m_uButton1Ret);
888 void CMessageBox::OnButton2()
890 if (GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->SendMessage(BM_GETCHECK, 0, 0)==BST_CHECKED)
892 m_bChecked = TRUE;
893 SetRegistryValue(m_sRegistryValue, m_uButton2Ret);
895 else
896 m_bChecked = FALSE;
897 if ((m_uButton2Ret == IDHELP)&&(!m_sHelpPath.IsEmpty()))
899 typedef HWND (WINAPI* FPHH)(HWND, LPCWSTR, UINT, DWORD);
900 FPHH pHtmlHelp = nullptr; // Function pointer
901 CAutoLibrary hInstHtmlHelp = AtlLoadSystemLibraryUsingFullPath(_T("HHCtrl.ocx"));
902 HWND hHelp = nullptr;
903 if (hInstHtmlHelp)
905 (FARPROC&)pHtmlHelp = GetProcAddress(hInstHtmlHelp, "HtmlHelpW");
906 if (pHtmlHelp)
907 hHelp = pHtmlHelp(m_hWnd, (LPCTSTR)m_sHelpPath, HH_DISPLAY_TOPIC, NULL);
909 if (!hHelp)
910 ::MessageBox(m_hWnd, _T("could not show help file"), _T("Help"), MB_ICONERROR);
912 else if (m_uButton2Ret == IDHELP)
913 OnHelp();
914 else
915 EndDialog(m_uButton2Ret);
918 void CMessageBox::OnButton3()
920 if (GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->SendMessage(BM_GETCHECK, 0, 0)==BST_CHECKED)
922 m_bChecked = TRUE;
923 SetRegistryValue(m_sRegistryValue, m_uButton3Ret);
925 else
926 m_bChecked = FALSE;
927 if ((m_uButton3Ret == IDHELP)&&(!m_sHelpPath.IsEmpty()))
929 typedef HWND (WINAPI* FPHH)(HWND, LPCWSTR, UINT, DWORD);
930 FPHH pHtmlHelp = nullptr; // Function pointer
931 CAutoLibrary hInstHtmlHelp = AtlLoadSystemLibraryUsingFullPath(_T("HHCtrl.ocx"));
932 HWND hHelp = nullptr;
933 if (hInstHtmlHelp)
935 (FARPROC&)pHtmlHelp = GetProcAddress(hInstHtmlHelp, "HtmlHelpW");
936 if (pHtmlHelp)
937 hHelp = pHtmlHelp(m_hWnd, (LPCTSTR)m_sHelpPath, HH_DISPLAY_TOPIC, NULL);
939 if (!hHelp)
940 ::MessageBox(m_hWnd, _T("could not show help file"), _T("Help"), MB_ICONERROR);
942 else if (m_uButton3Ret == IDHELP)
943 OnHelp();
944 else
945 EndDialog(m_uButton3Ret);
948 void CMessageBox::OnCancel()
950 if (m_uCancelRet == IDCANCEL)
951 EndDialog(m_uCancelRet);
952 //__super::OnCancel();
955 BOOL CMessageBox::OnInitDialog()
957 __super::OnInitDialog();
959 CRect rect(0, 0, 0, 0);
961 //determine the required size of the message box
962 m_szText = GetTextSize(m_sMessage);
963 CSize szIcon = GetIconSize(m_hIcon);
964 CSize szButtons = GetButtonSize();
966 CSize szIconText;
967 szIconText.cx = m_szText.cx + szIcon.cx + ((szIcon.cx == 0) ? MESSAGEBOX_ICONMARGIN : (2 * MESSAGEBOX_ICONMARGIN));
968 szIconText.cy = max(szIcon.cy, m_szText.cy);
970 rect.right = max(szButtons.cx, szIconText.cx);
971 rect.right += 2*GetSystemMetrics(SM_CXBORDER);
972 rect.right += 2*MESSAGEBOX_BORDERMARGINX;
973 rect.bottom = szIconText.cy;
974 rect.bottom += szButtons.cy;
975 rect.bottom += 2*MESSAGEBOX_BORDERMARGINY + MESSAGEBOX_TEXTBUTTONMARGIN;
976 rect.bottom += GetSystemMetrics(SM_CYCAPTION);
977 rect.bottom += 2 * GetSystemMetrics(SM_CYFIXEDFRAME);
978 rect.bottom += 2*GetSystemMetrics(SM_CYBORDER);
980 MoveWindow(rect);
981 CenterWindow();
983 GetClientRect(rect);
985 //now size and position the buttons as we need them
986 ASSERT(!m_sButton1.IsEmpty()); //at least the first button must be there!
987 if (m_sButton2.IsEmpty())
989 //only one button
990 CRect rt;
991 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->GetWindowRect(rt);
992 ScreenToClient(rt);
993 rt.MoveToX(rect.left + ((rect.Width() - m_szButtons.cx)/2));
994 rt.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
995 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->MoveWindow(rt);
996 //hide the other two buttons
997 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->ShowWindow(SW_HIDE);
998 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->ShowWindow(SW_HIDE);
1000 else if (m_sButton3.IsEmpty())
1002 //two buttons
1003 CRect rt1;
1004 CRect rt2;
1005 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->GetWindowRect(rt1);
1006 ScreenToClient(rt1);
1007 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->GetWindowRect(rt2);
1008 ScreenToClient(rt2);
1009 rt1.MoveToX(rect.left + ((rect.Width() - m_szButtons.cx)/2));
1010 rt1.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
1011 rt2.MoveToX(rt1.right + MESSAGEBOX_BUTTONMARGIN);
1012 rt2.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
1013 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->MoveWindow(rt1);
1014 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->MoveWindow(rt2);
1015 //hide the third button
1016 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->ShowWindow(SW_HIDE);
1018 else
1020 //three buttons
1021 CRect buttonrect;
1022 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->GetWindowRect(buttonrect);
1023 CRect rt1;
1024 CRect rt2;
1025 CRect rt3;
1026 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->GetWindowRect(rt1);
1027 ScreenToClient(rt1);
1028 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->GetWindowRect(rt2);
1029 ScreenToClient(rt2);
1030 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->GetWindowRect(rt3);
1031 ScreenToClient(rt3);
1032 rt1.MoveToX(rect.left + ((rect.Width() - m_szButtons.cx)/2));
1033 rt1.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
1034 rt2.MoveToX(rt1.right + MESSAGEBOX_BUTTONMARGIN);
1035 rt2.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
1036 rt3.MoveToX(rt2.right + MESSAGEBOX_BUTTONMARGIN);
1037 rt3.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
1038 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->MoveWindow(rt1);
1039 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->MoveWindow(rt2);
1040 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->MoveWindow(rt3);
1042 if (m_bShowCheck)
1044 CRect rt;
1045 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->GetWindowRect(rt);
1046 ScreenToClient(rt);
1047 rt.MoveToX(rect.left + MESSAGEBOX_BORDERMARGINX/*+ ((rect.Width() - szButtons.cx)/2)*/);
1048 rt.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - szButtons.cy);
1049 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->MoveWindow(rt);
1050 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->ShowWindow(SW_SHOW);
1052 else
1053 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->ShowWindow(SW_HIDE);
1055 SetWindowPos(&CWnd::wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
1056 SetForegroundWindow();
1057 SetFocus(); //Just playing safe
1059 if (m_nDefButton == 1)
1060 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->SetFocus();
1061 if (m_nDefButton == 2)
1062 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->SetFocus();
1063 if (m_nDefButton == 3)
1064 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->SetFocus();
1066 return FALSE; // return TRUE unless you set the focus to a control
1067 // EXCEPTION: OCX Property Pages should return FALSE
1070 BOOL CMessageBox::PreTranslateMessage(MSG* pMsg)
1072 if (pMsg->message == WM_KEYDOWN)
1074 switch (pMsg->wParam)
1076 case 'C':
1077 case VK_INSERT:
1079 if (GetAsyncKeyState(VK_CONTROL)&0x8000)
1081 CClipboardHelper clipboardHelper;
1082 if(clipboardHelper.Open(GetSafeHwnd()))
1084 EmptyClipboard();
1085 CStringA sClipboard = CStringA(m_sMessage);
1086 HGLOBAL hClipboardData = CClipboardHelper::GlobalAlloc(sClipboard.GetLength()+1);
1087 char * pchData = (char*)GlobalLock(hClipboardData);
1088 if (pchData)
1089 strcpy_s(pchData, sClipboard.GetLength()+1, (LPCSTR)sClipboard);
1090 GlobalUnlock(hClipboardData);
1091 SetClipboardData(CF_TEXT,hClipboardData);
1093 return TRUE;
1096 break;
1097 case VK_ESCAPE:
1099 switch (m_uType & 0xf)
1101 case MB_ABORTRETRYIGNORE:
1102 EndDialog(m_uButton1Ret);
1103 break;
1104 case MB_CANCELTRYCONTINUE:
1105 EndDialog(m_uButton1Ret);
1106 break;
1107 case MB_OKCANCEL:
1108 EndDialog(m_uButton2Ret);
1109 break;
1110 case MB_RETRYCANCEL:
1111 EndDialog(m_uButton2Ret);
1112 break;
1113 case MB_YESNO:
1114 EndDialog(m_uButton2Ret);
1115 break;
1116 case MB_YESNOCANCEL:
1117 EndDialog(m_uButton3Ret);
1118 break;
1121 break;
1125 return __super::PreTranslateMessage(pMsg);