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.

557 lines
14 KiB

  1. #ifndef _INC_MLUISUPP
  2. #define _INC_MLUISUPP
  3. #include <shlwapi.h>
  4. #include <shlwapip.h>
  5. #ifdef __cplusplus
  6. extern "C"
  7. {
  8. #endif
  9. //+------------------------------------------------------------------
  10. // Multilang Pluggable UI support
  11. // inline functions defs (to centralize code)
  12. //+------------------------------------------------------------------
  13. #ifdef UNICODE
  14. #define MLLoadString MLLoadStringW
  15. #define MLLoadShellLangString MLLoadShellLangStringW
  16. #define MLBuildResURLWrap MLBuildResURLWrapW
  17. #define MLLoadResources MLLoadResourcesW
  18. #define SHHtmlHelpOnDemandWrap SHHtmlHelpOnDemandWrapW
  19. #define SHWinHelpOnDemandWrap SHWinHelpOnDemandWrapW
  20. #else
  21. #define MLLoadString MLLoadStringA
  22. #define MLLoadShellLangString MLLoadShellLangStringA
  23. #define MLBuildResURLWrap MLBuildResURLWrapA
  24. #define MLLoadResources MLLoadResourcesA
  25. #define SHHtmlHelpOnDemandWrap SHHtmlHelpOnDemandWrapA
  26. #define SHWinHelpOnDemandWrap SHWinHelpOnDemandWrapA
  27. #endif
  28. void MLFreeResources(HINSTANCE hinstParent);
  29. HINSTANCE MLGetHinst();
  30. HINSTANCE MLLoadShellLangResources();
  31. #ifdef MLUI_MESSAGEBOX
  32. int MLShellMessageBox(HWND hWnd, LPCTSTR pszMsg, LPCTSTR pszTitle, UINT fuStyle, ...);
  33. #endif
  34. //
  35. // The following should be both A and W suffixed
  36. //
  37. int MLLoadStringA(UINT id, LPSTR sz, UINT cchMax);
  38. int MLLoadStringW(UINT id, LPWSTR sz, UINT cchMax);
  39. int MLLoadShellLangStringA(UINT id, LPSTR sz, UINT cchMax);
  40. int MLLoadShellLangStringW(UINT id, LPWSTR sz, UINT cchMax);
  41. HRESULT MLBuildResURLWrapA(LPSTR pszLibFile,
  42. HMODULE hModule,
  43. DWORD dwCrossCodePage,
  44. LPSTR pszResName,
  45. LPSTR pszResURL,
  46. int nBufSize,
  47. LPSTR pszParentDll);
  48. HRESULT MLBuildResURLWrapW(LPWSTR pszLibFile,
  49. HMODULE hModule,
  50. DWORD dwCrossCodePage,
  51. LPWSTR pszResName,
  52. LPWSTR pszResURL,
  53. int nBufSize,
  54. LPWSTR pszParentDll);
  55. void MLLoadResourcesA(HINSTANCE hinstParent, LPSTR pszLocResDll);
  56. void MLLoadResourcesW(HINSTANCE hinstParent, LPWSTR pszLocResDll);
  57. HWND SHHtmlHelpOnDemandWrapA(HWND hwndCaller, LPCSTR pszFile, UINT uCommand, DWORD_PTR dwData, DWORD dwCrossCodePage);
  58. HWND SHHtmlHelpOnDemandWrapW(HWND hwndCaller, LPCWSTR pszFile, UINT uCommand, DWORD_PTR dwData, DWORD dwCrossCodePage);
  59. BOOL SHWinHelpOnDemandWrapA(HWND hwndCaller, LPCSTR lpszHelp, UINT uCommand, DWORD_PTR dwData);
  60. BOOL SHWinHelpOnDemandWrapW(HWND hwndCaller, LPCWSTR lpszHelp, UINT uCommand, DWORD_PTR dwData);
  61. //
  62. // End of: The following should be both A and W suffixed
  63. //
  64. #ifdef MLUI_INIT
  65. // WARNING: do not attempt to access any of these members directly
  66. // these members may not be initialized until appropriate accessors
  67. // are called, for example hinstLocRes won't be intialized until
  68. // you call MLGetHinst()... so just call the accessor.
  69. struct tagMLUI_INFO
  70. {
  71. HINSTANCE hinstLocRes;
  72. HINSTANCE hinstParent;
  73. WCHAR szLocResDll[MAX_PATH];
  74. DWORD dwCrossCodePage;
  75. } g_mluiInfo;
  76. // REARCHITECT: These aren't thread safe... Do they need to be?
  77. //
  78. void MLLoadResourcesA(HINSTANCE hinstParent, LPSTR pszLocResDll)
  79. {
  80. #ifdef RIP
  81. RIP(hinstParent != NULL);
  82. RIP(pszLocResDll != NULL);
  83. #endif
  84. if (g_mluiInfo.hinstLocRes == NULL)
  85. {
  86. #ifdef MLUI_SUPPORT
  87. // plugUI: resource dll == ?
  88. // resource dll must be dynamically determined and loaded.
  89. // but we are NOT allowed to LoadLibrary during process attach.
  90. // therefore we cache the info we need and load later when
  91. // the first resource is requested.
  92. SHAnsiToUnicode(pszLocResDll, g_mluiInfo.szLocResDll, sizeof(g_mluiInfo.szLocResDll)/sizeof(g_mluiInfo.szLocResDll[0]));
  93. g_mluiInfo.hinstParent = hinstParent;
  94. g_mluiInfo.dwCrossCodePage = ML_CROSSCODEPAGE;
  95. #else
  96. // non-plugUI: resource dll == parent dll
  97. g_mluiInfo.hinstLocRes = hinstParent;
  98. #endif
  99. }
  100. }
  101. void MLLoadResourcesW(HINSTANCE hinstParent, LPWSTR pszLocResDll)
  102. {
  103. #ifdef RIP
  104. RIP(hinstParent != NULL);
  105. RIP(pszLocResDll != NULL);
  106. #endif
  107. if (g_mluiInfo.hinstLocRes == NULL)
  108. {
  109. #ifdef MLUI_SUPPORT
  110. // plugUI: resource dll == ?
  111. // resource dll must be dynamically determined and loaded.
  112. // but we are NOT allowed to LoadLibrary during process attach.
  113. // therefore we cache the info we need and load later when
  114. // the first resource is requested.
  115. StrCpyNW(g_mluiInfo.szLocResDll, pszLocResDll, sizeof(g_mluiInfo.szLocResDll)/sizeof(g_mluiInfo.szLocResDll[0]));
  116. g_mluiInfo.hinstParent = hinstParent;
  117. g_mluiInfo.dwCrossCodePage = ML_CROSSCODEPAGE;
  118. #else
  119. // non-plugUI: resource dll == parent dll
  120. g_mluiInfo.hinstLocRes = hinstParent;
  121. #endif
  122. }
  123. }
  124. void
  125. MLFreeResources(HINSTANCE hinstParent)
  126. {
  127. if (g_mluiInfo.hinstLocRes != NULL &&
  128. g_mluiInfo.hinstLocRes != hinstParent)
  129. {
  130. MLClearMLHInstance(g_mluiInfo.hinstLocRes);
  131. g_mluiInfo.hinstLocRes = NULL;
  132. }
  133. }
  134. // this is a private internal helper.
  135. // don't you dare call it from anywhere except at
  136. // the beginning of new ML* functions in this file
  137. __inline void
  138. _MLResAssure()
  139. {
  140. #ifdef MLUI_SUPPORT
  141. if(g_mluiInfo.hinstLocRes == NULL)
  142. {
  143. g_mluiInfo.hinstLocRes = MLLoadLibraryW(g_mluiInfo.szLocResDll,
  144. g_mluiInfo.hinstParent,
  145. g_mluiInfo.dwCrossCodePage);
  146. // we're guaranteed to at least have resources in the install language
  147. ASSERT(g_mluiInfo.hinstLocRes != NULL);
  148. }
  149. #endif
  150. }
  151. int
  152. MLLoadStringA(UINT id, LPSTR sz, UINT cchMax)
  153. {
  154. _MLResAssure();
  155. return LoadStringA(g_mluiInfo.hinstLocRes, id, sz, cchMax);
  156. }
  157. int
  158. MLLoadStringW(UINT id, LPWSTR sz, UINT cchMax)
  159. {
  160. _MLResAssure();
  161. return LoadStringWrapW(g_mluiInfo.hinstLocRes, id, sz, cchMax);
  162. }
  163. int
  164. MLLoadShellLangStringA(UINT id, LPSTR sz, UINT cchMax)
  165. {
  166. HINSTANCE hinstShellLangRes;
  167. int nRet;
  168. hinstShellLangRes = MLLoadShellLangResources();
  169. nRet = LoadStringA(hinstShellLangRes, id, sz, cchMax);
  170. MLFreeLibrary(hinstShellLangRes);
  171. return nRet;
  172. }
  173. int
  174. MLLoadShellLangStringW(UINT id, LPWSTR sz, UINT cchMax)
  175. {
  176. HINSTANCE hinstShellLangRes;
  177. int nRet;
  178. hinstShellLangRes = MLLoadShellLangResources();
  179. nRet = LoadStringWrapW(hinstShellLangRes, id, sz, cchMax);
  180. MLFreeLibrary(hinstShellLangRes);
  181. return nRet;
  182. }
  183. HINSTANCE
  184. MLGetHinst()
  185. {
  186. _MLResAssure();
  187. return g_mluiInfo.hinstLocRes;
  188. }
  189. HINSTANCE
  190. MLLoadShellLangResources()
  191. {
  192. HINSTANCE hinst;
  193. hinst = MLLoadLibraryW(g_mluiInfo.szLocResDll,
  194. g_mluiInfo.hinstParent,
  195. ML_SHELL_LANGUAGE);
  196. // we're guaranteed to at least have resources in the install language
  197. // unless we're 100% toasted
  198. return hinst;
  199. }
  200. #ifdef MLUI_MESSAGEBOX
  201. int MLShellMessageBox(HWND hWnd, LPCTSTR pszMsg, LPCTSTR pszTitle, UINT fuStyle, ...)
  202. {
  203. va_list vaList;
  204. int nRet = 0;
  205. LPTSTR pszFormattedMsg = NULL;
  206. TCHAR szTitleBuf[256];
  207. TCHAR szBuffer[1024];
  208. //
  209. // prepare the message
  210. //
  211. if (IS_INTRESOURCE(pszMsg))
  212. {
  213. if (MLLoadShellLangString(LOWORD((DWORD_PTR)pszMsg), szBuffer, ARRAYSIZE(szBuffer)))
  214. {
  215. pszMsg = szBuffer;
  216. }
  217. }
  218. if (!IS_INTRESOURCE(pszMsg) && // the string load might have failed
  219. pszMsg != NULL)
  220. {
  221. va_start(vaList, fuStyle);
  222. if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  223. pszMsg, 0, 0, (LPTSTR)&pszFormattedMsg, 0, &vaList))
  224. {
  225. pszMsg = pszFormattedMsg;
  226. }
  227. va_end(vaList);
  228. }
  229. //
  230. // prepare the title
  231. //
  232. if (!IS_INTRESOURCE(pszTitle) && pszTitle != NULL)
  233. {
  234. // do nothing
  235. }
  236. else if (pszTitle != NULL && MLLoadShellLangString(LOWORD((DWORD_PTR)pszTitle), szTitleBuf, ARRAYSIZE(szTitleBuf)))
  237. {
  238. pszTitle = szTitleBuf;
  239. }
  240. else if (hWnd && GetWindowText(hWnd, szTitleBuf, ARRAYSIZE(szTitleBuf)))
  241. {
  242. pszTitle = szTitleBuf;
  243. }
  244. else
  245. {
  246. pszTitle = TEXT("");
  247. }
  248. //
  249. // launch a MessageBox
  250. //
  251. #ifdef SHFUSION_H
  252. ULONG_PTR uCookie = 0;
  253. SHActivateContext(&uCookie);
  254. #endif
  255. nRet = MessageBox(hWnd, pszFormattedMsg, pszTitle, fuStyle | MB_SETFOREGROUND);
  256. #ifdef SHFUSION_H
  257. if (uCookie)
  258. {
  259. SHDeactivateContext(uCookie);
  260. }
  261. #endif
  262. if (pszFormattedMsg != NULL)
  263. {
  264. LocalFree(pszFormattedMsg);
  265. }
  266. return nRet;
  267. }
  268. #endif // MLUI_MESSAGEBOX
  269. #include "htmlhelp.h"
  270. HWND
  271. SHHtmlHelpOnDemandWrapA(HWND hwndCaller,
  272. LPCSTR pszFile,
  273. UINT uCommand,
  274. DWORD_PTR dwData,
  275. DWORD dwCrossCodePage)
  276. {
  277. BOOL fEnabled;
  278. ULONG_PTR uCookie = 0;
  279. HWND hwnd = NULL;
  280. #ifdef MLUI_SUPPORT
  281. fEnabled = TRUE;
  282. #else
  283. fEnabled = FALSE;
  284. #endif
  285. #ifdef SHFUSION_H
  286. SHActivateContext(&uCookie);
  287. #endif
  288. hwnd = SHHtmlHelpOnDemandA(hwndCaller,
  289. pszFile,
  290. uCommand,
  291. dwData,
  292. dwCrossCodePage,
  293. fEnabled);
  294. #ifdef SHFUSION_H
  295. if (uCookie)
  296. {
  297. SHDeactivateContext(uCookie);
  298. }
  299. #endif
  300. return hwnd;
  301. }
  302. HWND
  303. SHHtmlHelpOnDemandWrapW(HWND hwndCaller,
  304. LPCWSTR pszFile,
  305. UINT uCommand,
  306. DWORD_PTR dwData,
  307. DWORD dwCrossCodePage)
  308. {
  309. BOOL fEnabled;
  310. ULONG_PTR uCookie = 0;
  311. HWND hwnd = NULL;
  312. #ifdef MLUI_SUPPORT
  313. fEnabled = TRUE;
  314. #else
  315. fEnabled = FALSE;
  316. #endif
  317. #ifdef SHFUSION_H
  318. SHActivateContext(&uCookie);
  319. #endif
  320. hwnd = SHHtmlHelpOnDemandW(hwndCaller,
  321. pszFile,
  322. uCommand,
  323. dwData,
  324. dwCrossCodePage,
  325. fEnabled);
  326. #ifdef SHFUSION_H
  327. if (uCookie)
  328. {
  329. SHDeactivateContext(uCookie);
  330. }
  331. #endif
  332. return hwnd;
  333. }
  334. HWND
  335. MLHtmlHelpWrap(HWND hwndCaller,
  336. LPCTSTR pszFile,
  337. UINT uCommand,
  338. DWORD dwData,
  339. DWORD dwCrossCodePage)
  340. {
  341. HWND hwnd;
  342. ULONG_PTR uCookie = 0;
  343. #ifdef SHFUSION_H
  344. SHActivateContext(&uCookie);
  345. #endif
  346. #ifdef MLUI_SUPPORT
  347. hwnd = MLHtmlHelp(hwndCaller,
  348. pszFile,
  349. uCommand,
  350. dwData,
  351. dwCrossCodePage);
  352. #else
  353. hwnd = HtmlHelp(hwndCaller,
  354. pszFile,
  355. uCommand,
  356. dwData);
  357. #endif
  358. #ifdef SHFUSION_H
  359. if (uCookie)
  360. {
  361. SHDeactivateContext(uCookie);
  362. }
  363. #endif
  364. return hwnd;
  365. }
  366. BOOL
  367. SHWinHelpOnDemandWrapA(HWND hwndCaller,
  368. LPCSTR lpszHelp,
  369. UINT uCommand,
  370. DWORD_PTR dwData)
  371. {
  372. BOOL fEnabled;
  373. #ifdef MLUI_SUPPORT
  374. fEnabled = TRUE;
  375. #else
  376. fEnabled = FALSE;
  377. #endif
  378. return SHWinHelpOnDemandA(hwndCaller,
  379. lpszHelp,
  380. uCommand,
  381. dwData,
  382. fEnabled);
  383. }
  384. BOOL
  385. SHWinHelpOnDemandWrapW(HWND hwndCaller,
  386. LPCWSTR lpszHelp,
  387. UINT uCommand,
  388. DWORD_PTR dwData)
  389. {
  390. BOOL fEnabled;
  391. #ifdef MLUI_SUPPORT
  392. fEnabled = TRUE;
  393. #else
  394. fEnabled = FALSE;
  395. #endif
  396. return SHWinHelpOnDemandW(hwndCaller,
  397. lpszHelp,
  398. uCommand,
  399. dwData,
  400. fEnabled);
  401. }
  402. BOOL
  403. MLWinHelpWrap(HWND hwndCaller,
  404. LPCTSTR lpszHelp,
  405. UINT uCommand,
  406. DWORD dwData)
  407. {
  408. BOOL fRet;
  409. #ifdef MLUI_SUPPORT
  410. fRet = MLWinHelp(hwndCaller,
  411. lpszHelp,
  412. uCommand,
  413. dwData);
  414. #else
  415. fRet = WinHelp(hwndCaller,
  416. lpszHelp,
  417. uCommand,
  418. dwData);
  419. #endif
  420. return fRet;
  421. }
  422. HRESULT
  423. MLBuildResURLWrapA(LPSTR pszLibFile,
  424. HMODULE hModule,
  425. DWORD dwCrossCodePage,
  426. LPSTR pszResName,
  427. LPSTR pszResURL,
  428. int nBufSize,
  429. LPSTR pszParentDll)
  430. {
  431. HRESULT hr;
  432. #ifdef MLUI_SUPPORT
  433. hr = MLBuildResURLA(pszLibFile,
  434. hModule,
  435. dwCrossCodePage,
  436. pszResName,
  437. pszResURL,
  438. nBufSize);
  439. #else
  440. wnsprintfA(pszResURL, nBufSize, "res://%s/%s", pszParentDll, pszResName);
  441. hr = S_OK;
  442. #endif
  443. return hr;
  444. }
  445. HRESULT
  446. MLBuildResURLWrapW(LPWSTR pszLibFile,
  447. HMODULE hModule,
  448. DWORD dwCrossCodePage,
  449. LPWSTR pszResName,
  450. LPWSTR pszResURL,
  451. int nBufSize,
  452. LPWSTR pszParentDll)
  453. {
  454. HRESULT hr;
  455. #ifdef MLUI_SUPPORT
  456. hr = MLBuildResURLW(pszLibFile,
  457. hModule,
  458. dwCrossCodePage,
  459. pszResName,
  460. pszResURL,
  461. nBufSize);
  462. #else
  463. wnsprintfW(pszResURL, nBufSize, L"res://%s/%s", pszParentDll, pszResName);
  464. hr = S_OK;
  465. #endif
  466. return hr;
  467. }
  468. #endif // MLUI_INIT
  469. #ifdef __cplusplus
  470. };
  471. #endif
  472. #endif // _INC_MLUISUPP