OSDN Git Service

Workaround Show Message Problem
[tortoisegit/TortoiseGitJp.git] / Utils / MiscUI / MessageBox.cpp
1 // TortoiseSVN - a Windows shell extension for easy version control\r
2 \r
3 // Copyright (C) 2003-2008 - TortoiseSVN\r
4 \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
9 \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
14 \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
18 //\r
19 #include "StdAfx.h"\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
23 \r
24 \r
25 CMessageBox::CMessageBox(void)\r
26 {\r
27         m_hIcon = NULL;\r
28         m_uButton1Ret = 1;\r
29         m_uButton2Ret = 2;\r
30         m_uButton3Ret = 3;\r
31         m_uCancelRet = 0;\r
32         m_bShowCheck = FALSE;\r
33         m_bDestroyIcon = FALSE;\r
34 }\r
35 \r
36 CMessageBox::~CMessageBox(void)\r
37 {\r
38         if (m_bDestroyIcon)\r
39                 ::DestroyIcon(m_hIcon);\r
40 }\r
41 \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
43 {\r
44         CString sButton1;\r
45         CString sButton2;\r
46         CString sButton3;\r
47         CString sMessage;\r
48         CString sCaption;\r
49         CString nCheckMsg;\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
57 }\r
58 \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
60 {\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
63         DWORD dwRetVal;\r
64         HKEY hKey;\r
65         CString path;\r
66 #ifdef XMESSAGEBOX_APPREGPATH\r
67         path = XMESSAGEBOX_APPREGPATH;\r
68 #else\r
69         path = "Software\\";\r
70         path += AfxGetAppName();\r
71 #endif\r
72         if (RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_EXECUTE, &hKey)==ERROR_SUCCESS)\r
73         {\r
74                 int size = sizeof(dwRetVal);\r
75                 DWORD type;\r
76                 if (RegQueryValueEx(hKey, lpRegistry, NULL, &type, (BYTE*) &dwRetVal,(LPDWORD) &size)==ERROR_SUCCESS)\r
77                 {\r
78                         ASSERT(type==REG_DWORD);\r
79                         RegCloseKey(hKey);\r
80                         return (UINT)dwRetVal;                  //return with the last saved value\r
81                 }\r
82                 else\r
83                 {\r
84                         RegCloseKey(hKey);\r
85                 }\r
86         }\r
87 \r
88         CMessageBox box;\r
89         box.m_bShowCheck = TRUE;\r
90         box.m_sRegistryValue = lpRegistry;\r
91         if (lpCheckMessage == NULL)\r
92         {\r
93 #ifndef IDS_MSGBOX_DONOTSHOWAGAIN\r
94                 box.m_sCheckbox = _T("do not show again");\r
95 #else\r
96                 CString m_i18l;\r
97                 m_i18l.LoadString(IDS_MSGBOX_DONOTSHOWAGAIN);\r
98                 box.m_sCheckbox = m_i18l;\r
99 #endif\r
100         }\r
101         else\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
109         else\r
110                 box.m_bDestroyIcon = TRUE;\r
111         if (!IsWindow(hWnd))\r
112                 hWnd = NULL;\r
113         return box.GoModal(CWnd::FromHandle(hWnd), lpCaption, lpMessage, nDef); \r
114 }\r
115 \r
116 UINT CMessageBox::Show(HWND hWnd, LPCTSTR lpMessage, LPCTSTR lpCaption, int nDef, LPCTSTR icon, LPCTSTR lpButton1, LPCTSTR lpButton2/* = NULL*/, LPCTSTR lpButton3/* = NULL*/)\r
117 {\r
118         CMessageBox box;\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
125         else\r
126                 box.m_bDestroyIcon = TRUE;\r
127         if (!IsWindow(hWnd))\r
128                 hWnd = NULL;\r
129         return box.GoModal(CWnd::FromHandle(hWnd), lpCaption, lpMessage, nDef);\r
130 }\r
131 \r
132 UINT CMessageBox::Show(HWND hWnd, UINT nMessage, UINT nCaption, int nDef, LPCTSTR icon, UINT nButton1, UINT nButton2, UINT nButton3)\r
133 {\r
134         CString sButton1;\r
135         CString sButton2;\r
136         CString sButton3;\r
137         CString sMessage;\r
138         CString sCaption;\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
145 }\r
146 \r
147 \r
148 UINT CMessageBox::ShowCheck(HWND hWnd, UINT nMessage, UINT nCaption, UINT uType, LPCTSTR lpRegistry, UINT nCheckMessage)\r
149 {\r
150         CString sMessage;\r
151         CString sCaption;\r
152         CString sCheckMsg;\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
157 }\r
158 \r
159 UINT CMessageBox::ShowCheck(HWND hWnd, LPCTSTR lpMessage, LPCTSTR lpCaption, UINT uType, LPCTSTR lpRegistry, LPCTSTR lpCheckMessage)\r
160 {\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
163         DWORD dwRetVal;\r
164         HKEY hKey;\r
165         CString path;\r
166 #ifdef XMESSAGEBOX_APPREGPATH\r
167         path = XMESSAGEBOX_APPREGPATH;\r
168 #else\r
169         path = "Software\\";\r
170         path += AfxGetAppName();\r
171 #endif\r
172         if (RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_EXECUTE, &hKey)==ERROR_SUCCESS)\r
173         {\r
174                 int size = sizeof(dwRetVal);\r
175                 DWORD type;\r
176                 if (RegQueryValueEx(hKey, lpRegistry, NULL, &type, (BYTE*) &dwRetVal,(LPDWORD) &size)==ERROR_SUCCESS)\r
177                 {\r
178                         ASSERT(type==REG_DWORD);\r
179                         RegCloseKey(hKey);\r
180                         return (UINT)dwRetVal;                  //return with the last saved value\r
181                 }\r
182                 else\r
183                 {\r
184                         RegCloseKey(hKey);\r
185                 }\r
186         }\r
187 \r
188         CMessageBox box;\r
189         box.m_bShowCheck = TRUE;\r
190         box.m_sRegistryValue = lpRegistry;\r
191         if (lpCheckMessage == NULL)\r
192         {\r
193 #ifndef IDS_MSGBOX_DONOTSHOWAGAIN\r
194                 box.m_sCheckbox = _T("do not show again");\r
195 #else\r
196                 CString m_i18l;\r
197                 m_i18l.LoadString(IDS_MSGBOX_DONOTSHOWAGAIN);\r
198                 box.m_sCheckbox = m_i18l;\r
199 #endif\r
200         }\r
201         else\r
202                 box.m_sCheckbox = lpCheckMessage;\r
203         if (!IsWindow(hWnd))\r
204                 hWnd = NULL;\r
205         return box.GoModal(CWnd::FromHandle(hWnd), lpCaption, lpMessage, box.FillBoxStandard(uType));\r
206 }\r
207 \r
208 UINT CMessageBox::Show(HWND hWnd, UINT nMessage, UINT nCaption, UINT uType, LPCTSTR sHelpPath)\r
209 {\r
210         CString sMessage;\r
211         CString sCaption;\r
212         sMessage.LoadString(nMessage);\r
213         sCaption.LoadString(nCaption);\r
214         return CMessageBox::Show(hWnd, sMessage, sCaption, uType, sHelpPath);\r
215 }\r
216 \r
217 UINT CMessageBox::Show(HWND hWnd, LPCTSTR lpMessage, LPCTSTR lpCaption, UINT uType, LPCTSTR sHelpPath)\r
218 {\r
219         CMessageBox box;\r
220         \r
221         if (!IsWindow(hWnd))\r
222                 hWnd = NULL;\r
223         if (sHelpPath)\r
224                 box.SetHelpPath(sHelpPath);\r
225         return box.GoModal(CWnd::FromHandle(hWnd), lpCaption, lpMessage, box.FillBoxStandard(uType));\r
226 }\r
227 \r
228 UINT CMessageBox::Show(HWND hWnd, UINT nMessage, UINT nCaption, UINT uType, UINT nHelpID)\r
229 {\r
230         CMessageBox box;\r
231         CString sMessage;\r
232         CString sCaption;\r
233         sMessage.LoadString(nMessage);\r
234         sCaption.LoadString(nCaption);\r
235 \r
236         if (!IsWindow(hWnd))\r
237                 hWnd = NULL;\r
238         box.SetHelpID(nHelpID);\r
239 \r
240         return box.GoModal(CWnd::FromHandle(hWnd), sCaption, sMessage, box.FillBoxStandard(uType));\r
241 }\r
242 \r
243 int CMessageBox::FillBoxStandard(UINT uType)\r
244 {\r
245         int ret = 1;\r
246         m_uType = uType;\r
247         m_uCancelRet = IDCANCEL;\r
248         //load the icons according to uType\r
249         switch (uType & 0xf0)\r
250         {\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
254                 break;\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
258                 break;\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
262                 break;\r
263         case MB_ICONHAND:\r
264                 m_hIcon = (HICON)::LoadImage(NULL, IDI_HAND, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);\r
265                 ::MessageBeep(MB_ICONHAND);\r
266                 break;\r
267         }\r
268         //set up the button texts\r
269         switch (uType & 0xf)\r
270         {\r
271         case MB_ABORTRETRYIGNORE:\r
272 #ifndef IDS_MSGBOX_ABORT\r
273                 m_sButton1 = "Abort";\r
274 #else\r
275                 m_i18l.LoadString(IDS_MSGBOX_ABORT);\r
276                 m_sButton1 = m_i18l;\r
277 #endif\r
278                 m_uButton1Ret = IDABORT;\r
279 #ifndef IDS_MSGBOX_RETRY\r
280                 m_sButton2 = "Retry";\r
281 #else\r
282                 m_i18l.LoadString(IDS_MSGBOX_RETRY);\r
283                 m_sButton2 = m_i18l;\r
284 #endif\r
285                 m_uButton2Ret = IDRETRY;\r
286 #ifndef IDS_MSGBOX_IGNORE\r
287                 m_sButton3 = "Ignore";\r
288 #else\r
289                 m_i18l.LoadString(IDS_MSGBOX_IGNORE);\r
290                 m_sButton3 = m_i18l;\r
291 #endif\r
292                 m_uButton3Ret = IDIGNORE;\r
293                 break;\r
294         case MB_CANCELTRYCONTINUE:\r
295 #ifndef IDS_MSGBOX_CANCEL\r
296                 m_sButton1 = "Cancel";\r
297 #else\r
298                 m_i18l.LoadString(IDS_MSGBOX_CANCEL);\r
299                 m_sButton1 = m_i18l;\r
300 #endif\r
301                 m_uButton1Ret = IDCANCEL;\r
302 #ifndef IDS_MSGBOX_TRYAGAIN\r
303                 m_sButton2 = "Try Again";\r
304 #else\r
305                 m_i18l.LoadString(IDS_MSGBOX_TRYAGAIN);\r
306                 m_sButton2 = m_i18l;\r
307 #endif\r
308                 m_uButton2Ret = IDTRYAGAIN;\r
309 #ifndef IDS_MSGBOX_CONTINUE\r
310                 m_sButton3 = "Continue";\r
311 #else\r
312                 m_i18l.LoadString(IDS_MSGBOX_CONTINUE);\r
313                 m_sButton3 = m_i18l;\r
314 #endif\r
315                 m_uButton3Ret = IDCONTINUE;\r
316                 break;\r
317         case MB_OKCANCEL:\r
318 #ifndef IDS_MSGBOX_OK\r
319                 m_sButton1 = "Ok";\r
320 #else\r
321                 m_i18l.LoadString(IDS_MSGBOX_OK);\r
322                 m_sButton1 = m_i18l;\r
323 #endif\r
324                 m_uButton1Ret = IDOK;\r
325 #ifndef IDS_MSGBOX_CANCEL\r
326                 m_sButton2 = "Cancel";\r
327 #else\r
328                 m_i18l.LoadString(IDS_MSGBOX_CANCEL);\r
329                 m_sButton2 = m_i18l;\r
330 #endif\r
331                 m_uButton2Ret = IDCANCEL;\r
332                 break;\r
333         case MB_RETRYCANCEL:\r
334 #ifndef IDS_MSGBOX_RETRY\r
335                 m_sButton1 = "Retry";\r
336 #else\r
337                 m_i18l.LoadString(IDS_MSGBOX_RETRY);\r
338                 m_sButton1 = m_i18l;\r
339 #endif\r
340                 m_uButton1Ret = IDRETRY;\r
341 #ifndef IDS_MSGBOX_CANCEL\r
342                 m_sButton2 = "Cancel";\r
343 #else\r
344                 m_i18l.LoadString(IDS_MSGBOX_CANCEL);\r
345                 m_sButton2 = m_i18l;\r
346 #endif\r
347                 m_uButton2Ret = IDCANCEL;\r
348                 break;\r
349         case MB_YESNO:\r
350 #ifndef IDS_MSGBOX_YES\r
351                 m_sButton1 = "Yes";\r
352 #else\r
353                 m_i18l.LoadString(IDS_MSGBOX_YES);\r
354                 m_sButton1 = m_i18l;\r
355 #endif\r
356                 m_uButton1Ret = IDYES;\r
357 #ifndef IDS_MSGBOX_NO\r
358                 m_sButton2 = "No";\r
359 #else\r
360                 m_i18l.LoadString(IDS_MSGBOX_NO);\r
361                 m_sButton2 = m_i18l;\r
362 #endif\r
363                 m_uButton2Ret = IDNO;\r
364                 break;\r
365         case MB_YESNOCANCEL:\r
366 #ifndef IDS_MSGBOX_YES\r
367                 m_sButton1 = "Yes";\r
368 #else\r
369                 m_i18l.LoadString(IDS_MSGBOX_YES);\r
370                 m_sButton1 = m_i18l;\r
371 #endif\r
372                 m_uButton1Ret = IDYES;\r
373 #ifndef IDS_MSGBOX_NO\r
374                 m_sButton2 = "No";\r
375 #else\r
376                 m_i18l.LoadString(IDS_MSGBOX_NO);\r
377                 m_sButton2 = m_i18l;\r
378 #endif\r
379                 m_uButton2Ret = IDNO;\r
380 #ifndef IDS_MSGBOX_CANCEL\r
381                 m_sButton3 = "Cancel";\r
382 #else\r
383                 m_i18l.LoadString(IDS_MSGBOX_CANCEL);\r
384                 m_sButton3 = m_i18l;\r
385 #endif\r
386                 m_uButton3Ret = IDCANCEL;\r
387                 break;\r
388         case MB_OK:\r
389         default:\r
390 #ifndef IDS_MSGBOX_OK\r
391                 m_sButton1 = "Ok";\r
392 #else\r
393                 m_i18l.LoadString(IDS_MSGBOX_OK);\r
394                 m_sButton1 = m_i18l;\r
395 #endif\r
396         }\r
397         //now set the default button\r
398         switch (uType & 0xf00)\r
399         {\r
400         case MB_DEFBUTTON2:\r
401                 ret = 2;\r
402                 break;\r
403         case MB_DEFBUTTON3:\r
404                 ret = 3;\r
405                 break;\r
406         }\r
407         // do we need to add a help button?\r
408         if (uType & MB_HELP)\r
409         {\r
410                 CString sHelpText;\r
411 #ifndef IDS_MSGBOX_HELP\r
412                 sHelpText = _T("Help");\r
413 #else\r
414                 m_i18l.LoadString(IDS_MSGBOX_HELP);\r
415                 sHelpText = m_i18l;\r
416 #endif\r
417                 if (m_sButton2.IsEmpty())\r
418                 {\r
419                         m_sButton2 = sHelpText;\r
420                         m_uButton2Ret = IDHELP;\r
421                 }\r
422                 else if (m_sButton3.IsEmpty())\r
423                 {\r
424                         m_sButton3 = sHelpText;\r
425                         m_uButton3Ret = IDHELP;\r
426                 }\r
427         }\r
428         return ret;\r
429 }\r
430 \r
431 UINT CMessageBox::GoModal(CWnd * pWnd, const CString& title, const CString& msg, int nDefaultButton)\r
432 {\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
438     LPSTR lpBuffer;    \r
439       FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER  | \r
440           FORMAT_MESSAGE_IGNORE_INSERTS  | \r
441          FORMAT_MESSAGE_FROM_SYSTEM,\r
442          NULL,\r
443          nErrorNo, // ´ËÄË´íÎó´úÂ룬ͨ³£ÔÚ³ÌÐòÖпÉÓÉ GetLastError()µÃÖ®\r
444          LANG_NEUTRAL,\r
445          (LPTSTR) & lpBuffer,\r
446           0 ,\r
447          NULL );\r
448     memcpy(&m_LogFont, &(ncm.lfMessageFont), sizeof(LOGFONT));\r
449 \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
453         CDC * pDC;\r
454         if (pWnd)\r
455                 pDC = pWnd->GetDC();\r
456         else\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
469         \r
470         m_nDefButton = nDefaultButton;\r
471         m_sMessage = msg;\r
472         InitModalIndirect(dialogTemplate, pWnd);\r
473 \r
474         return (UINT)DoModal();\r
475 }\r
476 \r
477 void CMessageBox::SetRegistryValue(const CString& sValue, DWORD value)\r
478 {\r
479         CString path;\r
480 #ifdef XMESSAGEBOX_APPREGPATH\r
481         path = XMESSAGEBOX_APPREGPATH;\r
482 #else\r
483         path = "Software\\";\r
484         path += AfxGetAppName();\r
485 #endif\r
486         DWORD disp;\r
487         HKEY hKey;\r
488         if (RegCreateKeyEx(HKEY_CURRENT_USER, path, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &disp)!=ERROR_SUCCESS)\r
489         {\r
490                 return;\r
491         }\r
492         RegSetValueEx(hKey, sValue, 0, REG_DWORD,(const BYTE*) &value, sizeof(value));\r
493         RegCloseKey(hKey);\r
494 }\r
495 \r
496 CSize CMessageBox::GetTextSize(const CString& str)\r
497 {\r
498         CRect rect;\r
499         GetWindowRect(&rect);\r
500 \r
501         CDC * pDC = GetDC();\r
502 \r
503         CDC memDC;\r
504         CBitmap bitmap;\r
505         memDC.CreateCompatibleDC(pDC);\r
506         bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());\r
507         CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);\r
508 \r
509         //get the minimum size of the rectangle of the tooltip\r
510         CSize sz = DrawHTML(&memDC, rect, str, m_LogFont, TRUE);\r
511 \r
512         memDC.SelectObject(pOldBitmap);\r
513         memDC.DeleteDC();\r
514         bitmap.DeleteObject();\r
515 \r
516         ReleaseDC(pDC);\r
517 \r
518         return sz;\r
519 }\r
520 \r
521 CSize CMessageBox::GetIconSize(HICON hIcon)\r
522 {\r
523         ICONINFO ii;\r
524         CSize sz (0, 0);\r
525 \r
526         if (hIcon != NULL)\r
527         {\r
528                 //get icon dimensions\r
529                 ::SecureZeroMemory(&ii, sizeof(ICONINFO));\r
530                 if (::GetIconInfo(hIcon, &ii))\r
531                 {\r
532                         sz.cx = (DWORD)(ii.xHotspot * 2);\r
533                         sz.cy = (DWORD)(ii.yHotspot * 2);\r
534                         //release icon mask bitmaps\r
535                         if(ii.hbmMask)\r
536                                 ::DeleteObject(ii.hbmMask);\r
537                         if(ii.hbmColor)\r
538                                 ::DeleteObject(ii.hbmColor);\r
539                 }\r
540         }\r
541         m_szIcon = sz;\r
542         return sz;\r
543 }\r
544 \r
545 CSize CMessageBox::GetButtonSize()\r
546 {\r
547         CSize sz;\r
548         int nButtons = 0;               //number of buttons - 1\r
549 \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
555         \r
556         CSize sz1 = GetTextSize(m_sButton1);\r
557         CSize sz2 = GetTextSize(m_sButton2);\r
558         CSize sz3 = GetTextSize(m_sButton3);\r
559 \r
560         sz1.cx += 2*MESSAGEBOX_BUTTONX;\r
561         sz1.cy += 2*MESSAGEBOX_BUTTONY;\r
562 \r
563         if (sz2.cx)\r
564         {\r
565                 sz2.cx += 2*MESSAGEBOX_BUTTONX;\r
566                 sz2.cy += 2*MESSAGEBOX_BUTTONY;\r
567                 nButtons++;\r
568         }\r
569         if (sz3.cx)\r
570         {\r
571                 sz3.cx += 2*MESSAGEBOX_BUTTONX;\r
572                 sz3.cy += 2*MESSAGEBOX_BUTTONY;\r
573                 nButtons++;\r
574         }\r
575         \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
579 \r
580 \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
584         m_szButtons = sz;\r
585         if (m_bShowCheck)\r
586         {\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
593         }\r
594         m_szAllButtons = sz;\r
595         return sz;\r
596 }\r
597 \r
598 BEGIN_MESSAGE_MAP(CMessageBox, CDialog)\r
599         ON_WM_PAINT()\r
600         ON_WM_MOUSEMOVE()\r
601         ON_WM_LBUTTONUP()\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
605 END_MESSAGE_MAP()\r
606 \r
607 void CMessageBox::OnPaint()\r
608 {\r
609         CPaintDC dc(this); // device context for painting\r
610 \r
611 \r
612         CRect rect;\r
613         CRect drawrect;\r
614         GetClientRect(&rect);\r
615         GetClientRect(&drawrect);\r
616 \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
620         CDC memDC;\r
621         CBitmap bitmap;\r
622         memDC.CreateCompatibleDC(&dc);\r
623         bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());\r
624         CBitmap* pOldBitmap = memDC.SelectObject(&bitmap); \r
625         \r
626         memDC.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dc, 0,0, SRCCOPY);\r
627 \r
628         memDC.SetBkMode(TRANSPARENT);\r
629         memDC.SetBkColor(GetSysColor(COLOR_WINDOW));\r
630         memDC.SetTextColor(GetSysColor(COLOR_WINDOWTEXT)); \r
631 \r
632         //OnDrawBackground();\r
633         drawrect.DeflateRect(MESSAGEBOX_BORDERMARGINX, MESSAGEBOX_BORDERMARGINY);\r
634         if (m_hIcon != NULL)\r
635         {\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
639 \r
640                 drawrect.left += m_szIcon.cx + MESSAGEBOX_ICONMARGIN; \r
641         }\r
642 \r
643 \r
644         DrawHTML(&memDC, drawrect, m_sMessage, m_LogFont);\r
645         \r
646 \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
649         \r
650         //Cleanup resources.\r
651         memDC.SelectObject(pOldBitmap);\r
652         memDC.DeleteDC();\r
653         bitmap.DeleteObject(); \r
654 \r
655 \r
656 }\r
657 \r
658 void CMessageBox::OnMouseMove(UINT nFlags, CPoint point)\r
659 {\r
660         if (IsPointOverALink(point))\r
661         {\r
662                 m_Cursor.SetCursor(IDC_HAND);\r
663         }\r
664         else\r
665         {\r
666                 m_Cursor.Restore();     \r
667         }\r
668 \r
669         __super::OnMouseMove(nFlags, point);\r
670 }\r
671 \r
672 void CMessageBox::OnLButtonUp(UINT nFlags, CPoint point)\r
673 {\r
674         if (IsPointOverALink(point))\r
675         {\r
676                 CString url = GetLinkForPoint(point);\r
677                 ShellExecute(NULL, _T("open"), url, NULL,NULL, 0);\r
678         }\r
679 \r
680         __super::OnLButtonUp(nFlags, point);\r
681 }\r
682 \r
683 void CMessageBox::OnButton1()\r
684 {\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
688 }\r
689 \r
690 void CMessageBox::OnButton2()\r
691 {\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
695         {\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
699                 HWND hHelp = NULL;\r
700                 if (hInstHtmlHelp != NULL)\r
701                 {\r
702                         (FARPROC&)pHtmlHelp = GetProcAddress(hInstHtmlHelp, "HtmlHelpW");\r
703                         if (pHtmlHelp)\r
704                                 hHelp = pHtmlHelp(m_hWnd, (LPCTSTR)m_sHelpPath, HH_DISPLAY_TOPIC, NULL);\r
705                 }\r
706                 if (hHelp == NULL)\r
707                         ::MessageBox(m_hWnd, _T("could not show help file"), _T("Help"), MB_ICONERROR);\r
708         }\r
709         else if (m_uButton2Ret == IDHELP)\r
710         {\r
711                 OnHelp();\r
712         }\r
713         else\r
714                 EndDialog(m_uButton2Ret);\r
715 }\r
716 \r
717 void CMessageBox::OnButton3()\r
718 {\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
722         {\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
726                 HWND hHelp = NULL;\r
727                 if (hInstHtmlHelp != NULL)\r
728                 {\r
729                         (FARPROC&)pHtmlHelp = GetProcAddress(hInstHtmlHelp, "HtmlHelpW");\r
730                         if (pHtmlHelp)\r
731                                 hHelp = pHtmlHelp(m_hWnd, (LPCTSTR)m_sHelpPath, HH_DISPLAY_TOPIC, NULL);\r
732                 }\r
733                 if (hHelp == NULL)\r
734                         ::MessageBox(m_hWnd, _T("could not show help file"), _T("Help"), MB_ICONERROR);\r
735         }\r
736         else if (m_uButton3Ret == IDHELP)\r
737         {\r
738                 OnHelp();\r
739         }\r
740         else\r
741                 EndDialog(m_uButton3Ret);\r
742 }\r
743 \r
744 void CMessageBox::OnCancel()\r
745 {\r
746         if (m_uCancelRet == IDCANCEL)\r
747                 EndDialog(m_uCancelRet);\r
748         //__super::OnCancel();\r
749 }\r
750 \r
751 BOOL CMessageBox::OnInitDialog()\r
752 {\r
753         __super::OnInitDialog();\r
754 \r
755         CRect rect(0, 0, 0, 0);\r
756 \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
761 \r
762         CSize szIconText;\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
765 \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
774 \r
775         MoveWindow(rect);\r
776         CenterWindow();\r
777         \r
778         GetClientRect(rect);\r
779         \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
783         {\r
784                 //only one button\r
785                 CRect rt;\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
794         }\r
795         else if (m_sButton3.IsEmpty())\r
796         {\r
797                 //two buttons\r
798                 CRect rt1;\r
799                 CRect rt2;\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
812         }\r
813         else\r
814         {\r
815                 //three buttons\r
816                 CRect buttonrect;\r
817                 GetDlgItem(IDC_MESSAGEBOX_BUTTON1)->GetWindowRect(buttonrect);\r
818                 CRect rt1;\r
819                 CRect rt2;\r
820                 CRect rt3;\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
836         }\r
837         if (m_bShowCheck)\r
838         {\r
839                 CRect rt;\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
846         }\r
847         else\r
848                 GetDlgItem(IDC_MESSAGEBOX_CHECKBOX)->ShowWindow(SW_HIDE);\r
849 \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
856 \r
857         SetWindowPos(&CWnd::wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);\r
858         SetForegroundWindow();\r
859         SetFocus(); //Just playing safe\r
860 \r
861         return FALSE;  // return TRUE unless you set the focus to a control\r
862         // EXCEPTION: OCX Property Pages should return FALSE\r
863 }\r
864 \r
865 BOOL CMessageBox::PreTranslateMessage(MSG* pMsg)\r
866 {\r
867         if (pMsg->message == WM_KEYDOWN)\r
868         {\r
869                 switch (pMsg->wParam)\r
870                 {\r
871                 case 'C':\r
872                 case VK_INSERT:\r
873                         {\r
874                                 if (GetAsyncKeyState(VK_CONTROL)&0x8000)\r
875                                 {\r
876                                         CStringA sClipboard = CStringA(m_sMessage);\r
877                                         if (OpenClipboard())\r
878                                         {\r
879                                                 EmptyClipboard();\r
880                                                 HGLOBAL hClipboardData;\r
881                                                 hClipboardData = GlobalAlloc(GMEM_DDESHARE, sClipboard.GetLength()+1);\r
882                                                 char * pchData;\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
887                                                 CloseClipboard();\r
888                                         }\r
889                                         return TRUE;\r
890                                 }\r
891                         }\r
892                         break;\r
893                 case VK_ESCAPE:\r
894                         {\r
895                                 switch (m_uType & 0xf)\r
896                                 {\r
897                                 case MB_ABORTRETRYIGNORE:\r
898                                         EndDialog(m_uButton1Ret);\r
899                                         break;\r
900                                 case MB_CANCELTRYCONTINUE:\r
901                                         EndDialog(m_uButton1Ret);\r
902                                         break;\r
903                                 case MB_OKCANCEL:\r
904                                         EndDialog(m_uButton2Ret);\r
905                                         break;\r
906                                 case MB_RETRYCANCEL:\r
907                                         EndDialog(m_uButton2Ret);\r
908                                         break;\r
909                                 case MB_YESNO:\r
910                                         EndDialog(m_uButton2Ret);\r
911                                         break;\r
912                                 case MB_YESNOCANCEL:\r
913                                         EndDialog(m_uButton3Ret);\r
914                                         break;\r
915                                 }\r
916                         }\r
917                         break;\r
918                 }\r
919         }\r
920 \r
921         return __super::PreTranslateMessage(pMsg);\r
922 }\r
923 \r
924 \r
925 \r
926 \r
927 \r
928 \r
929 \r