Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

259 lines
7.0 KiB

  1. #include "stdafx.h"
  2. #include "common.h"
  3. #include "resource.h"
  4. #include "afxpriv.h"
  5. #include "InetMgrApp.h"
  6. #include "msgbox.h"
  7. extern CComModule _Module;
  8. extern CInetmgrApp theApp;
  9. BOOL
  10. WINAPI
  11. UtilHelpCallback(
  12. IN HWND hwnd,
  13. IN PVOID pVoid
  14. )
  15. /*++
  16. Routine Description:
  17. This routine is the called back that is called when a
  18. message box is displayed with a help button and the user
  19. clicks on the help button.
  20. Arguments:
  21. hwnd - handle to windows that recieved the WM_HELP message.
  22. pVoid - pointer to the user data passsed in the call to
  23. MessageBoxHelper. The client can store any value
  24. in this paramter.
  25. Return Value:
  26. TRUE callback was successful, FALSE some error occurred.
  27. --*/
  28. {
  29. //
  30. // Get a usable pointer to the help map entry.
  31. //
  32. MSG_HLPMAP *pHelpMapEntry = reinterpret_cast<MSG_HLPMAP *>( pVoid );
  33. if (pHelpMapEntry)
  34. {
  35. WinHelpDebug(pHelpMapEntry->uIdMessage);
  36. ::WinHelp(hwnd,theApp.m_pszHelpFilePath, HELP_CONTEXT, pHelpMapEntry->uIdMessage);
  37. return TRUE;
  38. }
  39. else
  40. {
  41. return FALSE;
  42. }
  43. }
  44. int DoHelpMessageBox(HWND hWndIn, UINT iResourceID, UINT nType, UINT nIDPrompt)
  45. {
  46. CString strMsg;
  47. strMsg.LoadString(iResourceID);
  48. return DoHelpMessageBox(hWndIn,strMsg,nType,nIDPrompt);
  49. }
  50. int DoHelpMessageBox(HWND hWndIn, LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt)
  51. {
  52. HWND hWndTop;
  53. int nResult = 0;
  54. HWND hWnd = hWndIn;
  55. if (!hWnd)
  56. {
  57. hWnd = CWnd::GetSafeOwner_(NULL, &hWndTop);
  58. }
  59. // set help context if possible
  60. DWORD* pdwContext = NULL;
  61. HWND hWnd2 = AfxGetMainWnd()->GetSafeHwnd();
  62. if (hWnd2 != NULL)
  63. {
  64. // use app-level context or frame level context
  65. LRESULT lResult = ::SendMessage(hWnd2, WM_HELPPROMPTADDR, 0, 0); // Use "MainWnd" HWND
  66. if (lResult != 0)
  67. {pdwContext = (DWORD*)lResult;}
  68. }
  69. DWORD dwOldPromptContext = 0;
  70. if (pdwContext != NULL)
  71. {
  72. // save old prompt context for restoration later
  73. dwOldPromptContext = *pdwContext;
  74. if (nIDPrompt != 0)
  75. {*pdwContext = HID_BASE_PROMPT + nIDPrompt;}
  76. }
  77. TCHAR wszTitle[MAX_PATH] ;
  78. LoadString(_Module.GetResourceInstance(), IDS_APP_NAME, wszTitle, MAX_PATH);
  79. if (nIDPrompt != 0)
  80. {nType |= MB_HELP;}
  81. if (nType & MB_HELP)
  82. {
  83. MSG_HLPMAP HelpMapEntry;
  84. HelpMapEntry.uIdMessage = nIDPrompt;
  85. nResult = MessageBoxHelper(hWnd, lpszPrompt, wszTitle, nType | MB_TASKMODAL, UtilHelpCallback, &HelpMapEntry);
  86. }
  87. else
  88. {
  89. nResult = ::MessageBox(hWnd, lpszPrompt, wszTitle, nType | MB_TASKMODAL);
  90. }
  91. // restore prompt context if possible
  92. if (pdwContext != NULL)
  93. {*pdwContext = dwOldPromptContext;}
  94. // re-enable windows
  95. if (hWndTop != NULL)
  96. {::EnableWindow(hWndTop, TRUE);}
  97. return nResult;
  98. }
  99. /*++
  100. Routine Name:
  101. MessageBoxHelper
  102. Routine Description:
  103. This routine is very similar to the win32 MessageBox except it
  104. creates a hidden dialog when the user request that a help button
  105. be displayed. The MessageBox api is some what broken
  106. with respect to the way the help button works. When the help button is
  107. clicked the MessageBox api will send a help event to the parent window.
  108. It is the responsiblity of the parent window to respond corectly, i.e.
  109. start either WinHelp or HtmlHelp. Unfortunatly not in all cases does the
  110. caller have a parent window or has ownership to the parent window code to
  111. add suport for the help event. In these case is why someone would use this
  112. function.
  113. Arguments:
  114. hWnd - handle of owner window
  115. lpText - address of text in message box
  116. lpCaption - address of title of message box
  117. uType - style of message box
  118. pfHelpCallback - pointer to function called when a WM_HELP message is received, this
  119. parameter is can be NULL then api acts like MessageBox.
  120. pRefData - user defined refrence data passed along to the callback routine,
  121. this paremeter can be NULL.
  122. Return Value:
  123. See windows sdk for return values from MessageBox
  124. --*/
  125. INT
  126. MessageBoxHelper(
  127. IN HWND hWnd,
  128. IN LPCTSTR pszMsg,
  129. IN LPCTSTR pszTitle,
  130. IN UINT uFlags,
  131. IN pfHelpCallback pCallback, OPTIONAL
  132. IN PVOID pRefData OPTIONAL
  133. )
  134. {
  135. INT iRetval = 0;
  136. //
  137. // If the caller specifed the help flag and provided a callback then
  138. // use the message box dialog class to display the message box, otherwise
  139. // fall back to the original behavior of MessageBox.
  140. //
  141. if( ( uFlags & MB_HELP ) && pCallback )
  142. {
  143. TMessageBoxDialog MyHelpDialog( hWnd, uFlags, pszTitle, pszMsg, pCallback, pRefData );
  144. if(MyHelpDialog.bValid())
  145. {
  146. iRetval = MyHelpDialog.iMessageBox();
  147. }
  148. }
  149. else
  150. {
  151. //
  152. // Display the message box.
  153. //
  154. iRetval = ::MessageBox( hWnd, pszMsg, pszTitle, uFlags );
  155. }
  156. return iRetval;
  157. }
  158. /********************************************************************
  159. Message box helper class.
  160. ********************************************************************/
  161. BOOL TMessageBoxDialog::bHandleMessage(
  162. IN UINT uMsg,
  163. IN WPARAM wParam,
  164. IN LPARAM lParam
  165. )
  166. {
  167. BOOL bStatus = TRUE;
  168. switch (uMsg)
  169. {
  170. case WM_INITDIALOG:
  171. ShowWindow( _hDlg, SW_HIDE );
  172. _iRetval = ::MessageBox( _hDlg, _pszMsg, _pszTitle, _uFlags );
  173. EndDialog( _hDlg, IDOK );
  174. break;
  175. case WM_HELP:
  176. bStatus = ( _pCallback ) ? _pCallback( _hDlg, _pRefData ) : FALSE;
  177. break;
  178. default:
  179. bStatus = FALSE;
  180. break;
  181. }
  182. return bStatus;
  183. }
  184. INT_PTR APIENTRY TMessageBoxDialog::SetupDlgProc(IN HWND hDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)
  185. /*++
  186. Routine Description:
  187. Setup the wndproc and initialize GWL_USERDATA.
  188. Arguments:
  189. Standard wndproc parms.
  190. Return Value:
  191. --*/
  192. {
  193. BOOL bRet = FALSE;
  194. TMessageBoxDialog *pThis = NULL;
  195. if( WM_INITDIALOG == uMsg )
  196. {
  197. pThis = reinterpret_cast<TMessageBoxDialog*>(lParam);
  198. if( pThis )
  199. {
  200. pThis->_hDlg = hDlg;
  201. SetWindowLongPtr(hDlg, DWLP_USER, reinterpret_cast<LONG_PTR>(pThis));
  202. bRet = pThis->bHandleMessage(uMsg, wParam, lParam);
  203. }
  204. }
  205. else
  206. {
  207. pThis = reinterpret_cast<TMessageBoxDialog*>(GetWindowLongPtr(hDlg, DWLP_USER));
  208. if( pThis )
  209. {
  210. bRet = pThis->bHandleMessage(uMsg, wParam, lParam);
  211. if( WM_DESTROY == uMsg )
  212. {
  213. // our window is about to go away, so we need to cleanup DWLP_USER here
  214. SetWindowLongPtr(hDlg, DWLP_USER, 0);
  215. }
  216. }
  217. }
  218. return bRet;
  219. }