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.

558 lines
14 KiB

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