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.

506 lines
16 KiB

  1. /*
  2. * u t i l . c p p
  3. *
  4. * Purpose:
  5. *
  6. * History
  7. *
  8. * Copyright (C) Microsoft Corp. 1995, 1996.
  9. */
  10. #include <pch.hxx>
  11. #include <dllmain.h>
  12. #include <resource.h>
  13. #include "shared.h"
  14. #include "util.h"
  15. #include "mimeolep.h"
  16. #include <icutil.h>
  17. #include <strconst.h>
  18. #include "demand.h"
  19. extern BOOL g_fCanEditBiDi;
  20. INT_PTR CALLBACK BGSoundDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  21. //NOTE: if *ppstm == NULL, then the stream is created.
  22. //Otherwise it is written to.
  23. HRESULT HrLoadStreamFileFromResourceW(ULONG uCodePage, LPCSTR lpszResourceName, LPSTREAM *ppstm)
  24. {
  25. HRESULT hr=E_FAIL;
  26. HRSRC hres;
  27. HGLOBAL hGlobal;
  28. LPBYTE pb;
  29. DWORD cb;
  30. LPWSTR pszW=0;
  31. ULONG cchW;
  32. if (!ppstm || !lpszResourceName)
  33. return E_INVALIDARG;
  34. hres = FindResource(g_hLocRes, lpszResourceName, MAKEINTRESOURCE(RT_FILE));
  35. if (!hres)
  36. goto error;
  37. hGlobal = LoadResource(g_hLocRes, hres);
  38. if (!hGlobal)
  39. goto error;
  40. pb = (LPBYTE)LockResource(hGlobal);
  41. if (!pb)
  42. goto error;
  43. cb = SizeofResource(g_hLocRes, hres);
  44. if (!cb)
  45. goto error;
  46. cchW = (cb + 1);
  47. if (!MemAlloc ((LPVOID *)&pszW, sizeof(pszW[0]) * cchW))
  48. {
  49. hr = E_OUTOFMEMORY;
  50. goto error;
  51. }
  52. cchW = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, (LPSTR)pb, cb, pszW, cchW);
  53. if (cchW==0)
  54. goto error;
  55. if (*ppstm)
  56. hr = (*ppstm)->Write(pszW, cchW*sizeof(WCHAR), NULL);
  57. else
  58. {
  59. if (SUCCEEDED(hr = MimeOleCreateVirtualStream(ppstm)))
  60. hr = (*ppstm)->Write (pszW, cchW*sizeof(WCHAR), NULL);
  61. }
  62. error:
  63. SafeMemFree(pszW);
  64. return hr;
  65. }
  66. //
  67. // REVIEW: We need this function because current version of USER.EXE does
  68. // not support pop-up only menu.
  69. //
  70. HMENU LoadPopupMenu(UINT id)
  71. {
  72. HMENU hmenuParent = LoadMenu(g_hLocRes, MAKEINTRESOURCE(id));
  73. if (hmenuParent) {
  74. HMENU hpopup = GetSubMenu(hmenuParent, 0);
  75. RemoveMenu(hmenuParent, 0, MF_BYPOSITION);
  76. DestroyMenu(hmenuParent);
  77. return hpopup;
  78. }
  79. return NULL;
  80. }
  81. UINT_PTR TTIdFromCmdId(UINT_PTR idCmd)
  82. {
  83. if (idCmd >= IDM_FIRST && idCmd <= IDM_LAST)
  84. idCmd += TT_BASE;
  85. else
  86. idCmd = 0;
  87. return(idCmd);
  88. }
  89. // --------------------
  90. //
  91. // ProcessTooltips:
  92. //
  93. // This function is used to process tooltips text notification.
  94. //
  95. // --------------------
  96. void ProcessTooltips(LPTOOLTIPTEXTOE lpttt)
  97. {
  98. if (lpttt->lpszText = MAKEINTRESOURCE(TTIdFromCmdId(lpttt->hdr.idFrom)))
  99. lpttt->hinst = g_hLocRes;
  100. else
  101. lpttt->hinst = NULL;
  102. }
  103. #define DEFAULT_FONTSIZE 2
  104. INT PointSizeToHTMLSize(INT iPointSize)
  105. {
  106. INT iHTMLSize;
  107. // 1 ----- 8
  108. // 2 ----- 10
  109. // 3 ----- 12
  110. // 4 ----- 14
  111. // 5 ----- 18
  112. // 6 ----- 24
  113. // 7 ----- 36
  114. if(iPointSize>=8 && iPointSize<9)
  115. iHTMLSize = 1;
  116. else if(iPointSize>=9 && iPointSize<12)
  117. iHTMLSize = 2;
  118. else if(iPointSize>=12 && iPointSize<14)
  119. iHTMLSize = 3;
  120. else if(iPointSize>=14 && iPointSize<18)
  121. iHTMLSize = 4;
  122. else if(iPointSize>=18 && iPointSize<24)
  123. iHTMLSize = 5;
  124. else if(iPointSize>=24 && iPointSize<36)
  125. iHTMLSize = 6;
  126. else if(iPointSize>=36)
  127. iHTMLSize = 7;
  128. else
  129. iHTMLSize = DEFAULT_FONTSIZE;
  130. return iHTMLSize;
  131. }
  132. HRESULT DoBackgroundSoundDlg(HWND hwnd, PBGSOUNDDLG pBGSoundDlg)
  133. {
  134. if (DialogBoxParamWrapW(g_hLocRes, MAKEINTRESOURCEW(iddBackSound), hwnd, BGSoundDlgProc, (LPARAM)pBGSoundDlg)==IDOK)
  135. return S_OK;
  136. return E_FAIL;
  137. }
  138. static const HELPMAP g_rgBGSoundHlp[] =
  139. {
  140. {ideSoundLoc, 50180},
  141. {idbtnBrowseSound, 50185},
  142. {idrbPlayNTimes, 50190},
  143. {idePlayCount, 50190},
  144. {IDC_SPIN1, 50190},
  145. {idrbPlayInfinite, 50195},
  146. {0, 0}
  147. };
  148. INT_PTR CALLBACK BGSoundDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  149. {
  150. PBGSOUNDDLG pBGSoundDlg;
  151. WCHAR wsz[10];
  152. OPENFILENAMEW ofn;
  153. WCHAR wszTitle[CCHMAX_STRINGRES],
  154. wszFilter[CCHMAX_STRINGRES],
  155. wszFile[MAX_PATH],
  156. wszInitialDir[MAX_PATH];
  157. LPCWSTR wszMediaDir = L"\\Media";
  158. LPWSTR pwszFile = NULL;;
  159. UINT rc;
  160. switch (uMsg)
  161. {
  162. case WM_INITDIALOG:
  163. pBGSoundDlg = (PBGSOUNDDLG)lParam;
  164. Assert (pBGSoundDlg);
  165. SendMessage(GetDlgItem(hwnd, ideSoundLoc), EM_SETLIMITTEXT, MAX_PATH-1, 0);
  166. SendMessage(GetDlgItem(hwnd, idePlayCount), EM_SETLIMITTEXT, 3, 0);
  167. SetWindowTextWrapW(GetDlgItem(hwnd, ideSoundLoc), pBGSoundDlg->wszUrl);
  168. wnsprintfW(wsz, ARRAYSIZE(wsz), L"%d", max(pBGSoundDlg->cRepeat, 1));
  169. SetWindowTextWrapW(GetDlgItem(hwnd, idePlayCount), wsz);
  170. CheckRadioButton(hwnd, idrbPlayNTimes, idrbPlayInfinite, pBGSoundDlg->cRepeat==-1 ? idrbPlayInfinite:idrbPlayNTimes);
  171. SendDlgItemMessage(hwnd, IDC_SPIN1, UDM_SETRANGE, 0, MAKELONG(999, 1));
  172. SetWindowLongPtr(hwnd, DWLP_USER, lParam);
  173. break;
  174. case WM_HELP:
  175. case WM_CONTEXTMENU:
  176. return OnContextHelp(hwnd, uMsg, wParam, lParam, g_rgBGSoundHlp);
  177. case WM_COMMAND:
  178. switch (LOWORD(wParam))
  179. {
  180. case idrbPlayInfinite:
  181. case idrbPlayNTimes:
  182. EnableWindow(GetDlgItem(hwnd, idePlayCount), LOWORD(wParam)==idrbPlayNTimes);
  183. break;
  184. case idbtnBrowseSound:
  185. *wszFile=0;
  186. *wszFilter=0;
  187. *wszTitle=0;
  188. LoadStringWrapW(g_hLocRes, idsFilterAudio, wszFilter, ARRAYSIZE(wszFilter));
  189. ReplaceCharsW(wszFilter, L'|', L'\0');
  190. ZeroMemory(&ofn, sizeof(ofn));
  191. ofn.lStructSize = sizeof(ofn);
  192. ofn.hwndOwner = hwnd;
  193. ofn.lpstrFile = wszFile;
  194. ofn.lpstrFilter = wszFilter;
  195. LoadStringWrapW(g_hLocRes, idsPickBGSound, wszTitle, ARRAYSIZE(wszTitle));
  196. ofn.lpstrTitle = wszTitle;
  197. ofn.nMaxFile = ARRAYSIZE(wszFile);
  198. ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_NONETWORKBUTTON|OFN_NOCHANGEDIR;
  199. // begin added for BUG 29778
  200. rc = GetWindowsDirectoryWrapW(wszInitialDir, ARRAYSIZE(wszInitialDir));
  201. if( rc > ARRAYSIZE(wszInitialDir))
  202. {
  203. // if cannot copy entire windows dir path then punt and default to desktop
  204. *wszInitialDir = 0;
  205. }
  206. else
  207. {
  208. if (!StrCatBuffW(wszInitialDir, wszMediaDir, ARRAYSIZE(wszInitialDir)))
  209. {
  210. // punt if can't concat
  211. *wszInitialDir = 0;
  212. }
  213. }
  214. ofn.lpstrInitialDir = wszInitialDir;
  215. // end added for BUG 29778
  216. if (HrAthGetFileNameW(&ofn, TRUE)==S_OK)
  217. SetWindowTextWrapW(GetDlgItem(hwnd, ideSoundLoc), wszFile);
  218. return TRUE;
  219. case IDOK:
  220. pBGSoundDlg = (PBGSOUNDDLG)GetWindowLongPtr(hwnd, DWLP_USER);
  221. GetWindowTextWrapW(GetDlgItem(hwnd, ideSoundLoc), pBGSoundDlg->wszUrl, ARRAYSIZE(pBGSoundDlg->wszUrl));
  222. if (!IsValidFileIfFileUrlW(pBGSoundDlg->wszUrl) &&
  223. AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsBgSound), MAKEINTRESOURCEW(idsErrBgSoundFileBad), NULL, MB_YESNO|MB_DEFBUTTON2)==IDNO)
  224. break;
  225. pBGSoundDlg->cRepeat=1;
  226. if (IsDlgButtonChecked(hwnd, idrbPlayNTimes))
  227. {
  228. GetWindowTextWrapW(GetDlgItem(hwnd, idePlayCount), wsz, ARRAYSIZE(wsz));
  229. pBGSoundDlg->cRepeat = StrToIntW(wsz);
  230. if (pBGSoundDlg->cRepeat <= 0 || pBGSoundDlg->cRepeat > 999)
  231. {
  232. AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsBgSound), MAKEINTRESOURCEW(idsErrBgSoundLoopRange), NULL, MB_OK);
  233. break;
  234. }
  235. }
  236. else
  237. pBGSoundDlg->cRepeat=-1; //infinite
  238. // fall thro'
  239. case IDCANCEL:
  240. EndDialog(hwnd, LOWORD(wParam));
  241. return TRUE;
  242. }
  243. break;
  244. }
  245. return FALSE;
  246. }
  247. static const HELPMAP g_rgFmtParaHlp[] =
  248. {
  249. {idmFmtLeft, 50200},
  250. {idmFmtRight, 50200},
  251. {idmFmtCenter, 50200},
  252. {idmFmtJustify, 50200},
  253. {idmFmtNumbers, 50205},
  254. {idmFmtBullets, 50205},
  255. {idmFmtBulletsNone, 50205},
  256. {0, 0}
  257. };
  258. INT_PTR CALLBACK FmtParaDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  259. {
  260. int id, i;
  261. LPPARAPROP pParaProp;
  262. pParaProp = (LPPARAPROP)GetWindowLongPtr(hwnd, DWLP_USER);
  263. switch(msg)
  264. {
  265. case WM_INITDIALOG:
  266. {
  267. Assert(lParam!= NULL);
  268. SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)lParam);
  269. pParaProp = (LPPARAPROP)lParam;
  270. CenterDialog(hwnd);
  271. // Bug 96520
  272. // if we are in plain text mode then paragraph format should be set to left
  273. if(!(pParaProp->group[0].iID))
  274. pParaProp->group[0].iID = idmFmtLeft;
  275. CheckRadioButton( hwnd, idmFmtLeft, idmFmtJustify, pParaProp->group[0].iID);
  276. CheckRadioButton( hwnd, idmFmtNumbers, idmFmtBulletsNone, pParaProp->group[1].iID);
  277. CheckRadioButton( hwnd, idmFmtBlockDirLTR, idmFmtBlockDirRTL, pParaProp->group[2].iID);
  278. if (!g_fCanEditBiDi)
  279. {
  280. ShowWindow(GetDlgItem(hwnd, idmFmtBlockDirRTL), SW_HIDE);
  281. ShowWindow(GetDlgItem(hwnd, idmFmtBlockDirLTR), SW_HIDE);
  282. ShowWindow(GetDlgItem(hwnd, IDC_STATIC1), SW_HIDE);
  283. ShowWindow(GetDlgItem(hwnd, IDC_STATIC2), SW_HIDE);
  284. }
  285. }
  286. return(TRUE);
  287. case WM_HELP:
  288. case WM_CONTEXTMENU:
  289. return OnContextHelp(hwnd, msg, wParam, lParam, g_rgFmtParaHlp);
  290. case WM_COMMAND:
  291. switch(id=GET_WM_COMMAND_ID(wParam, lParam))
  292. {
  293. case idmFmtBlockDirLTR:
  294. case idmFmtBlockDirRTL:
  295. // Dir Attribute implies alignment
  296. CheckRadioButton( hwnd, idmFmtLeft, idmFmtRight, id == idmFmtBlockDirLTR ? idmFmtLeft : idmFmtRight);
  297. break;
  298. case IDOK:
  299. for (i = 0; i < 4; i++)
  300. {
  301. if(IsDlgButtonChecked(hwnd, idmFmtLeft + i) == BST_CHECKED)
  302. {
  303. pParaProp->group[0].bChanged = !(pParaProp->group[0].iID - (idmFmtLeft + i) == 0);
  304. pParaProp->group[0].iID = idmFmtLeft + i;
  305. }
  306. }
  307. for (i = 0; i < 2; i++)
  308. {
  309. if(IsDlgButtonChecked(hwnd, idmFmtNumbers + i) == BST_CHECKED)
  310. {
  311. pParaProp->group[1].bChanged = !(pParaProp->group[1].iID - (idmFmtNumbers + i) == 0);
  312. pParaProp->group[1].iID = idmFmtNumbers + i;
  313. }
  314. }
  315. // Bullets and Numbers are flip flops, let's force a change if the user selscts none
  316. // leaving the same previous ID
  317. if(IsDlgButtonChecked(hwnd, idmFmtBulletsNone) == BST_CHECKED)
  318. {
  319. pParaProp->group[1].bChanged = TRUE;
  320. }
  321. if (g_fCanEditBiDi)
  322. {
  323. for (i = 0; i < 2; i++)
  324. {
  325. if(IsDlgButtonChecked(hwnd, idmFmtBlockDirLTR + i) == BST_CHECKED)
  326. {
  327. pParaProp->group[2].bChanged = !(pParaProp->group[2].iID - (idmFmtBlockDirLTR + i) == 0);
  328. pParaProp->group[2].iID = idmFmtBlockDirLTR + i;
  329. }
  330. }
  331. }
  332. // fall thro'
  333. case IDCANCEL:
  334. EndDialog(hwnd, id);
  335. break;
  336. }
  337. break;
  338. }
  339. return FALSE;
  340. }
  341. BOOL CanEditBiDi(void)
  342. {
  343. UINT cNumkeyboards = 0, i;
  344. HKL* phKeyboadList = NULL;
  345. BOOL fBiDiKeyBoard = FALSE;
  346. // Let's check how many keyboard the system has
  347. cNumkeyboards = GetKeyboardLayoutList(0, phKeyboadList);
  348. phKeyboadList = (HKL*)LocalAlloc(LPTR, cNumkeyboards * sizeof(HKL));
  349. cNumkeyboards = GetKeyboardLayoutList(cNumkeyboards, phKeyboadList);
  350. for (i = 0; i < cNumkeyboards; i++)
  351. {
  352. LANGID LangID = PRIMARYLANGID(LANGIDFROMLCID(LOWORD(phKeyboadList[i])));
  353. if( LangID == LANG_ARABIC
  354. ||LangID == LANG_HEBREW
  355. ||LangID == LANG_FARSI)
  356. {
  357. fBiDiKeyBoard = TRUE;
  358. break;
  359. }
  360. }
  361. if(phKeyboadList)
  362. {
  363. LocalFree((HLOCAL)phKeyboadList);
  364. }
  365. return fBiDiKeyBoard;
  366. }
  367. BOOL OnContextHelp(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, HELPMAP const * rgCtxMap)
  368. {
  369. if (uMsg == WM_HELP)
  370. {
  371. LPHELPINFO lphi = (LPHELPINFO) lParam;
  372. if (lphi->iContextType == HELPINFO_WINDOW) // must be for a control
  373. {
  374. OEWinHelp ((HWND)lphi->hItemHandle,
  375. c_szCtxHelpFile,
  376. HELP_WM_HELP,
  377. (DWORD_PTR)(LPVOID)rgCtxMap);
  378. }
  379. return (TRUE);
  380. }
  381. else if (uMsg == WM_CONTEXTMENU)
  382. {
  383. OEWinHelp ((HWND) wParam,
  384. c_szCtxHelpFile,
  385. HELP_CONTEXTMENU,
  386. (DWORD_PTR)(LPVOID)rgCtxMap);
  387. return (TRUE);
  388. }
  389. Assert(0);
  390. return FALSE;
  391. }
  392. BOOL CALLBACK AthFixDialogFontsProc(HWND hChild, LPARAM lParam){
  393. HFONT hFont = (HFONT)lParam;
  394. if(hFont)
  395. SendMessage(hChild, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
  396. else
  397. return FALSE;
  398. return TRUE;
  399. }
  400. HRESULT AthFixDialogFonts(HWND hwndDlg)
  401. {
  402. HFONT hFont = NULL;
  403. if(!IsWindow(hwndDlg))
  404. return E_INVALIDARG;
  405. if((FAILED(g_lpIFontCache->GetFont(FNT_SYS_ICON, NULL, &hFont))) || (!hFont))
  406. return E_FAIL;
  407. EnumChildWindows(hwndDlg, AthFixDialogFontsProc, (LPARAM)hFont);
  408. return S_OK;
  409. }
  410. //
  411. // If you are calling this function and you use the result to draw text, you
  412. // must use a function that supports font substitution (DrawTextWrapW, ExtTextOutWrapW).
  413. //
  414. BOOL GetTextExtentPoint32AthW(HDC hdc, LPCWSTR lpwString, int cchString, LPSIZE lpSize, DWORD dwFlags)
  415. {
  416. RECT rect = {0};
  417. int rc;
  418. rc = DrawTextWrapW(hdc, lpwString, cchString, &rect, DT_CALCRECT | dwFlags);
  419. lpSize->cx = rect.right - rect.left + 1;
  420. lpSize->cy = rect.bottom - rect.top + 1;
  421. return((BOOL)rc);
  422. }