Source code of Windows XP (NT5)
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.

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