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
438 memcpy(&m_LogFont, &(ncm.lfMessageFont), sizeof(LOGFONT));
\r
440 //the problem with the LOGFONT lfHeight is that it is not in pixels,
\r
441 //but the dialog template needs the height in pixels.
\r
442 //We need to convert those values first:
\r
445 pDC = pWnd->GetDC();
\r
447 pDC = GetDesktopWindow()->GetDC();
\r
448 int pix = -MulDiv(m_LogFont.lfHeight, 72, GetDeviceCaps(pDC->m_hDC, LOGPIXELSY));
\r
449 CDlgTemplate dialogTemplate = CDlgTemplate(title, WS_CAPTION | DS_CENTER,
\r
450 0, 0, 0, 0, m_LogFont.lfFaceName, pix);
\r
451 dialogTemplate.AddButton(_T("Button1"), WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | ((nDefaultButton == 1) ? BS_DEFPUSHBUTTON : 0), 0,
\r
452 2 + 3, 62, 56, 13, IDC_MESSAGEBOX_BUTTON1);
\r
453 dialogTemplate.AddButton(_T("Button2"), WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | ((nDefaultButton == 2) ? BS_DEFPUSHBUTTON : 0), 0,
\r
454 2 + 3, 62, 56, 13, IDC_MESSAGEBOX_BUTTON2);
\r
455 dialogTemplate.AddButton(_T("Button3"), WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | ((nDefaultButton == 3) ? BS_DEFPUSHBUTTON : 0), 0,
\r
456 2 + 3, 62, 56, 13, IDC_MESSAGEBOX_BUTTON3);
\r
457 dialogTemplate.AddButton(_T("Checkbox"), WS_CHILD | WS_TABSTOP | BS_AUTOCHECKBOX, 0,
\r
458 0, 0, 0, 0, IDC_MESSAGEBOX_CHECKBOX);
\r
460 m_nDefButton = nDefaultButton;
\r
462 InitModalIndirect(dialogTemplate, pWnd);
\r
464 return (UINT)DoModal();
\r
467 void CMessageBox::SetRegistryValue(const CString& sValue, DWORD value)
\r
470 #ifdef XMESSAGEBOX_APPREGPATH
\r
471 path = XMESSAGEBOX_APPREGPATH;
\r
473 path = "Software\\";
\r
474 path += AfxGetAppName();
\r
478 if (RegCreateKeyEx(HKEY_CURRENT_USER, path, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &disp)!=ERROR_SUCCESS)
\r
482 RegSetValueEx(hKey, sValue, 0, REG_DWORD,(const BYTE*) &value, sizeof(value));
\r
486 CSize CMessageBox::GetTextSize(const CString& str)
\r
489 GetWindowRect(&rect);
\r
491 CDC * pDC = GetDC();
\r
495 memDC.CreateCompatibleDC(pDC);
\r
496 bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
\r
497 CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
\r
499 //get the minimum size of the rectangle of the tooltip
\r
500 CSize sz = DrawHTML(&memDC, rect, str, m_LogFont, TRUE);
\r
502 memDC.SelectObject(pOldBitmap);
\r
504 bitmap.DeleteObject();
\r
511 CSize CMessageBox::GetIconSize(HICON hIcon)
\r
518 //get icon dimensions
\r
519 ::SecureZeroMemory(&ii, sizeof(ICONINFO));
\r
520 if (::GetIconInfo(hIcon, &ii))
\r
522 sz.cx = (DWORD)(ii.xHotspot * 2);
\r
523 sz.cy = (DWORD)(ii.yHotspot * 2);
\r
524 //release icon mask bitmaps
\r
526 ::DeleteObject(ii.hbmMask);
\r
528 ::DeleteObject(ii.hbmColor);
\r
535 CSize CMessageBox::GetButtonSize()
\r
538 int nButtons = 0; //number of buttons - 1
\r
540 SetDlgItemText(IDC_MESSAGEBOX_BUTTON1, m_sButton1);
\r
541 SetDlgItemText(IDC_MESSAGEBOX_BUTTON2, m_sButton2);
\r
542 //GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->SendMessage(BM_SETSTYLE, BS_DEFPUSHBUTTON, 1);
\r
543 SetDlgItemText(IDC_MESSAGEBOX_BUTTON3, m_sButton3);
\r
544 SetDlgItemText(IDC_MESSAGEBOX_CHECKBOX, m_sCheckbox);
\r
546 CSize sz1 = GetTextSize(m_sButton1);
\r
547 CSize sz2 = GetTextSize(m_sButton2);
\r
548 CSize sz3 = GetTextSize(m_sButton3);
\r
550 sz1.cx += 2*MESSAGEBOX_BUTTONX;
\r
551 sz1.cy += 2*MESSAGEBOX_BUTTONY;
\r
555 sz2.cx += 2*MESSAGEBOX_BUTTONX;
\r
556 sz2.cy += 2*MESSAGEBOX_BUTTONY;
\r
561 sz3.cx += 2*MESSAGEBOX_BUTTONX;
\r
562 sz3.cy += 2*MESSAGEBOX_BUTTONY;
\r
566 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->MoveWindow(0, 0, sz1.cx, sz1.cy);
\r
567 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->MoveWindow(0, 0, sz2.cx, sz2.cy);
\r
568 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->MoveWindow(0, 0, sz3.cx, sz3.cy);
\r
571 sz.cx = sz1.cx + sz2.cx + sz3.cx + (nButtons * MESSAGEBOX_BUTTONMARGIN);
\r
572 sz.cy = max(sz1.cy, sz2.cy);
\r
573 sz.cy = max(sz.cy, sz3.cy);
\r
577 CSize szCheck = GetTextSize(m_sCheckbox);
\r
578 szCheck.cx += 2*GetSystemMetrics(SM_CXMENUCHECK);
\r
579 szCheck.cy += 2*MESSAGEBOX_BUTTONY;
\r
580 sz.cx = max(sz.cx, szCheck.cx);
\r
581 sz.cy += szCheck.cy + MESSAGEBOX_BUTTONCHECKMARGIN;
\r
582 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->MoveWindow(0, 0, szCheck.cx, szCheck.cy);
\r
584 m_szAllButtons = sz;
\r
588 BEGIN_MESSAGE_MAP(CMessageBox, CDialog)
\r
592 ON_BN_CLICKED(IDC_MESSAGEBOX_BUTTON1, OnButton1)
\r
593 ON_BN_CLICKED(IDC_MESSAGEBOX_BUTTON2, OnButton2)
\r
594 ON_BN_CLICKED(IDC_MESSAGEBOX_BUTTON3, OnButton3)
\r
597 void CMessageBox::OnPaint()
\r
599 CPaintDC dc(this); // device context for painting
\r
604 GetClientRect(&rect);
\r
605 GetClientRect(&drawrect);
\r
607 //create a memory device-context. This is done to help reduce
\r
608 //screen flicker, since we will paint the entire control to the
\r
609 //off screen device context first.
\r
612 memDC.CreateCompatibleDC(&dc);
\r
613 bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
\r
614 CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
\r
616 memDC.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dc, 0,0, SRCCOPY);
\r
618 memDC.SetBkMode(TRANSPARENT);
\r
619 memDC.SetBkColor(GetSysColor(COLOR_WINDOW));
\r
620 memDC.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
\r
622 //OnDrawBackground();
\r
623 drawrect.DeflateRect(MESSAGEBOX_BORDERMARGINX, MESSAGEBOX_BORDERMARGINY);
\r
624 if (m_hIcon != NULL)
\r
626 DrawIconEx(memDC.m_hDC, drawrect.left, drawrect.top +
\r
627 ((drawrect.Height() - m_szAllButtons.cy - MESSAGEBOX_TEXTBUTTONMARGIN - m_szIcon.cy) / 2),
\r
628 m_hIcon, m_szIcon.cx, m_szIcon.cy, 0, NULL, DI_NORMAL);
\r
630 drawrect.left += m_szIcon.cx + MESSAGEBOX_ICONMARGIN;
\r
634 DrawHTML(&memDC, drawrect, m_sMessage, m_LogFont);
\r
637 //Copy the memory device context back into the original DC.
\r
638 dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, 0,0, SRCCOPY);
\r
640 //Cleanup resources.
\r
641 memDC.SelectObject(pOldBitmap);
\r
643 bitmap.DeleteObject();
\r
648 void CMessageBox::OnMouseMove(UINT nFlags, CPoint point)
\r
650 if (IsPointOverALink(point))
\r
652 m_Cursor.SetCursor(IDC_HAND);
\r
656 m_Cursor.Restore();
\r
659 __super::OnMouseMove(nFlags, point);
\r
662 void CMessageBox::OnLButtonUp(UINT nFlags, CPoint point)
\r
664 if (IsPointOverALink(point))
\r
666 CString url = GetLinkForPoint(point);
\r
667 ShellExecute(NULL, _T("open"), url, NULL,NULL, 0);
\r
670 __super::OnLButtonUp(nFlags, point);
\r
673 void CMessageBox::OnButton1()
\r
675 if (GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->SendMessage(BM_GETCHECK, 0, 0)==BST_CHECKED)
\r
676 SetRegistryValue(m_sRegistryValue, m_uButton1Ret);
\r
677 EndDialog(m_uButton1Ret);
\r
680 void CMessageBox::OnButton2()
\r
682 if (GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->SendMessage(BM_GETCHECK, 0, 0)==BST_CHECKED)
\r
683 SetRegistryValue(m_sRegistryValue, m_uButton2Ret);
\r
684 if ((m_uButton2Ret == IDHELP)&&(!m_sHelpPath.IsEmpty()))
\r
686 typedef HWND (WINAPI* FPHH)(HWND, LPCWSTR, UINT, DWORD);
\r
687 FPHH pHtmlHelp=NULL; // Function pointer
\r
688 HINSTANCE hInstHtmlHelp = LoadLibrary(_T("HHCtrl.ocx"));
\r
690 if (hInstHtmlHelp != NULL)
\r
692 (FARPROC&)pHtmlHelp = GetProcAddress(hInstHtmlHelp, "HtmlHelpW");
\r
694 hHelp = pHtmlHelp(m_hWnd, (LPCTSTR)m_sHelpPath, HH_DISPLAY_TOPIC, NULL);
\r
697 ::MessageBox(m_hWnd, _T("could not show help file"), _T("Help"), MB_ICONERROR);
\r
699 else if (m_uButton2Ret == IDHELP)
\r
704 EndDialog(m_uButton2Ret);
\r
707 void CMessageBox::OnButton3()
\r
709 if (GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->SendMessage(BM_GETCHECK, 0, 0)==BST_CHECKED)
\r
710 SetRegistryValue(m_sRegistryValue, m_uButton3Ret);
\r
711 if ((m_uButton3Ret == IDHELP)&&(!m_sHelpPath.IsEmpty()))
\r
713 typedef HWND (WINAPI* FPHH)(HWND, LPCWSTR, UINT, DWORD);
\r
714 FPHH pHtmlHelp=NULL; // Function pointer
\r
715 HINSTANCE hInstHtmlHelp = LoadLibrary(_T("HHCtrl.ocx"));
\r
717 if (hInstHtmlHelp != NULL)
\r
719 (FARPROC&)pHtmlHelp = GetProcAddress(hInstHtmlHelp, "HtmlHelpW");
\r
721 hHelp = pHtmlHelp(m_hWnd, (LPCTSTR)m_sHelpPath, HH_DISPLAY_TOPIC, NULL);
\r
724 ::MessageBox(m_hWnd, _T("could not show help file"), _T("Help"), MB_ICONERROR);
\r
726 else if (m_uButton3Ret == IDHELP)
\r
731 EndDialog(m_uButton3Ret);
\r
734 void CMessageBox::OnCancel()
\r
736 if (m_uCancelRet == IDCANCEL)
\r
737 EndDialog(m_uCancelRet);
\r
738 //__super::OnCancel();
\r
741 BOOL CMessageBox::OnInitDialog()
\r
743 __super::OnInitDialog();
\r
745 CRect rect(0, 0, 0, 0);
\r
747 //determine the required size of the message box
\r
748 CSize szText = GetTextSize(m_sMessage);
\r
749 CSize szIcon = GetIconSize(m_hIcon);
\r
750 CSize szButtons = GetButtonSize();
\r
753 szIconText.cx = szText.cx + szIcon.cx + ((szIcon.cx == 0) ? MESSAGEBOX_ICONMARGIN : (2*MESSAGEBOX_ICONMARGIN));
\r
754 szIconText.cy = max(szIcon.cy, szText.cy);
\r
756 rect.right = max(szButtons.cx, szIconText.cx);
\r
757 rect.right += 2*GetSystemMetrics(SM_CXBORDER);
\r
758 rect.right += 2*MESSAGEBOX_BORDERMARGINX;
\r
759 rect.bottom = szIconText.cy;
\r
760 rect.bottom += szButtons.cy;
\r
761 rect.bottom += 2*MESSAGEBOX_BORDERMARGINY + MESSAGEBOX_TEXTBUTTONMARGIN;
\r
762 rect.bottom += GetSystemMetrics(SM_CYCAPTION);
\r
763 rect.bottom += 2*GetSystemMetrics(SM_CYBORDER);
\r
768 GetClientRect(rect);
\r
770 //now size and position the buttons as we need them
\r
771 ASSERT(!m_sButton1.IsEmpty()); //at least the first button must be there!
\r
772 if (m_sButton2.IsEmpty())
\r
776 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->GetWindowRect(rt);
\r
777 ScreenToClient(rt);
\r
778 rt.MoveToX(rect.left + ((rect.Width() - m_szButtons.cx)/2));
\r
779 rt.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
\r
780 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->MoveWindow(rt);
\r
781 //hide the other two buttons
\r
782 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->ShowWindow(SW_HIDE);
\r
783 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->ShowWindow(SW_HIDE);
\r
785 else if (m_sButton3.IsEmpty())
\r
790 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->GetWindowRect(rt1);
\r
791 ScreenToClient(rt1);
\r
792 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->GetWindowRect(rt2);
\r
793 ScreenToClient(rt2);
\r
794 rt1.MoveToX(rect.left + ((rect.Width() - m_szButtons.cx)/2));
\r
795 rt1.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
\r
796 rt2.MoveToX(rt1.right + MESSAGEBOX_BUTTONMARGIN);
\r
797 rt2.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
\r
798 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->MoveWindow(rt1);
\r
799 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->MoveWindow(rt2);
\r
800 //hide the third button
\r
801 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->ShowWindow(SW_HIDE);
\r
807 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->GetWindowRect(buttonrect);
\r
811 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->GetWindowRect(rt1);
\r
812 ScreenToClient(rt1);
\r
813 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->GetWindowRect(rt2);
\r
814 ScreenToClient(rt2);
\r
815 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->GetWindowRect(rt3);
\r
816 ScreenToClient(rt3);
\r
817 rt1.MoveToX(rect.left + ((rect.Width() - m_szButtons.cx)/2));
\r
818 rt1.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
\r
819 rt2.MoveToX(rt1.right + MESSAGEBOX_BUTTONMARGIN);
\r
820 rt2.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
\r
821 rt3.MoveToX(rt2.right + MESSAGEBOX_BUTTONMARGIN);
\r
822 rt3.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - m_szButtons.cy);
\r
823 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->MoveWindow(rt1);
\r
824 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->MoveWindow(rt2);
\r
825 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->MoveWindow(rt3);
\r
830 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->GetWindowRect(rt);
\r
831 ScreenToClient(rt);
\r
832 rt.MoveToX(rect.left + MESSAGEBOX_BORDERMARGINX/*+ ((rect.Width() - szButtons.cx)/2)*/);
\r
833 rt.MoveToY(rect.bottom - MESSAGEBOX_BORDERMARGINY - szButtons.cy);
\r
834 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->MoveWindow(rt);
\r
835 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->ShowWindow(SW_SHOW);
\r
838 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->ShowWindow(SW_HIDE);
\r
840 if (m_nDefButton == 1)
\r
841 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->SetFocus();
\r
842 if (m_nDefButton == 2)
\r
843 GetDlgItem(IDC_MESSAGEBOX_BUTTON2)->SetFocus();
\r
844 if (m_nDefButton == 3)
\r
845 GetDlgItem(IDC_MESSAGEBOX_BUTTON3)->SetFocus();
\r
847 SetWindowPos(&CWnd::wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
\r
848 SetForegroundWindow();
\r
849 SetFocus(); //Just playing safe
\r
851 return FALSE; // return TRUE unless you set the focus to a control
\r
852 // EXCEPTION: OCX Property Pages should return FALSE
\r
855 BOOL CMessageBox::PreTranslateMessage(MSG* pMsg)
\r
857 if (pMsg->message == WM_KEYDOWN)
\r
859 switch (pMsg->wParam)
\r
864 if (GetAsyncKeyState(VK_CONTROL)&0x8000)
\r
866 CStringA sClipboard = CStringA(m_sMessage);
\r
867 if (OpenClipboard())
\r
870 HGLOBAL hClipboardData;
\r
871 hClipboardData = GlobalAlloc(GMEM_DDESHARE, sClipboard.GetLength()+1);
\r
873 pchData = (char*)GlobalLock(hClipboardData);
\r
874 strcpy_s(pchData, sClipboard.GetLength()+1, (LPCSTR)sClipboard);
\r
875 GlobalUnlock(hClipboardData);
\r
876 SetClipboardData(CF_TEXT,hClipboardData);
\r
885 switch (m_uType & 0xf)
\r
887 case MB_ABORTRETRYIGNORE:
\r
888 EndDialog(m_uButton1Ret);
\r
890 case MB_CANCELTRYCONTINUE:
\r
891 EndDialog(m_uButton1Ret);
\r
894 EndDialog(m_uButton2Ret);
\r
896 case MB_RETRYCANCEL:
\r
897 EndDialog(m_uButton2Ret);
\r
900 EndDialog(m_uButton2Ret);
\r
902 case MB_YESNOCANCEL:
\r
903 EndDialog(m_uButton3Ret);
\r
911 return __super::PreTranslateMessage(pMsg);
\r