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.

232 lines
6.2 KiB

  1. //
  2. // SHMessageBoxHelp implementation
  3. //
  4. // History
  5. // 01/14/00 dsheldon created
  6. //
  7. #include "priv.h"
  8. #include "ids.h"
  9. #include <htmlhelp.h>
  10. HRESULTHELPMAPPING g_prghhmShellDefault[] =
  11. {
  12. {HRESULT_FROM_WIN32(ERROR_NO_NETWORK), "tshoot00.chm>windefault", "w0networking.htm" },
  13. };
  14. class CHelpMessageBox
  15. {
  16. public:
  17. CHelpMessageBox(HRESULTHELPMAPPING* prghhm, DWORD chhm);
  18. int DoHelpMessageBox(HWND hwndParent, LPCWSTR pszText, LPCWSTR pszCaption, UINT uType, HRESULT hrErr);
  19. private:
  20. int DisplayMessageBox(HWND hwnd, LPCWSTR pszText, LPCWSTR pszCaption, UINT uType);
  21. HRESULTHELPMAPPING* GetHResultHelpMapping(HRESULT hrErr, HRESULTHELPMAPPING* prghhm, DWORD chhm);
  22. static INT_PTR CALLBACK StaticDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  23. INT_PTR CALLBACK DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  24. // Data
  25. HRESULTHELPMAPPING* _prghhm;
  26. DWORD _chhm;
  27. HRESULTHELPMAPPING* _phhmEntry;
  28. LPCWSTR _pszText;
  29. LPCWSTR _pszCaption;
  30. UINT _uType;
  31. };
  32. CHelpMessageBox::CHelpMessageBox(HRESULTHELPMAPPING* prghhm, DWORD chhm)
  33. {
  34. // Initialize class members
  35. _phhmEntry = NULL;
  36. _prghhm = prghhm;
  37. _chhm = chhm;
  38. }
  39. int CHelpMessageBox::DisplayMessageBox(HWND hwnd, LPCWSTR pszText, LPCWSTR pszCaption, UINT uType)
  40. {
  41. LPWSTR pszAllocString = NULL;
  42. if (NULL != _phhmEntry)
  43. {
  44. uType |= MB_HELP;
  45. // Need to add the "For more information, click help." string.
  46. WCHAR szMoreInfo[256];
  47. if (LoadStringW(HINST_THISDLL, IDS_CLICKHELPFORINFO, szMoreInfo, ARRAYSIZE(szMoreInfo)))
  48. {
  49. DWORD cchText = lstrlenW(pszText);
  50. // The 3 here are for '\n', '\n', '\0'
  51. DWORD cchBuffer = cchText + lstrlenW(szMoreInfo) + 3;
  52. pszAllocString = (LPWSTR) LocalAlloc(0, cchBuffer * sizeof (WCHAR));
  53. if (pszAllocString)
  54. {
  55. StringCchPrintfW(pszAllocString, cchBuffer, L"%s\n\n%s", pszText, szMoreInfo);
  56. }
  57. }
  58. }
  59. else
  60. {
  61. // No help topic mapping for this error
  62. TraceMsg(TF_WARNING, "No help topic mapping for this error. Removing help button.");
  63. uType &= (~MB_HELP);
  64. }
  65. int iReturn = MessageBoxW(hwnd, pszAllocString ? pszAllocString : pszText, pszCaption, uType);
  66. if (pszAllocString)
  67. {
  68. LocalFree(pszAllocString);
  69. }
  70. return iReturn;
  71. }
  72. HRESULTHELPMAPPING* CHelpMessageBox::GetHResultHelpMapping(HRESULT hrErr, HRESULTHELPMAPPING* prghhm, DWORD chhm)
  73. {
  74. HRESULTHELPMAPPING* phhm = NULL;
  75. for (DWORD i = 0; i < chhm; i++)
  76. {
  77. if (prghhm[i].hr == hrErr)
  78. {
  79. phhm = &(prghhm[i]);
  80. break;
  81. }
  82. }
  83. return phhm;
  84. }
  85. CHelpMessageBox::DoHelpMessageBox(HWND hwndParent, LPCWSTR pszText, LPCWSTR pszCaption, UINT uType, HRESULT hrErr)
  86. {
  87. int iReturn = 0;
  88. _pszText = pszText;
  89. _pszCaption = pszCaption;
  90. _uType = uType;
  91. // Find the index of the help topic matching the hresult
  92. // First search the mapping the user passed in, if present
  93. if (NULL != _prghhm)
  94. {
  95. _phhmEntry = GetHResultHelpMapping(hrErr, _prghhm, _chhm);
  96. }
  97. // If we didn't find a mapping in the caller's list, search the shell's global list
  98. if (NULL == _phhmEntry)
  99. {
  100. _phhmEntry = GetHResultHelpMapping(hrErr, g_prghhmShellDefault, ARRAYSIZE(g_prghhmShellDefault));
  101. }
  102. ULONG_PTR ul;
  103. HANDLE h = CreateAndActivateContext(&ul);
  104. iReturn = (int) DialogBoxParam(HINST_THISDLL, MAKEINTRESOURCE(DLG_NULL), hwndParent, StaticDlgProc, (LPARAM) this);
  105. DeactivateAndDestroyContext(h, ul);
  106. return iReturn;
  107. }
  108. INT_PTR CHelpMessageBox::StaticDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  109. {
  110. CHelpMessageBox* pthis = NULL;
  111. if (uMsg == WM_INITDIALOG)
  112. {
  113. pthis = (CHelpMessageBox*) lParam;
  114. SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) pthis);
  115. }
  116. else
  117. {
  118. pthis = (CHelpMessageBox*) GetWindowLongPtr(hwnd, DWLP_USER);
  119. }
  120. if (NULL != pthis)
  121. {
  122. return pthis->DlgProc(hwnd, uMsg, wParam, lParam);
  123. }
  124. return 0;
  125. }
  126. INT_PTR CHelpMessageBox::DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  127. {
  128. INT_PTR iReturn = FALSE;
  129. switch (uMsg)
  130. {
  131. case WM_INITDIALOG:
  132. // Launch Messagebox
  133. {
  134. int i = DisplayMessageBox(hwnd, _pszText, _pszCaption, _uType);
  135. EndDialog(hwnd, i);
  136. }
  137. iReturn = TRUE;
  138. break;
  139. case WM_HELP:
  140. // Call the appropriate help topic
  141. ASSERT(_phhmEntry != NULL);
  142. HtmlHelpA(
  143. hwnd,
  144. _phhmEntry->szHelpFile,
  145. HH_DISPLAY_TOPIC,
  146. (DWORD_PTR) _phhmEntry->szHelpTopic);
  147. break;
  148. default:
  149. break;
  150. }
  151. return iReturn;
  152. }
  153. STDAPI_(int) SHMessageBoxHelpA(HWND hwnd,
  154. LPCSTR pszText,
  155. LPCSTR pszCaption,
  156. UINT uType,
  157. HRESULT hrErr,
  158. HRESULTHELPMAPPING* prghhm,
  159. DWORD chhm)
  160. {
  161. WCHAR szTextW[1024];
  162. WCHAR szCaptionW[256];
  163. CHelpMessageBox parent(prghhm, chhm);
  164. if (!SHAnsiToUnicode(pszText, szTextW, ARRAYSIZE(szTextW)))
  165. {
  166. *szTextW = 0;
  167. }
  168. if (!SHAnsiToUnicode(pszCaption, szCaptionW, ARRAYSIZE(szCaptionW)))
  169. {
  170. *szCaptionW = 0;
  171. }
  172. return parent.DoHelpMessageBox(hwnd, szTextW, szCaptionW, uType, hrErr);
  173. }
  174. STDAPI_(int) SHMessageBoxHelpW(HWND hwnd,
  175. LPCWSTR pszText,
  176. LPCWSTR pszCaption,
  177. UINT uType,
  178. HRESULT hrErr,
  179. HRESULTHELPMAPPING* prghhm,
  180. DWORD chhm)
  181. {
  182. CHelpMessageBox parent(prghhm, chhm);
  183. return parent.DoHelpMessageBox(hwnd, pszText, pszCaption, uType, hrErr);
  184. }