1 // TortoiseSVN - a Windows shell extension for easy version control
\r
3 // Copyright (C) 2003-2008 - TortoiseSVN
\r
5 // This program is free software; you can redistribute it and/or
\r
6 // modify it under the terms of the GNU General Public License
\r
7 // as published by the Free Software Foundation; either version 2
\r
8 // of the License, or (at your option) any later version.
\r
10 // This program is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with this program; if not, write to the Free Software Foundation,
\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
20 //#include "resource.h" //if you defined some IDS_MSGBOX_xxxx this include is needed!
\r
21 #include "messagebox.h"
\r
22 #include ".\messagebox.h"
\r
25 CMessageBox::CMessageBox(void)
\r
32 m_bShowCheck = FALSE;
\r
33 m_bDestroyIcon = FALSE;
\r
36 CMessageBox::~CMessageBox(void)
\r
39 ::DestroyIcon(m_hIcon);
\r
42 UINT CMessageBox::ShowCheck(HWND hWnd, UINT nMessage, UINT nCaption, int nDef, LPCTSTR icon, UINT nButton1, UINT nButton2, UINT nButton3, LPCTSTR lpRegistry, UINT nCheckMessage/* = NULL*/)
\r
50 sButton1.LoadString(nButton1);
\r
51 sButton2.LoadString(nButton2);
\r
52 sButton3.LoadString(nButton3);
\r
53 sMessage.LoadString(nMessage);
\r
54 sCaption.LoadString(nCaption);
\r
55 nCheckMsg.LoadString(nCheckMessage);
\r
56 return CMessageBox::ShowCheck(hWnd, sMessage, sCaption, nDef, icon, sButton1, sButton2, sButton3, lpRegistry, nCheckMsg);
\r
59 UINT CMessageBox::ShowCheck(HWND hWnd, LPCTSTR lpMessage, LPCTSTR lpCaption, int nDef, LPCTSTR icon, LPCTSTR lpButton1, LPCTSTR lpButton2, LPCTSTR lpButton3, LPCTSTR lpRegistry, LPCTSTR lpCheckMessage/* = NULL*/)
\r
61 //check the registry if we have to show the box or just return with the last used return value
\r
62 //this would be the case if the user pressed "do not show again".
\r
66 #ifdef XMESSAGEBOX_APPREGPATH
\r
67 path = XMESSAGEBOX_APPREGPATH;
\r
69 path = "Software\\";
\r
70 path += AfxGetAppName();
\r
72 if (RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_EXECUTE, &hKey)==ERROR_SUCCESS)
\r
74 int size = sizeof(dwRetVal);
\r
76 if (RegQueryValueEx(hKey, lpRegistry, NULL, &type, (BYTE*) &dwRetVal,(LPDWORD) &size)==ERROR_SUCCESS)
\r
78 ASSERT(type==REG_DWORD);
\r
80 return (UINT)dwRetVal; //return with the last saved value
\r
89 box.m_bShowCheck = TRUE;
\r
90 box.m_sRegistryValue = lpRegistry;
\r
91 if (lpCheckMessage == NULL)
\r
93 #ifndef IDS_MSGBOX_DONOTSHOWAGAIN
\r
94 box.m_sCheckbox = _T("do not show again");
\r
97 m_i18l.LoadString(IDS_MSGBOX_DONOTSHOWAGAIN);
\r
98 box.m_sCheckbox = m_i18l;
\r
102 box.m_sCheckbox = lpCheckMessage;
\r
103 box.m_sButton1 = lpButton1;
\r
104 box.m_sButton2 = lpButton2;
\r
105 box.m_sButton3 = lpButton3;
\r
106 box.m_hIcon = (HICON)::LoadImage(AfxGetResourceHandle(), icon, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
\r
107 if (box.m_hIcon == NULL)
\r
108 box.m_hIcon = (HICON)::LoadImage(NULL, icon, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
\r
110 box.m_bDestroyIcon = TRUE;
\r
111 if (!IsWindow(hWnd))
\r
113 return box.GoModal(CWnd::FromHandle(hWnd), lpCaption, lpMessage, nDef);
\r
116 UINT CMessageBox::Show(HWND hWnd, LPCTSTR lpMessage, LPCTSTR lpCaption, int nDef, LPCTSTR icon, LPCTSTR lpButton1, LPCTSTR lpButton2/* = NULL*/, LPCTSTR lpButton3/* = NULL*/)
\r
119 box.m_sButton1 = lpButton1;
\r
120 box.m_sButton2 = lpButton2;
\r
121 box.m_sButton3 = lpButton3;
\r
122 box.m_hIcon = (HICON)::LoadImage(AfxGetResourceHandle(), icon, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
\r
123 if (box.m_hIcon == NULL)
\r
124 box.m_hIcon = (HICON)::LoadImage(NULL, icon, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
\r
126 box.m_bDestroyIcon = TRUE;
\r
127 if (!IsWindow(hWnd))
\r
129 return box.GoModal(CWnd::FromHandle(hWnd), lpCaption, lpMessage, nDef);
\r
132 UINT CMessageBox::Show(HWND hWnd, UINT nMessage, UINT nCaption, int nDef, LPCTSTR icon, UINT nButton1, UINT nButton2, UINT nButton3)
\r
139 sButton1.LoadString(nButton1);
\r
140 sButton2.LoadString(nButton2);
\r
141 sButton3.LoadString(nButton3);
\r
142 sMessage.LoadString(nMessage);
\r
143 sCaption.LoadString(nCaption);
\r
144 return CMessageBox::Show(hWnd, sMessage, sCaption, nDef, icon, sButton1, sButton2, sButton3);
\r
148 UINT CMessageBox::ShowCheck(HWND hWnd, UINT nMessage, UINT nCaption, UINT uType, LPCTSTR lpRegistry, UINT nCheckMessage)
\r
153 sMessage.LoadString(nMessage);
\r
154 sCaption.LoadString(nCaption);
\r
155 sCheckMsg.LoadString(nCheckMessage);
\r
156 return CMessageBox::ShowCheck(hWnd, sMessage, sCaption, uType, lpRegistry, sCheckMsg);
\r
159 UINT CMessageBox::ShowCheck(HWND hWnd, LPCTSTR lpMessage, LPCTSTR lpCaption, UINT uType, LPCTSTR lpRegistry, LPCTSTR lpCheckMessage)
\r
161 //check the registry if we have to show the box or just return with the last used return value
\r
162 //this would be the case if the user pressed "do not show again".
\r
166 #ifdef XMESSAGEBOX_APPREGPATH
\r
167 path = XMESSAGEBOX_APPREGPATH;
\r
169 path = "Software\\";
\r
170 path += AfxGetAppName();
\r
172 if (RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_EXECUTE, &hKey)==ERROR_SUCCESS)
\r
174 int size = sizeof(dwRetVal);
\r
176 if (RegQueryValueEx(hKey, lpRegistry, NULL, &type, (BYTE*) &dwRetVal,(LPDWORD) &size)==ERROR_SUCCESS)
\r
178 ASSERT(type==REG_DWORD);
\r
180 return (UINT)dwRetVal; //return with the last saved value
\r
189 box.m_bShowCheck = TRUE;
\r
190 box.m_sRegistryValue = lpRegistry;
\r
191 if (lpCheckMessage == NULL)
\r
193 #ifndef IDS_MSGBOX_DONOTSHOWAGAIN
\r
194 box.m_sCheckbox = _T("do not show again");
\r
197 m_i18l.LoadString(IDS_MSGBOX_DONOTSHOWAGAIN);
\r
198 box.m_sCheckbox = m_i18l;
\r
202 box.m_sCheckbox = lpCheckMessage;
\r
203 if (!IsWindow(hWnd))
\r
205 return box.GoModal(CWnd::FromHandle(hWnd), lpCaption, lpMessage, box.FillBoxStandard(uType));
\r
208 UINT CMessageBox::Show(HWND hWnd, UINT nMessage, UINT nCaption, UINT uType, LPCTSTR sHelpPath)
\r
212 sMessage.LoadString(nMessage);
\r
213 sCaption.LoadString(nCaption);
\r
214 return CMessageBox::Show(hWnd, sMessage, sCaption, uType, sHelpPath);
\r
217 UINT CMessageBox::Show(HWND hWnd, LPCTSTR lpMessage, LPCTSTR lpCaption, UINT uType, LPCTSTR sHelpPath)
\r
221 if (!IsWindow(hWnd))
\r
224 box.SetHelpPath(sHelpPath);
\r
225 return box.GoModal(CWnd::FromHandle(hWnd), lpCaption, lpMessage, box.FillBoxStandard(uType));
\r
228 UINT CMessageBox::Show(HWND hWnd, UINT nMessage, UINT nCaption, UINT uType, UINT nHelpID)
\r
233 sMessage.LoadString(nMessage);
\r
234 sCaption.LoadString(nCaption);
\r
236 if (!IsWindow(hWnd))
\r
238 box.SetHelpID(nHelpID);
\r
240 return box.GoModal(CWnd::FromHandle(hWnd), sCaption, sMessage, box.FillBoxStandard(uType));
\r
243 int CMessageBox::FillBoxStandard(UINT uType)
\r
247 m_uCancelRet = IDCANCEL;
\r
248 //load the icons according to uType
\r
249 switch (uType & 0xf0)
\r
251 case MB_ICONEXCLAMATION:
\r
252 m_hIcon = (HICON)::LoadImage(NULL, IDI_EXCLAMATION, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
\r
253 ::MessageBeep(MB_ICONEXCLAMATION);
\r
255 case MB_ICONASTERISK:
\r
256 m_hIcon = (HICON)::LoadImage(NULL, IDI_ASTERISK, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
\r
257 ::MessageBeep(MB_ICONASTERISK);
\r
259 case MB_ICONQUESTION:
\r
260 m_hIcon = (HICON)::LoadImage(NULL, IDI_QUESTION, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
\r
261 ::MessageBeep(MB_ICONQUESTION);
\r
264 m_hIcon = (HICON)::LoadImage(NULL, IDI_HAND, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
\r
265 ::MessageBeep(MB_ICONHAND);
\r
268 //set up the button texts
\r
269 switch (uType & 0xf)
\r
271 case MB_ABORTRETRYIGNORE:
\r
272 #ifndef IDS_MSGBOX_ABORT
\r
273 m_sButton1 = "Abort";
\r
275 m_i18l.LoadString(IDS_MSGBOX_ABORT);
\r
276 m_sButton1 = m_i18l;
\r
278 m_uButton1Ret = IDABORT;
\r
279 #ifndef IDS_MSGBOX_RETRY
\r
280 m_sButton2 = "Retry";
\r
282 m_i18l.LoadString(IDS_MSGBOX_RETRY);
\r
283 m_sButton2 = m_i18l;
\r
285 m_uButton2Ret = IDRETRY;
\r
286 #ifndef IDS_MSGBOX_IGNORE
\r
287 m_sButton3 = "Ignore";
\r
289 m_i18l.LoadString(IDS_MSGBOX_IGNORE);
\r
290 m_sButton3 = m_i18l;
\r
292 m_uButton3Ret = IDIGNORE;
\r
294 case MB_CANCELTRYCONTINUE:
\r
295 #ifndef IDS_MSGBOX_CANCEL
\r
296 m_sButton1 = "Cancel";
\r
298 m_i18l.LoadString(IDS_MSGBOX_CANCEL);
\r
299 m_sButton1 = m_i18l;
\r
301 m_uButton1Ret = IDCANCEL;
\r
302 #ifndef IDS_MSGBOX_TRYAGAIN
\r
303 m_sButton2 = "Try Again";
\r
305 m_i18l.LoadString(IDS_MSGBOX_TRYAGAIN);
\r
306 m_sButton2 = m_i18l;
\r
308 m_uButton2Ret = IDTRYAGAIN;
\r
309 #ifndef IDS_MSGBOX_CONTINUE
\r
310 m_sButton3 = "Continue";
\r
312 m_i18l.LoadString(IDS_MSGBOX_CONTINUE);
\r
313 m_sButton3 = m_i18l;
\r
315 m_uButton3Ret = IDCONTINUE;
\r
318 #ifndef IDS_MSGBOX_OK
\r
321 m_i18l.LoadString(IDS_MSGBOX_OK);
\r
322 m_sButton1 = m_i18l;
\r
324 m_uButton1Ret = IDOK;
\r
325 #ifndef IDS_MSGBOX_CANCEL
\r
326 m_sButton2 = "Cancel";
\r
328 m_i18l.LoadString(IDS_MSGBOX_CANCEL);
\r
329 m_sButton2 = m_i18l;
\r
331 m_uButton2Ret = IDCANCEL;
\r
333 case MB_RETRYCANCEL:
\r
334 #ifndef IDS_MSGBOX_RETRY
\r
335 m_sButton1 = "Retry";
\r
337 m_i18l.LoadString(IDS_MSGBOX_RETRY);
\r
338 m_sButton1 = m_i18l;
\r
340 m_uButton1Ret = IDRETRY;
\r
341 #ifndef IDS_MSGBOX_CANCEL
\r
342 m_sButton2 = "Cancel";
\r
344 m_i18l.LoadString(IDS_MSGBOX_CANCEL);
\r
345 m_sButton2 = m_i18l;
\r
347 m_uButton2Ret = IDCANCEL;
\r
350 #ifndef IDS_MSGBOX_YES
\r
351 m_sButton1 = "Yes";
\r
353 m_i18l.LoadString(IDS_MSGBOX_YES);
\r
354 m_sButton1 = m_i18l;
\r
356 m_uButton1Ret = IDYES;
\r
357 #ifndef IDS_MSGBOX_NO
\r
360 m_i18l.LoadString(IDS_MSGBOX_NO);
\r
361 m_sButton2 = m_i18l;
\r
363 m_uButton2Ret = IDNO;
\r
365 case MB_YESNOCANCEL:
\r
366 #ifndef IDS_MSGBOX_YES
\r
367 m_sButton1 = "Yes";
\r
369 m_i18l.LoadString(IDS_MSGBOX_YES);
\r
370 m_sButton1 = m_i18l;
\r
372 m_uButton1Ret = IDYES;
\r
373 #ifndef IDS_MSGBOX_NO
\r
376 m_i18l.LoadString(IDS_MSGBOX_NO);
\r
377 m_sButton2 = m_i18l;
\r
379 m_uButton2Ret = IDNO;
\r
380 #ifndef IDS_MSGBOX_CANCEL
\r
381 m_sButton3 = "Cancel";
\r
383 m_i18l.LoadString(IDS_MSGBOX_CANCEL);
\r
384 m_sButton3 = m_i18l;
\r
386 m_uButton3Ret = IDCANCEL;
\r
390 #ifndef IDS_MSGBOX_OK
\r
393 m_i18l.LoadString(IDS_MSGBOX_OK);
\r
394 m_sButton1 = m_i18l;
\r
397 //now set the default button
\r
398 switch (uType & 0xf00)
\r
400 case MB_DEFBUTTON2:
\r
403 case MB_DEFBUTTON3:
\r
407 // do we need to add a help button?
\r
408 if (uType & MB_HELP)
\r
411 #ifndef IDS_MSGBOX_HELP
\r
412 sHelpText = _T("Help");
\r
414 m_i18l.LoadString(IDS_MSGBOX_HELP);
\r
415 sHelpText = m_i18l;
\r
417 if (m_sButton2.IsEmpty())
\r
419 m_sButton2 = sHelpText;
\r
420 m_uButton2Ret = IDHELP;
\r
422 else if (m_sButton3.IsEmpty())
\r
424 m_sButton3 = sHelpText;
\r
425 m_uButton3Ret = IDHELP;
\r
431 UINT CMessageBox::GoModal(CWnd * pWnd, const CString& title, const CString& msg, int nDefaultButton)
\r
433 NONCLIENTMETRICS ncm;
\r
434 memset(&ncm,0,sizeof(NONCLIENTMETRICS));
\r
435 ncm.cbSize = sizeof(NONCLIENTMETRICS);
\r
436 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);
\r
437 DWORD nErrorNo = GetLastError ( ); // µÃµ½´íÎó´úÂë
\r
439 FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER |
\r
440 FORMAT_MESSAGE_IGNORE_INSERTS |
\r
441 FORMAT_MESSAGE_FROM_SYSTEM,
\r
443 nErrorNo, // ´ËÄË´íÎó´úÂ룬ͨ³£ÔÚ³ÌÐòÖпÉÓÉ GetLastError()µÃÖ®
\r
445 (LPTSTR) & lpBuffer,
\r
448 memcpy(&m_LogFont, &(ncm.lfMessageFont), sizeof(LOGFONT));
\r
450 //the problem with the LOGFONT lfHeight is that it is not in pixels,
\r
451 //but the dialog template needs the height in pixels.
\r
452 //We need to convert those values first:
\r
455 pDC = pWnd->GetDC();
\r
457 pDC = GetDesktopWindow()->GetDC();
\r
458 int pix = -MulDiv(m_LogFont.lfHeight, 72, GetDeviceCaps(pDC->m_hDC, LOGPIXELSY));
\r
459 CDlgTemplate dialogTemplate = CDlgTemplate(title, WS_CAPTION | DS_CENTER,
\r
460 0, 0, 0, 0, m_LogFont.lfFaceName, pix);
\r
461 dialogTemplate.AddButton(_T("Button1"), WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | ((nDefaultButton == 1) ? BS_DEFPUSHBUTTON : 0), 0,
\r
462 2 + 3, 62, 56, 13, IDC_MESSAGEBOX_BUTTON1);
\r
463 dialogTemplate.AddButton(_T("Button2"), WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | ((nDefaultButton == 2) ? BS_DEFPUSHBUTTON : 0), 0,
\r
464 2 + 3, 62, 56, 13, IDC_MESSAGEBOX_BUTTON2);
\r
465 dialogTemplate.AddButton(_T("Button3"), WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | ((nDefaultButton == 3) ? BS_DEFPUSHBUTTON : 0), 0,
\r
466 2 + 3, 62, 56, 13, IDC_MESSAGEBOX_BUTTON3);
\r
467 dialogTemplate.AddButton(_T("Checkbox"), WS_CHILD | WS_TABSTOP | BS_AUTOCHECKBOX, 0,
\r
468 0, 0, 0, 0, IDC_MESSAGEBOX_CHECKBOX);
\r
470 m_nDefButton = nDefaultButton;
\r
472 InitModalIndirect(dialogTemplate, pWnd);
\r
474 return (UINT)DoModal();
\r
477 void CMessageBox::SetRegistryValue(const CString& sValue, DWORD value)
\r
480 #ifdef XMESSAGEBOX_APPREGPATH
\r
481 path = XMESSAGEBOX_APPREGPATH;
\r
483 path = "Software\\";
\r
484 path += AfxGetAppName();
\r
488 if (RegCreateKeyEx(HKEY_CURRENT_USER, path, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &disp)!=ERROR_SUCCESS)
\r
492 RegSetValueEx(hKey, sValue, 0, REG_DWORD,(const BYTE*) &value, sizeof(value));
\r
496 CSize CMessageBox::GetTextSize(const CString& str)
\r
499 GetWindowRect(&rect);
\r
501 CDC * pDC = GetDC();
\r
505 memDC.CreateCompatibleDC(pDC);
\r
506 bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
\r
507 CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
\r
509 //get the minimum size of the rectangle of the tooltip
\r
510 CSize sz = DrawHTML(&memDC, rect, str, m_LogFont, TRUE);
\r
512 memDC.SelectObject(pOldBitmap);
\r
514 bitmap.DeleteObject();
\r
521 CSize CMessageBox::GetIconSize(HICON hIcon)
\r
528 //get icon dimensions
\r
529 ::SecureZeroMemory(&ii, sizeof(ICONINFO));
\r
530 if (::GetIconInfo(hIcon, &ii))
\r
532 sz.cx = (DWORD)(ii.xHotspot * 2);
\r
533 sz.cy = (DWORD)(ii.yHotspot * 2);
\r
534 //release icon mask bitmaps
\r
536 ::DeleteObject(ii.hbmMask);
\r
538 ::DeleteObject(ii.hbmColor);
\r
545 CSize CMessageBox::GetButtonSize()
\r
548 int nButtons = 0; //number of buttons - 1
\r
550 SetDlgItemText(IDC_MESSAGEBOX_BUTTON1, m_sButton1);
\r
551 SetDlgItemText(IDC_MESSAGEBOX_BUTTON2, m_sButton2);
\r
552 //GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->SendMessage(BM_SETSTYLE, BS_DEFPUSHBUTTON, 1);
\r
553 SetDlgItemText(IDC_MESSAGEBOX_BUTTON3, m_sButton3);
\r
554 SetDlgItemText(IDC_MESSAGEBOX_CHECKBOX, m_sCheckbox);
\r
556 CSize sz1 = GetTextSize(m_sButton1);
\r
557 CSize sz2 = GetTextSize(m_sButton2);
\r
558 CSize sz3 = GetTextSize(m_sButton3);
\r
560 sz1.cx += 2*MESSAGEBOX_BUTTONX;
\r
561 sz1.cy += 2*MESSAGEBOX_BUTTONY;
\r
565 sz2.cx += 2*MESSAGEBOX_BUTTONX;
\r
566 sz2.cy += 2*MESSAGEBOX_BUTTONY;
\r
571 sz3.cx += 2*MESSAGEBOX_BUTTONX;
\r
572 sz3.cy += 2*MESSAGEBOX_BUTTONY;
\r
576 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->MoveWindow(0, 0, sz1.cx, sz1.cy);
\r
577 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->MoveWindow(0, 0, sz2.cx, sz2.cy);
\r
578 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->MoveWindow(0, 0, sz3.cx, sz3.cy);
\r
581 sz.cx = sz1.cx + sz2.cx + sz3.cx + (nButtons * MESSAGEBOX_BUTTONMARGIN);
\r
582 sz.cy = max(sz1.cy, sz2.cy);
\r
583 sz.cy = max(sz.cy, sz3.cy);
\r
587 CSize szCheck = GetTextSize(m_sCheckbox);
\r
588 szCheck.cx += 2*GetSystemMetrics(SM_CXMENUCHECK);
\r
589 szCheck.cy += 2*MESSAGEBOX_BUTTONY;
\r
590 sz.cx = max(sz.cx, szCheck.cx);
\r
591 sz.cy += szCheck.cy + MESSAGEBOX_BUTTONCHECKMARGIN;
\r
592 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->MoveWindow(0, 0, szCheck.cx, szCheck.cy);
\r
594 m_szAllButtons = sz;
\r
598 BEGIN_MESSAGE_MAP(CMessageBox, CDialog)
\r
602 ON_BN_CLICKED(IDC_MESSAGEBOX_BUTTON1, OnButton1)
\r
603 ON_BN_CLICKED(IDC_MESSAGEBOX_BUTTON2, OnButton2)
\r
604 ON_BN_CLICKED(IDC_MESSAGEBOX_BUTTON3, OnButton3)
\r
607 void CMessageBox::OnPaint()
\r
609 CPaintDC dc(this); // device context for painting
\r
614 GetClientRect(&rect);
\r
615 GetClientRect(&drawrect);
\r
617 //create a memory device-context. This is done to help reduce
\r
618 //screen flicker, since we will paint the entire control to the
\r
619 //off screen device context first.
\r
622 memDC.CreateCompatibleDC(&dc);
\r
623 bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
\r
624 CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
\r
626 memDC.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dc, 0,0, SRCCOPY);
\r
628 memDC.SetBkMode(TRANSPARENT);
\r
629 memDC.SetBkColor(GetSysColor(COLOR_WINDOW));
\r
630 memDC.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
\r
632 //OnDrawBackground();
\r
633 drawrect.DeflateRect(MESSAGEBOX_BORDERMARGINX, MESSAGEBOX_BORDERMARGINY);
\r
634 if (m_hIcon != NULL)
\r
636 DrawIconEx(memDC.m_hDC, drawrect.left, drawrect.top +
\r
637 ((drawrect.Height() - m_szAllButtons.cy - MESSAGEBOX_TEXTBUTTONMARGIN - m_szIcon.cy) / 2),
\r
638 m_hIcon, m_szIcon.cx, m_szIcon.cy, 0, NULL, DI_NORMAL);
\r
640 drawrect.left += m_szIcon.cx + MESSAGEBOX_ICONMARGIN;
\r
644 DrawHTML(&memDC, drawrect, m_sMessage, m_LogFont);
\r
647 //Copy the memory device context back into the original DC.
\r
648 dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, 0,0, SRCCOPY);
\r
650 //Cleanup resources.
\r
651 memDC.SelectObject(pOldBitmap);
\r
653 bitmap.DeleteObject();
\r
658 void CMessageBox::OnMouseMove(UINT nFlags, CPoint point)
\r
660 if (IsPointOverALink(point))
\r
662 m_Cursor.SetCursor(IDC_HAND);
\r
666 m_Cursor.Restore();
\r
669 __super::OnMouseMove(nFlags, point);
\r
672 void CMessageBox::OnLButtonUp(UINT nFlags, CPoint point)
\r
674 if (IsPointOverALink(point))
\r
676 CString url = GetLinkForPoint(point);
\r
677 ShellExecute(NULL, _T("open"), url, NULL,NULL, 0);
\r
680 __super::OnLButtonUp(nFlags, point);
\r
683 void CMessageBox::OnButton1()
\r
685 if (GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->SendMessage(BM_GETCHECK, 0, 0)==BST_CHECKED)
\r
686 SetRegistryValue(m_sRegistryValue, m_uButton1Ret);
\r
687 EndDialog(m_uButton1Ret);
\r
690 void CMessageBox::OnButton2()
\r
692 if (GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->SendMessage(BM_GETCHECK, 0, 0)==BST_CHECKED)
\r
693 SetRegistryValue(m_sRegistryValue, m_uButton2Ret);
\r
694 if ((m_uButton2Ret == IDHELP)&&(!m_sHelpPath.IsEmpty()))
\r
696 typedef HWND (WINAPI* FPHH)(HWND, LPCWSTR, UINT, DWORD);
\r
697 FPHH pHtmlHelp=NULL; // Function pointer
\r
698 HINSTANCE hInstHtmlHelp = LoadLibrary(_T("HHCtrl.ocx"));
\r
700 if (hInstHtmlHelp != NULL)
\r
702 (FARPROC&)pHtmlHelp = GetProcAddress(hInstHtmlHelp, "HtmlHelpW");
\r
704 hHelp = pHtmlHelp(m_hWnd, (LPCTSTR)m_sHelpPath, HH_DISPLAY_TOPIC, NULL);
\r
707 ::MessageBox(m_hWnd, _T("could not show help file"), _T("Help"), MB_ICONERROR);
\r
709 else if (m_uButton2Ret == IDHELP)
\r
714 EndDialog(m_uButton2Ret);
\r
717 void CMessageBox::OnButton3()
\r
719 if (GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->SendMessage(BM_GETCHECK, 0, 0)==BST_CHECKED)
\r
720 SetRegistryValue(m_sRegistryValue, m_uButton3Ret);
\r
721 if ((m_uButton3Ret == IDHELP)&&(!m_sHelpPath.IsEmpty()))
\r
723 typedef HWND (WINAPI* FPHH)(HWND, LPCWSTR, UINT, DWORD);
\r
724 FPHH pHtmlHelp=NULL; // Function pointer
\r
725 HINSTANCE hInstHtmlHelp = LoadLibrary(_T("HHCtrl.ocx"));
\r
727 if (hInstHtmlHelp != NULL)
\r
729 (FARPROC&)pHtmlHelp = GetProcAddress(hInstHtmlHelp, "HtmlHelpW");
\r
731 hHelp = pHtmlHelp(m_hWnd, (LPCTSTR)m_sHelpPath, HH_DISPLAY_TOPIC, NULL);
\r
734 ::MessageBox(m_hWnd, _T("could not show help file"), _T("Help"), MB_ICONERROR);
\r
736 else if (m_uButton3Ret == IDHELP)
\r
741 EndDialog(m_uButton3Ret);
\r
744 void CMessageBox::OnCancel()
\r
746 if (m_uCancelRet == IDCANCEL)
\r
747 EndDialog(m_uCancelRet);
\r
748 //__super::OnCancel();
\r
751 BOOL CMessageBox::OnInitDialog()
\r
753 __super::OnInitDialog();
\r
755 CRect rect(0, 0, 0, 0);
\r
757 //determine the required size of the message box
\r
758 CSize szText = GetTextSize(m_sMessage);
\r
759 CSize szIcon = GetIconSize(m_hIcon);
\r
760 CSize szButtons = GetButtonSize();
\r
763 szIconText.cx = szText.cx + szIcon.cx + ((szIcon.cx == 0) ? MESSAGEBOX_ICONMARGIN : (2*MESSAGEBOX_ICONMARGIN));
\r
764 szIconText.cy = max(szIcon.cy, szText.cy);
\r
766 rect.right = max(szButtons.cx, szIconText.cx);
\r
767 rect.right += 2*GetSystemMetrics(SM_CXBORDER);
\r
768 rect.right += 2*MESSAGEBOX_BORDERMARGINX;
\r
769 rect.bottom = szIconText.cy;
\r
770 rect.bottom += szButtons.cy;
\r
771 rect.bottom += 2*MESSAGEBOX_BORDERMARGINY + MESSAGEBOX_TEXTBUTTONMARGIN;
\r
772 rect.bottom += GetSystemMetrics(SM_CYCAPTION);
\r
773 rect.bottom += 2*GetSystemMetrics(SM_CYBORDER);
\r
778 GetClientRect(rect);
\r
780 //now size and position the buttons as we need them
\r
781 ASSERT(!m_sButton1.IsEmpty()); //at least the first button must be there!
\r
782 if (m_sButton2.IsEmpty())
\r
786 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->GetWindowRect(rt);
\r
787 ScreenToClient(rt);
\r
788 rt.MoveToX(rect.left + ((rect.Width() - m_szButtons.cx)/2));
\r
789 rt.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
\r
790 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->MoveWindow(rt);
\r
791 //hide the other two buttons
\r
792 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->ShowWindow(SW_HIDE);
\r
793 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->ShowWindow(SW_HIDE);
\r
795 else if (m_sButton3.IsEmpty())
\r
800 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->GetWindowRect(rt1);
\r
801 ScreenToClient(rt1);
\r
802 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->GetWindowRect(rt2);
\r
803 ScreenToClient(rt2);
\r
804 rt1.MoveToX(rect.left + ((rect.Width() - m_szButtons.cx)/2));
\r
805 rt1.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
\r
806 rt2.MoveToX(rt1.right + MESSAGEBOX_BUTTONMARGIN);
\r
807 rt2.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
\r
808 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->MoveWindow(rt1);
\r
809 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->MoveWindow(rt2);
\r
810 //hide the third button
\r
811 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->ShowWindow(SW_HIDE);
\r
817 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->GetWindowRect(buttonrect);
\r
821 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->GetWindowRect(rt1);
\r
822 ScreenToClient(rt1);
\r
823 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->GetWindowRect(rt2);
\r
824 ScreenToClient(rt2);
\r
825 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->GetWindowRect(rt3);
\r
826 ScreenToClient(rt3);
\r
827 rt1.MoveToX(rect.left + ((rect.Width() - m_szButtons.cx)/2));
\r
828 rt1.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
\r
829 rt2.MoveToX(rt1.right + MESSAGEBOX_BUTTONMARGIN);
\r
830 rt2.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
\r
831 rt3.MoveToX(rt2.right + MESSAGEBOX_BUTTONMARGIN);
\r
832 rt3.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
\r
833 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->MoveWindow(rt1);
\r
834 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->MoveWindow(rt2);
\r
835 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->MoveWindow(rt3);
\r
840 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->GetWindowRect(rt);
\r
841 ScreenToClient(rt);
\r
842 rt.MoveToX(rect.left + MESSAGEBOX_BORDERMARGINX/*+ ((rect.Width() - szButtons.cx)/2)*/);
\r
843 rt.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - szButtons.cy);
\r
844 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->MoveWindow(rt);
\r
845 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->ShowWindow(SW_SHOW);
\r
848 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->ShowWindow(SW_HIDE);
\r
850 if (m_nDefButton == 1)
\r
851 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->SetFocus();
\r
852 if (m_nDefButton == 2)
\r
853 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->SetFocus();
\r
854 if (m_nDefButton == 3)
\r
855 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->SetFocus();
\r
857 SetWindowPos(&CWnd::wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
\r
858 SetForegroundWindow();
\r
859 SetFocus(); //Just playing safe
\r
861 return FALSE; // return TRUE unless you set the focus to a control
\r
862 // EXCEPTION: OCX Property Pages should return FALSE
\r
865 BOOL CMessageBox::PreTranslateMessage(MSG* pMsg)
\r
867 if (pMsg->message == WM_KEYDOWN)
\r
869 switch (pMsg->wParam)
\r
874 if (GetAsyncKeyState(VK_CONTROL)&0x8000)
\r
876 CStringA sClipboard = CStringA(m_sMessage);
\r
877 if (OpenClipboard())
\r
880 HGLOBAL hClipboardData;
\r
881 hClipboardData = GlobalAlloc(GMEM_DDESHARE, sClipboard.GetLength()+1);
\r
883 pchData = (char*)GlobalLock(hClipboardData);
\r
884 strcpy_s(pchData, sClipboard.GetLength()+1, (LPCSTR)sClipboard);
\r
885 GlobalUnlock(hClipboardData);
\r
886 SetClipboardData(CF_TEXT,hClipboardData);
\r
895 switch (m_uType & 0xf)
\r
897 case MB_ABORTRETRYIGNORE:
\r
898 EndDialog(m_uButton1Ret);
\r
900 case MB_CANCELTRYCONTINUE:
\r
901 EndDialog(m_uButton1Ret);
\r
904 EndDialog(m_uButton2Ret);
\r
906 case MB_RETRYCANCEL:
\r
907 EndDialog(m_uButton2Ret);
\r
910 EndDialog(m_uButton2Ret);
\r
912 case MB_YESNOCANCEL:
\r
913 EndDialog(m_uButton3Ret);
\r
921 return __super::PreTranslateMessage(pMsg);
\r