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.

1794 lines
58 KiB

  1. //
  2. // FONTS.C - Selecting character set default fonts dialog
  3. //
  4. // Copyright(c) Microsoft Corp., 1996 All rights reserved.
  5. //
  6. // History:
  7. // 7/11/96 t-gpease trashed old International subdialog to create the new
  8. // improved codepage compatiable Fonts dialog.
  9. // WAS
  10. //
  11. // INTL.C - international dialog proc for inetcpl applet.
  12. //
  13. // Copyright(c) Microsoft Corp., 1996 All rights reserved.
  14. //
  15. // HISTORY:
  16. // 2/2/96 yutakan created.
  17. // 2/6/96 yutakan ported most of functions from IE2.0i.
  18. // 8/20/98 weiwu add script base font dialog proc (UNICODE version only)
  19. #include "inetcplp.h"
  20. #include <mlang.h>
  21. #include <mluisupp.h>
  22. #ifdef UNIX
  23. #include <mainwin.h>
  24. #endif /*UNIX */
  25. // Used for window property to remember the font created
  26. static const TCHAR c_szPropDlgFont[] = TEXT("DefaultDlgFont");
  27. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  28. #ifdef UNICODE
  29. PMIMECPINFO g_pCPInfo = NULL;
  30. #else
  31. PMIMECPINFO g_pCPInfoW = NULL;
  32. typedef struct tagMIMECPINFOA
  33. {
  34. DWORD dwFlags;
  35. UINT uiCodePage;
  36. UINT uiFamilyCodePage;
  37. CHAR wszDescription[MAX_MIMECP_NAME]; // NOTE:
  38. CHAR wszWebCharset[MAX_MIMECSET_NAME]; // To make it simple, it has wsz
  39. CHAR wszHeaderCharset[MAX_MIMECSET_NAME]; // prefix even though it's CHAR. So,
  40. CHAR wszBodyCharset[MAX_MIMECSET_NAME]; // we don't need to put #ifdef UNICODE
  41. CHAR wszFixedWidthFont[MAX_MIMEFACE_NAME]; // in below code anymore except
  42. CHAR wszProportionalFont[MAX_MIMEFACE_NAME]; // conversion time.
  43. BYTE bGDICharset;
  44. } MIMECPINFOA, *PMIMECPINFOA;
  45. PMIMECPINFOA g_pCPInfo = NULL;
  46. #endif
  47. ULONG g_cCPInfo = 0;
  48. ULONG g_cSidInfo = 0;
  49. IMLangFontLink2 *g_pMLFlnk2 = NULL;
  50. typedef HRESULT (* PCOINIT) (LPVOID);
  51. typedef VOID (* PCOUNINIT) (VOID);
  52. typedef VOID (* PCOMEMFREE) (LPVOID);
  53. typedef HRESULT (* PCOCREINST) (REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID * );
  54. extern HMODULE hOLE32;
  55. extern PCOINIT pCoInitialize;
  56. extern PCOUNINIT pCoUninitialize;
  57. extern PCOMEMFREE pCoTaskMemFree;
  58. extern PCOCREINST pCoCreateInstance;
  59. BOOL _StartOLE32();
  60. #define IsVerticalFont(p) (*(p) == '@')
  61. typedef struct {
  62. TCHAR szPropFont[MAX_MIMEFACE_NAME];
  63. TCHAR szFixedFont[MAX_MIMEFACE_NAME];
  64. TCHAR szFriendlyName[MAX_MIMECP_NAME];
  65. TCHAR szMIMEFont[MAX_MIMECP_NAME];
  66. DWORD dwFontSize;
  67. } CODEPAGEDATA;
  68. typedef struct {
  69. HWND hDlg;
  70. HWND hwndPropCB;
  71. HWND hwndFixedCB;
  72. HWND hwndSizeCB;
  73. HWND hwndMIMECB;
  74. HWND hwndNamesLB;
  75. DWORD dwDefaultCodePage;
  76. BOOL bChanged;
  77. CODEPAGEDATA *page;
  78. LPCTSTR lpszKeyPath;
  79. } FONTSDATA, *LPFONTSDATA;
  80. typedef struct {
  81. HWND hDlg;
  82. HWND hwndPropLB;
  83. HWND hwndFixedLB;
  84. HWND hwndNamesCB;
  85. SCRIPT_ID sidDefault;
  86. BOOL bChanged;
  87. PSCRIPTINFO pSidInfo;
  88. LPCTSTR lpszKeyPath;
  89. } FONTSCRIPTDATA, *LPFONTSCRIPTDATA;
  90. const struct {
  91. SCRIPT_ID Sid;
  92. BYTE nCharSet;
  93. UINT uiCp;
  94. } g_CharSetTransTable[] =
  95. {
  96. sidAsciiLatin, ANSI_CHARSET, 1252,
  97. sidLatin, ANSI_CHARSET, 1252,
  98. sidCyrillic, RUSSIAN_CHARSET, 1251,
  99. sidGreek, GREEK_CHARSET, 1253,
  100. sidHebrew, HEBREW_CHARSET, 1255,
  101. sidArabic, ARABIC_CHARSET, 1256,
  102. sidThai, THAI_CHARSET, 874,
  103. sidKana, SHIFTJIS_CHARSET, 932,
  104. sidHan, GB2312_CHARSET, 936,
  105. sidBopomofo, CHINESEBIG5_CHARSET,950,
  106. sidHangul, HANGEUL_CHARSET, 949,
  107. };
  108. //
  109. // Map script ID to charset
  110. // We should use MLang service when it is available
  111. //
  112. BYTE CharSetFromSid(SCRIPT_ID Sid)
  113. {
  114. for (int i=0; i<ARRAYSIZE(g_CharSetTransTable); i++)
  115. {
  116. if (Sid == g_CharSetTransTable[i].Sid)
  117. return g_CharSetTransTable[i].nCharSet;
  118. }
  119. return DEFAULT_CHARSET;
  120. }
  121. // SHLWAPI StrCmp/StrCmpI doesn't work.
  122. // Make this simple function to tell if string is equal in character value
  123. BOOL IsStringEqual(LPCTSTR lpString1, LPCTSTR lpString2)
  124. {
  125. if (lstrlen(lpString1) != lstrlen(lpString2))
  126. return FALSE;
  127. while(*lpString1 && *lpString2)
  128. {
  129. if (*lpString1 != *lpString2)
  130. {
  131. return FALSE;
  132. }
  133. lpString1++;
  134. lpString2++;
  135. }
  136. return TRUE;
  137. }
  138. //
  139. // Initialize script table with resource string
  140. //
  141. BOOL InitScriptTable(LPFONTSCRIPTDATA pFnt)
  142. {
  143. HRESULT hr;
  144. BOOL bRet = FALSE;
  145. IMultiLanguage2 * pML2;
  146. ASSERT(IS_VALID_CODE_PTR(pCoInitialize, PCOINIT));
  147. ASSERT(IS_VALID_CODE_PTR(pCoUninitialize, PCOUNINIT));
  148. ASSERT(IS_VALID_CODE_PTR(pCoTaskMemFree, PCOMEMFREE));
  149. ASSERT(IS_VALID_CODE_PTR(pCoCreateInstance, PCOCREINST));
  150. hr = pCoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage2, (LPVOID *) &pML2);
  151. if (SUCCEEDED(hr))
  152. {
  153. hr = pML2->QueryInterface(IID_IMLangFontLink2, (LPVOID *) &g_pMLFlnk2);
  154. if (SUCCEEDED(hr))
  155. {
  156. IEnumScript *pEnumScript;
  157. if (SUCCEEDED(pML2->EnumScripts(SCRIPTCONTF_SCRIPT_USER, INETCPL_GetUILanguage(), &pEnumScript)))
  158. {
  159. UINT cNum = 0;
  160. pML2->GetNumberOfScripts(&cNum);
  161. pFnt->pSidInfo = (PSCRIPTINFO)LocalAlloc(LPTR, sizeof(SCRIPTINFO) * cNum);
  162. if (NULL != pFnt->pSidInfo)
  163. {
  164. hr = pEnumScript->Next(cNum, pFnt->pSidInfo, &g_cSidInfo);
  165. if (SUCCEEDED(hr))
  166. {
  167. bRet = TRUE;
  168. }
  169. else
  170. {
  171. LocalFree(pFnt->pSidInfo);
  172. pFnt->pSidInfo = NULL;
  173. }
  174. }
  175. pEnumScript->Release();
  176. }
  177. }
  178. if (pML2)
  179. pML2->Release();
  180. }
  181. return bRet;
  182. }
  183. //
  184. // DrawSampleString()
  185. //
  186. // Draw the sample string with current font
  187. //
  188. void DrawSampleString(LPFONTSDATA pFnt, int idSample, LPCTSTR lpFace, SCRIPT_ID ScriptId)
  189. {
  190. HDC hDC;
  191. HFONT hFont, hTemp;
  192. LOGFONT lf = {0};
  193. DWORD rgbText, rgbBack;
  194. RECT rc;
  195. SIZE TextExtent;
  196. TEXTMETRIC tm;
  197. int len, x, y;
  198. TCHAR szFontSample[1024];
  199. if (!lpFace)
  200. return;
  201. MLLoadString(IDS_FONT_SAMPLE_DEFAULT+ScriptId, szFontSample, ARRAYSIZE(szFontSample));
  202. GetWindowRect(GetDlgItem(pFnt->hDlg, idSample), &rc);
  203. // Use MapWindowPoints() as it works for mirrored windows as well.
  204. MapWindowRect(NULL, pFnt->hDlg, &rc);
  205. // ScreenToClient(pFnt->hDlg, (LPPOINT)&rc.left);
  206. // ScreenToClient(pFnt->hDlg, (LPPOINT)&rc.right);
  207. hDC = GetDC(pFnt->hDlg);
  208. rgbBack = SetBkColor(hDC, GetSysColor(COLOR_3DFACE));
  209. rgbText = GetSysColor(COLOR_WINDOWTEXT);
  210. rgbText = SetTextColor(hDC, rgbText);
  211. hFont = GetWindowFont(pFnt->hDlg);
  212. GetObject(hFont, sizeof(LOGFONT), &lf);
  213. lf.lfCharSet = CharSetFromSid(ScriptId);
  214. lf.lfHeight += lf.lfHeight/2;
  215. lf.lfWidth += lf.lfWidth/2;
  216. StrCpyN(lf.lfFaceName, lpFace, LF_FACESIZE);
  217. hFont = CreateFontIndirect(&lf);
  218. hTemp = (HFONT)SelectObject(hDC, hFont);
  219. GetTextMetrics(hDC, &tm);
  220. len = lstrlen(szFontSample);
  221. GetTextExtentPoint32(hDC, szFontSample, len, &TextExtent);
  222. TextExtent.cy = tm.tmAscent - tm.tmInternalLeading;
  223. DrawEdge(hDC, &rc, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
  224. if ((TextExtent.cx >= (rc.right - rc.left)) || (TextExtent.cx <= 0))
  225. x = rc.left;
  226. else
  227. x = rc.left + ((rc.right - rc.left) - TextExtent.cx) / 2;
  228. y = min(rc.bottom, rc.bottom - ((rc.bottom - rc.top) - TextExtent.cy) / 2);
  229. if (lpFace[0])
  230. ExtTextOut(hDC, x, y - (tm.tmAscent), ETO_OPAQUE | ETO_CLIPPED,
  231. &rc, szFontSample, len, NULL );
  232. else
  233. ExtTextOut(hDC, x, y - (tm.tmAscent), ETO_OPAQUE | ETO_CLIPPED,
  234. &rc, TEXT(" "), 1, NULL );
  235. SetBkColor(hDC, rgbBack);
  236. SetTextColor(hDC, rgbText);
  237. if (hTemp)
  238. DeleteObject(SelectObject(hDC, hTemp));
  239. ReleaseDC(pFnt->hDlg, hDC);
  240. }
  241. //
  242. // FillCharsetListBoxes()
  243. //
  244. // Fills the Web page and Plain text ListBoxes with the appropriate
  245. // font data
  246. //
  247. BOOL FillScriptListBoxes(LPFONTSCRIPTDATA pFnt, SCRIPT_ID sid)
  248. {
  249. UINT i;
  250. UINT nFonts = 0;
  251. int iSidInfo = -1;
  252. PSCRIPTFONTINFO pSidFont = NULL;
  253. if (!pFnt->pSidInfo)
  254. return FALSE;
  255. // erase all the listboxes to start fresh
  256. SendMessage(pFnt->hwndPropLB, LB_RESETCONTENT, 0, 0);
  257. SendMessage(pFnt->hwndFixedLB, LB_RESETCONTENT, 0, 0);
  258. for(i=0; i < g_cSidInfo; i++)
  259. {
  260. if (pFnt->pSidInfo[i].ScriptId == sid)
  261. {
  262. iSidInfo = i;
  263. break;
  264. }
  265. }
  266. if (-1 == iSidInfo)
  267. return FALSE;
  268. if (g_pMLFlnk2)
  269. {
  270. g_pMLFlnk2->GetScriptFontInfo(sid, SCRIPTCONTF_PROPORTIONAL_FONT, &nFonts, NULL);
  271. if (nFonts)
  272. {
  273. pSidFont = (PSCRIPTFONTINFO) LocalAlloc(LPTR, sizeof(SCRIPTFONTINFO)*nFonts);
  274. if (pSidFont)
  275. {
  276. g_pMLFlnk2->GetScriptFontInfo(sid, SCRIPTCONTF_PROPORTIONAL_FONT, &nFonts, pSidFont);
  277. for (i=0; i<nFonts; i++)
  278. {
  279. if (LB_ERR == SendMessage(pFnt->hwndPropLB, LB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)((pSidFont+i)->wszFont)))
  280. {
  281. // add the font name to the combobox
  282. SendMessage(pFnt->hwndPropLB, LB_ADDSTRING, 0, (LPARAM)((pSidFont+i)->wszFont));
  283. }
  284. }
  285. // Hack PRC font problems on Win9x and NT4 (Bug #24641, #39946)
  286. // Win9x does not ship with GBK-supporting fixed-pitch fonts,
  287. // We provide user proportional fonts as plain text font candidates.
  288. if (sid == sidHan && GetACP() == 936 && !IsOS(OS_WIN2000ORGREATER))
  289. {
  290. for (i=0; i<nFonts; i++)
  291. {
  292. // add the font name to the combobox
  293. SendMessage(pFnt->hwndFixedLB, LB_ADDSTRING, 0, (LPARAM)((pSidFont+i)->wszFont));
  294. }
  295. }
  296. LocalFree(pSidFont);
  297. pSidFont = NULL;
  298. }
  299. }
  300. // Get number of available fonts
  301. g_pMLFlnk2->GetScriptFontInfo(sid, SCRIPTCONTF_FIXED_FONT, &nFonts, NULL);
  302. if (nFonts)
  303. {
  304. pSidFont = (PSCRIPTFONTINFO) LocalAlloc(LPTR, sizeof(SCRIPTFONTINFO)*nFonts);
  305. if (pSidFont)
  306. {
  307. g_pMLFlnk2->GetScriptFontInfo(sid, SCRIPTCONTF_FIXED_FONT, &nFonts, pSidFont);
  308. if (!pFnt->pSidInfo[iSidInfo].wszFixedWidthFont[0])
  309. {
  310. StrCpyN(pFnt->pSidInfo[iSidInfo].wszFixedWidthFont, pSidFont->wszFont, LF_FACESIZE);
  311. pFnt->bChanged = TRUE;
  312. }
  313. // All fixedwidth and proportional fonts are web page font candidates
  314. for (i=0; i<nFonts; i++)
  315. {
  316. if (LB_ERR == SendMessage(pFnt->hwndFixedLB, LB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)((pSidFont+i)->wszFont)))
  317. {
  318. // add the font name to the combobox
  319. SendMessage(pFnt->hwndFixedLB, LB_ADDSTRING, 0, (LPARAM)((pSidFont+i)->wszFont));
  320. }
  321. if (LB_ERR == SendMessage(pFnt->hwndPropLB, LB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)((pSidFont+i)->wszFont)))
  322. {
  323. // add the font name to the combobox
  324. SendMessage(pFnt->hwndPropLB, LB_ADDSTRING, 0, (LPARAM)((pSidFont+i)->wszFont));
  325. }
  326. }
  327. LocalFree(pSidFont);
  328. }
  329. }
  330. }
  331. // Add fonts to combobox
  332. #ifdef UNIX
  333. /* We would have called EnumFontFamiliesEx wherein we would have
  334. * have populated the fonts list boxes with substitute fonts if any
  335. *
  336. * So, before we populate the proportional and the fixed fonts below,
  337. * we must query and use substitute fonts if avbl.
  338. */
  339. {
  340. CHAR szSubstFont[MAX_MIMEFACE_NAME+1];
  341. DWORD cchSubstFont = MAX_MIMEFACE_NAME + 1;
  342. CHAR szFont[MAX_MIMEFACE_NAME + 1];
  343. WideCharToMultiByte(CP_ACP, 0, pFnt->pSidInfo[iSidInfo].wszProportionalFont, -1, szFont,
  344. MAX_MIMEFACE_NAME + 1, NULL, NULL);
  345. if ((ERROR_SUCCESS == MwGetSubstituteFont(szFont, szSubstFont, &cchSubstFont)) &&
  346. cchSubstFont)
  347. {
  348. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSubstFont, -1,
  349. pFnt->pSidInfo[iSidInfo].wszProportionalFont, MAX_MIMEFACE_NAME + 1);
  350. }
  351. WideCharToMultiByte(CP_ACP, 0, pFnt->pSidInfo[iSidInfo].wszFixedWidthFont, -1, szFont,
  352. MAX_MIMEFACE_NAME + 1, NULL, NULL);
  353. cchSubstFont = MAX_MIMEFACE_NAME + 1;
  354. if ((ERROR_SUCCESS == MwGetSubstituteFont(szFont, szSubstFont, &cchSubstFont)) &&
  355. cchSubstFont)
  356. {
  357. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSubstFont, -1,
  358. pFnt->pSidInfo[iSidInfo].wszFixedWidthFont, MAX_MIMEFACE_NAME + 1);
  359. }
  360. }
  361. #endif /* UNIX */
  362. // select the current prop default
  363. if (pFnt->pSidInfo[iSidInfo].wszProportionalFont[0])
  364. {
  365. if (LB_ERR == SendMessage(pFnt->hwndPropLB, LB_SELECTSTRING, (WPARAM)-1,
  366. (LPARAM)pFnt->pSidInfo[iSidInfo].wszProportionalFont))
  367. pFnt->pSidInfo[iSidInfo].wszProportionalFont[0] = 0;
  368. }
  369. // Draw sample strings with current font
  370. DrawSampleString((FONTSDATA *)pFnt, IDC_FONTS_PROP_SAMPLE, pFnt->pSidInfo[iSidInfo].wszProportionalFont, pFnt->pSidInfo[iSidInfo].ScriptId);
  371. // select the current fixed default
  372. if (pFnt->pSidInfo[iSidInfo].wszFixedWidthFont[0])
  373. {
  374. if (LB_ERR == SendMessage(pFnt->hwndFixedLB, LB_SELECTSTRING, (WPARAM)-1,
  375. (LPARAM)pFnt->pSidInfo[iSidInfo].wszFixedWidthFont))
  376. pFnt->pSidInfo[iSidInfo].wszFixedWidthFont[0] = 0;
  377. }
  378. // Draw sample strings with current font
  379. DrawSampleString((FONTSDATA *)pFnt, IDC_FONTS_FIXED_SAMPLE, pFnt->pSidInfo[iSidInfo].wszFixedWidthFont, pFnt->pSidInfo[iSidInfo].ScriptId);
  380. // we handled it
  381. return TRUE;
  382. } // FillScriptListBoxes()
  383. //
  384. // FontsDlgInitEx()
  385. //
  386. // Initializes the script based font dialog, use same dialog box template.
  387. //
  388. BOOL FontsDlgInitEx(IN HWND hDlg, LPCTSTR lpszKeyPath)
  389. {
  390. HKEY hkey;
  391. // DWORD dw;
  392. DWORD cb;
  393. DWORD i;
  394. TCHAR szKey[1024];
  395. LPFONTSCRIPTDATA pFnt; // localize data
  396. if (!hDlg)
  397. return FALSE; // nothing to initialize
  398. // get some space to store local data
  399. // NOTE: LocalAlloc already zeroes the memory
  400. pFnt = (LPFONTSCRIPTDATA)LocalAlloc(LPTR, sizeof(*pFnt));
  401. if (!pFnt)
  402. {
  403. EndDialog(hDlg, 0);
  404. return FALSE;
  405. }
  406. if (!InitScriptTable(pFnt))
  407. {
  408. EndDialog(hDlg, 0);
  409. return FALSE;
  410. }
  411. // associate the memory with the dialog window
  412. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pFnt);
  413. // save the dialog handle
  414. pFnt->hDlg = hDlg;
  415. // get the dialog items
  416. pFnt->hwndPropLB = GetDlgItem(pFnt->hDlg, IDC_FONTS_PROP_FONT_LIST);
  417. pFnt->hwndFixedLB = GetDlgItem(pFnt->hDlg, IDC_FONTS_FIXED_FONT_LIST);
  418. pFnt->hwndNamesCB = GetDlgItem(pFnt->hDlg, IDC_FONTS_CHAR_SET_COMBO);
  419. pFnt->lpszKeyPath = lpszKeyPath ? lpszKeyPath: REGSTR_PATH_INTERNATIONAL_SCRIPTS;
  420. if (!g_pMLFlnk2 || FAILED(g_pMLFlnk2->CodePageToScriptID(GetACP(), &(pFnt->sidDefault))))
  421. pFnt->sidDefault = sidAsciiLatin;
  422. // We shouldn't consider default script in registry since we no longer have UI to allow user to change default script
  423. #if 0
  424. // get values from registry
  425. if (RegOpenKeyEx(HKEY_CURRENT_USER, pFnt->lpszKeyPath, NULL, KEY_READ, &hkey)
  426. == ERROR_SUCCESS)
  427. {
  428. cb = sizeof(dw);
  429. if (RegQueryValueEx(hkey, REGSTR_VAL_DEFAULT_SCRIPT, NULL, NULL, (LPBYTE)&dw, &cb)
  430. == ERROR_SUCCESS)
  431. {
  432. pFnt->sidDefault = (SCRIPT_ID)dw;
  433. }
  434. RegCloseKey(hkey);
  435. }
  436. #endif
  437. for (i = 0; i < g_cSidInfo; i++)
  438. {
  439. wnsprintf(szKey, ARRAYSIZE(szKey), TEXT("%s\\%u"), pFnt->lpszKeyPath, pFnt->pSidInfo[i].ScriptId);
  440. if (RegOpenKeyEx(HKEY_CURRENT_USER, szKey, NULL, KEY_READ, &hkey) == ERROR_SUCCESS)
  441. {
  442. TCHAR szFont[MAX_MIMEFACE_NAME];
  443. cb = sizeof(szFont);
  444. if (RegQueryValueEx(hkey, REGSTR_VAL_FIXED_FONT, NULL, NULL,
  445. (LPBYTE)szFont, &cb) == ERROR_SUCCESS)
  446. {
  447. StrCpyN(pFnt->pSidInfo[i].wszFixedWidthFont, szFont, ARRAYSIZE(pFnt->pSidInfo[i].wszFixedWidthFont));
  448. }
  449. cb = sizeof(szFont);
  450. if (RegQueryValueEx(hkey, REGSTR_VAL_PROP_FONT, NULL, NULL,
  451. (LPBYTE)szFont, &cb) == ERROR_SUCCESS)
  452. {
  453. StrCpyN(pFnt->pSidInfo[i].wszProportionalFont, szFont, ARRAYSIZE(pFnt->pSidInfo[i].wszProportionalFont));
  454. }
  455. RegCloseKey(hkey);
  456. }
  457. // add the name to the listbox
  458. SendMessage(pFnt->hwndNamesCB, CB_ADDSTRING, 0,
  459. (LPARAM)pFnt->pSidInfo[i].wszDescription);
  460. // check to see if it is the default code page
  461. if (pFnt->sidDefault == pFnt->pSidInfo[i].ScriptId)
  462. {
  463. SendMessage(pFnt->hwndNamesCB, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)pFnt->pSidInfo[i].wszDescription);
  464. }
  465. }
  466. pFnt->bChanged = FALSE;
  467. FillScriptListBoxes(pFnt, pFnt->sidDefault);
  468. if( g_restrict.fFonts )
  469. {
  470. EnableWindow( GetDlgItem( hDlg, IDC_FONTS_PROP_FONT_LIST ), FALSE);
  471. EnableWindow( GetDlgItem( hDlg, IDC_FONTS_FIXED_FONT_LIST ), FALSE);
  472. EnableWindow( GetDlgItem( hDlg, IDC_FONTS_CHAR_SET_COMBO ), FALSE);
  473. #ifdef UNIX
  474. EnableWindow( GetDlgItem( hDlg, IDC_FONTS_UPDATE_BUTTON ), FALSE);
  475. #endif
  476. }
  477. // everything ok
  478. return TRUE;
  479. } // FontsDlgInit()
  480. //
  481. // SaveFontsDataEx()
  482. //
  483. // Save the new fonts settings into regestry
  484. //
  485. void SaveFontsDataEx(LPFONTSCRIPTDATA pFnt)
  486. {
  487. HKEY hkeyScript;
  488. TCHAR szScript[MAX_SCRIPT_NAME];
  489. HKEY hkey;
  490. DWORD dw;
  491. // get values from registry
  492. if (RegCreateKeyEx(HKEY_CURRENT_USER, pFnt->lpszKeyPath, NULL, NULL, NULL, KEY_WRITE, NULL, &hkey, &dw)
  493. == ERROR_SUCCESS)
  494. {
  495. UINT i;
  496. RegSetValueEx(hkey, REGSTR_VAL_DEFAULT_SCRIPT, NULL, REG_BINARY, (LPBYTE)&pFnt->sidDefault, sizeof(pFnt->sidDefault));
  497. for(i = 0; i < g_cSidInfo; i++)
  498. {
  499. wnsprintf(szScript, ARRAYSIZE(szScript), TEXT("%u"), pFnt->pSidInfo[i].ScriptId);
  500. if (RegCreateKeyEx(hkey, szScript, NULL, NULL, NULL, KEY_WRITE, NULL, &hkeyScript, &dw) == ERROR_SUCCESS)
  501. {
  502. // Currently, no need for script name, save registry space
  503. #if 0
  504. RegSetValueEx(hkeyScript, REGSTR_VAL_FONT_SCRIPT_NAME, NULL, REG_SZ,
  505. (LPBYTE)&pFnt->pSidInfo[i].wszDescription,
  506. (lstrlen(pFnt->pSidInfo[i].wszDescription)+1)*sizeof(TCHAR));
  507. #endif
  508. RegSetValueEx(hkeyScript, REGSTR_VAL_SCRIPT_FIXED_FONT, NULL, REG_SZ,
  509. (LPBYTE)pFnt->pSidInfo[i].wszFixedWidthFont,
  510. (lstrlen(pFnt->pSidInfo[i].wszFixedWidthFont)+1)*sizeof(TCHAR));
  511. RegSetValueEx(hkeyScript, REGSTR_VAL_SCRIPT_PROP_FONT, NULL, REG_SZ,
  512. (LPBYTE)pFnt->pSidInfo[i].wszProportionalFont,
  513. (lstrlen(pFnt->pSidInfo[i].wszProportionalFont)+1)*sizeof(TCHAR));
  514. RegCloseKey(hkeyScript);
  515. } // if RegCreateKeyEx
  516. } // for
  517. RegCloseKey(hkey);
  518. } // if RegCreateKeyEx
  519. } // SaveFontsDataEx()
  520. //
  521. // FontsOnCommandEx()
  522. //
  523. // Handles WM_COMMAND message for the script based Fonts subdialog
  524. //
  525. BOOL FontsOnCommandEx(LPFONTSCRIPTDATA pFnt, UINT id, UINT nCmd)
  526. {
  527. switch(id)
  528. {
  529. case IDOK:
  530. if (pFnt->bChanged)
  531. {
  532. SaveFontsDataEx(pFnt);
  533. // tell MSHTML to pick up changes and update
  534. UpdateAllWindows();
  535. }
  536. return TRUE; // exit dialog
  537. case IDCANCEL:
  538. return TRUE; // exit dialog
  539. case IDC_FONTS_PROP_FONT_LIST:
  540. case IDC_FONTS_FIXED_FONT_LIST:
  541. if (nCmd==LBN_SELCHANGE)
  542. {
  543. UINT i;
  544. TCHAR szScript[MAX_SCRIPT_NAME];
  545. pFnt->bChanged = TRUE; // we need to save
  546. // find the currently selected item in the list box
  547. GetDlgItemText(pFnt->hDlg, IDC_FONTS_CHAR_SET_COMBO, szScript, ARRAYSIZE(szScript));
  548. // find the code page from the text
  549. for(i=0; i < g_cSidInfo; i++)
  550. {
  551. INT_PTR j;
  552. if (IsStringEqual(szScript, pFnt->pSidInfo[i].wszDescription))
  553. {
  554. // grab the new values
  555. j = SendMessage(pFnt->hwndPropLB, LB_GETCURSEL, 0, 0);
  556. SendMessage(pFnt->hwndPropLB, LB_GETTEXT, j, (LPARAM)(pFnt->pSidInfo[i].wszProportionalFont));
  557. j = SendMessage(pFnt->hwndFixedLB, LB_GETCURSEL, 0, 0);
  558. SendMessage(pFnt->hwndFixedLB, LB_GETTEXT, j, (LPARAM)(pFnt->pSidInfo[i].wszFixedWidthFont));
  559. break;
  560. }
  561. }
  562. // Redraw sample strings
  563. DrawSampleString((LPFONTSDATA)pFnt, IDC_FONTS_PROP_SAMPLE, pFnt->pSidInfo[i].wszProportionalFont, pFnt->pSidInfo[i].ScriptId);
  564. DrawSampleString((LPFONTSDATA)pFnt, IDC_FONTS_FIXED_SAMPLE, pFnt->pSidInfo[i].wszFixedWidthFont, pFnt->pSidInfo[i].ScriptId);
  565. // if we don't find it... we are going to keep the default
  566. ASSERT(i < g_cSidInfo); // something went wrong
  567. }
  568. break;
  569. case IDC_FONTS_CHAR_SET_COMBO:
  570. if (nCmd==CBN_SELCHANGE)
  571. {
  572. UINT i;
  573. TCHAR szScript[MAX_SCRIPT_NAME];
  574. GetDlgItemText(pFnt->hDlg, IDC_FONTS_CHAR_SET_COMBO, szScript, ARRAYSIZE(szScript));
  575. // find the code page from the text
  576. for(i=0; i < g_cSidInfo; i++)
  577. {
  578. if (IsStringEqual(szScript, pFnt->pSidInfo[i].wszDescription))
  579. {
  580. FillScriptListBoxes(pFnt, pFnt->pSidInfo[i].ScriptId);
  581. break;
  582. }
  583. }
  584. }
  585. break;
  586. #ifdef UNIX
  587. case IDC_FONTS_UPDATE_BUTTON:
  588. {
  589. HCURSOR hOldCursor = NULL;
  590. HCURSOR hNewCursor = NULL;
  591. hNewCursor = LoadCursor(NULL, IDC_WAIT);
  592. if (hNewCursor)
  593. hOldCursor = SetCursor(hNewCursor);
  594. DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_FONTUPD_PROG), pFnt->hDlg,FontUpdDlgProc, NULL);
  595. if(hOldCursor)
  596. SetCursor(hOldCursor);
  597. }
  598. break;
  599. #endif
  600. }
  601. // don't exit dialog
  602. return FALSE;
  603. }
  604. //
  605. // FontsDlgProcEx()
  606. //
  607. // Message handler for the script based "Fonts" subdialog.
  608. //
  609. INT_PTR CALLBACK FontsDlgProcEx(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  610. {
  611. LPFONTSCRIPTDATA pFnt = (LPFONTSCRIPTDATA) GetWindowLongPtr(hDlg, DWLP_USER);
  612. PAINTSTRUCT ps;
  613. switch (uMsg)
  614. {
  615. case WM_INITDIALOG:
  616. return FontsDlgInitEx(hDlg, (LPTSTR)lParam);
  617. break;
  618. case WM_DESTROY:
  619. // Free memory
  620. if (pFnt)
  621. {
  622. if (pFnt->pSidInfo)
  623. LocalFree(pFnt->pSidInfo);
  624. LocalFree(pFnt);
  625. }
  626. break;
  627. case WM_PAINT:
  628. if (BeginPaint(hDlg, &ps))
  629. {
  630. UINT i;
  631. SCRIPT_ID sid = 0;
  632. TCHAR szScript[MAX_SCRIPT_NAME];
  633. GetDlgItemText(hDlg, IDC_FONTS_CHAR_SET_COMBO, szScript, ARRAYSIZE(szScript));
  634. // find the script id from the text
  635. for(i = 0; i < g_cSidInfo; i++)
  636. {
  637. if (IsStringEqual(szScript, pFnt->pSidInfo[i].wszDescription))
  638. {
  639. sid = pFnt->pSidInfo[i].ScriptId;
  640. break;
  641. }
  642. }
  643. if (i < g_cSidInfo)
  644. {
  645. // show sample strings with current font
  646. DrawSampleString((LPFONTSDATA)pFnt, IDC_FONTS_PROP_SAMPLE, pFnt->pSidInfo[i].wszProportionalFont, pFnt->pSidInfo[i].ScriptId);
  647. DrawSampleString((LPFONTSDATA)pFnt, IDC_FONTS_FIXED_SAMPLE, pFnt->pSidInfo[i].wszFixedWidthFont, pFnt->pSidInfo[i].ScriptId);
  648. }
  649. EndPaint(hDlg, &ps);
  650. }
  651. break;
  652. case WM_COMMAND:
  653. if (FontsOnCommandEx(pFnt, LOWORD(wParam), HIWORD(wParam)))
  654. EndDialog(hDlg, LOWORD(wParam) == IDOK? 1: 0);
  655. break;
  656. case WM_HELP: // F1
  657. ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  658. HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  659. break;
  660. case WM_CONTEXTMENU: // right mouse click
  661. ResWinHelp( (HWND) wParam, IDS_HELPFILE,
  662. HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  663. break;
  664. #ifdef UNIX
  665. case WM_DRAWITEM:
  666. switch (GET_WM_COMMAND_ID(wParam, lParam))
  667. {
  668. case IDC_FONTS_UPDATE_BUTTON:
  669. DrawXFontButton(hDlg, (LPDRAWITEMSTRUCT)lParam);
  670. return TRUE;
  671. }
  672. return FALSE;
  673. #endif
  674. default:
  675. return FALSE;
  676. }
  677. return TRUE;
  678. }
  679. //
  680. // Back out old font dialog for OE4
  681. //
  682. //
  683. // InitMimeCsetTable()
  684. //
  685. // Initialize MimeCharsetTable[]'s string field with resource string
  686. //
  687. BOOL InitMimeCsetTable(BOOL bIsOE5)
  688. {
  689. IMultiLanguage *pML=NULL;
  690. IMultiLanguage2 *pML2=NULL;
  691. HRESULT hr;
  692. if(!hOLE32)
  693. {
  694. if(!_StartOLE32())
  695. {
  696. ASSERT(FALSE);
  697. return FALSE;
  698. }
  699. }
  700. hr = pCoInitialize(NULL);
  701. if (FAILED(hr))
  702. return FALSE;
  703. if (bIsOE5)
  704. hr = pCoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage2, (LPVOID *) &pML2);
  705. else
  706. hr = pCoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage, (LPVOID *) &pML);
  707. if (SUCCEEDED(hr))
  708. {
  709. IEnumCodePage *pEnumCP;
  710. if (bIsOE5)
  711. {
  712. // Ignore MUI if cross code page, otherwise, we won't be able to save data in registry
  713. char szUICP[1024] = {0};
  714. LANGID uiLangId = INETCPL_GetUILanguage();
  715. // We always support English (US)
  716. if (uiLangId != 0x0409)
  717. GetLocaleInfoA(MAKELCID(uiLangId, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, szUICP, ARRAYSIZE(szUICP));
  718. if (szUICP[0] && (UINT)StrToIntA(szUICP) != GetACP())
  719. hr = pML2->EnumCodePages(MIMECONTF_VALID, GetSystemDefaultLangID(), &pEnumCP);
  720. else
  721. hr = pML2->EnumCodePages(MIMECONTF_VALID, uiLangId, &pEnumCP);
  722. }
  723. else
  724. hr = pML->EnumCodePages(MIMECONTF_VALID, &pEnumCP);
  725. if (SUCCEEDED(hr))
  726. {
  727. UINT cNum = 0;
  728. if (bIsOE5)
  729. pML2->GetNumberOfCodePageInfo(&cNum);
  730. else
  731. pML->GetNumberOfCodePageInfo(&cNum);
  732. #ifdef UNICODE
  733. g_pCPInfo = (PMIMECPINFO)LocalAlloc(LPTR, sizeof(MIMECPINFO) * cNum);
  734. if (NULL != g_pCPInfo)
  735. {
  736. hr = pEnumCP->Next(cNum, g_pCPInfo, &g_cCPInfo);
  737. if (SUCCEEDED(hr))
  738. {
  739. g_pCPInfo = (PMIMECPINFO)LocalReAlloc(g_pCPInfo, sizeof(MIMECPINFO) * g_cCPInfo, LMEM_MOVEABLE);
  740. }
  741. else
  742. {
  743. LocalFree(g_pCPInfo);
  744. g_pCPInfo = NULL;
  745. }
  746. #else
  747. g_pCPInfoW = (PMIMECPINFO)LocalAlloc(LPTR, sizeof(MIMECPINFO) * cNum);
  748. if (NULL != g_pCPInfoW)
  749. {
  750. hr = pEnumCP->Next(cNum, g_pCPInfoW, &g_cCPInfo);
  751. if (SUCCEEDED(hr))
  752. {
  753. g_pCPInfo = (PMIMECPINFOA)LocalAlloc(LPTR, sizeof(MIMECPINFOA) * g_cCPInfo);
  754. if (NULL != g_pCPInfo)
  755. {
  756. UINT i;
  757. for (i = 0; i < g_cCPInfo; i++)
  758. {
  759. g_pCPInfo[i].dwFlags = g_pCPInfoW[i].dwFlags;
  760. g_pCPInfo[i].uiCodePage = g_pCPInfoW[i].uiCodePage;
  761. g_pCPInfo[i].uiFamilyCodePage = g_pCPInfoW[i].uiFamilyCodePage;
  762. WideCharToMultiByte(CP_ACP, 0, (WCHAR *)g_pCPInfoW[i].wszDescription, -1, g_pCPInfo[i].wszDescription, sizeof(g_pCPInfo[i].wszDescription), NULL, NULL);
  763. WideCharToMultiByte(CP_ACP, 0, (WCHAR *)g_pCPInfoW[i].wszWebCharset, -1, g_pCPInfo[i].wszWebCharset, sizeof(g_pCPInfo[i].wszWebCharset), NULL, NULL);
  764. WideCharToMultiByte(CP_ACP, 0, (WCHAR *)g_pCPInfoW[i].wszHeaderCharset, -1, g_pCPInfo[i].wszHeaderCharset, sizeof(g_pCPInfo[i].wszHeaderCharset), NULL, NULL);
  765. WideCharToMultiByte(CP_ACP, 0, (WCHAR *)g_pCPInfoW[i].wszBodyCharset, -1, g_pCPInfo[i].wszBodyCharset, sizeof(g_pCPInfo[i].wszBodyCharset), NULL, NULL);
  766. WideCharToMultiByte(CP_ACP, 0, (WCHAR *)g_pCPInfoW[i].wszFixedWidthFont, -1, g_pCPInfo[i].wszFixedWidthFont, sizeof(g_pCPInfo[i].wszFixedWidthFont), NULL, NULL);
  767. WideCharToMultiByte(CP_ACP, 0, (WCHAR *)g_pCPInfoW[i].wszProportionalFont, -1, g_pCPInfo[i].wszProportionalFont, sizeof(g_pCPInfo[i].wszProportionalFont), NULL, NULL);
  768. g_pCPInfo[i].bGDICharset = g_pCPInfoW[i].bGDICharset;
  769. }
  770. }
  771. }
  772. LocalFree(g_pCPInfoW);
  773. g_pCPInfoW = NULL;
  774. #endif
  775. }
  776. pEnumCP->Release();
  777. }
  778. if (bIsOE5)
  779. pML2->Release();
  780. else
  781. pML->Release();
  782. }
  783. pCoUninitialize();
  784. return TRUE;
  785. }
  786. //
  787. // FreeMimeCsetTable()
  788. //
  789. // Free string buffer of MimeCharsetTable[]'s string field
  790. //
  791. void FreeMimeCsetTable(void)
  792. {
  793. if (NULL != g_pCPInfo)
  794. {
  795. LocalFree(g_pCPInfo);
  796. g_pCPInfo = NULL;
  797. g_cCPInfo = 0;
  798. }
  799. }
  800. //
  801. // EnumFontsProc()
  802. //
  803. // Selects only one font per style
  804. //
  805. int CALLBACK EnumFontsProc(
  806. ENUMLOGFONTEX FAR* elf, // address of logical-font data
  807. TEXTMETRIC FAR* tm, // address of physical-font data
  808. DWORD dwFontType, // type of font
  809. LPARAM lParam // address of application-defined data
  810. )
  811. {
  812. LOGFONT FAR* lf;
  813. LPFONTSDATA pFnt;
  814. ASSERT(lParam);
  815. ASSERT(elf);
  816. pFnt = (LPFONTSDATA)lParam;
  817. lf = &(elf->elfLogFont);
  818. if ( dwFontType == DEVICE_FONTTYPE || dwFontType == RASTER_FONTTYPE )
  819. return TRUE; // keep going but don't use this font
  820. /* We don't use the SYMBOL fonts */
  821. if( lf->lfCharSet == SYMBOL_CHARSET )
  822. return TRUE;
  823. // we don't handle Mac Charset
  824. if (lf->lfCharSet == MAC_CHARSET )
  825. return TRUE;
  826. if ( IsVerticalFont(lf->lfFaceName) )
  827. return TRUE; // keep going but don't use this font
  828. if ( lf->lfPitchAndFamily & FIXED_PITCH )
  829. {
  830. if (CB_ERR == SendMessage(pFnt->hwndFixedCB, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)elf->elfLogFont.lfFaceName))
  831. {
  832. // add the font name to the combobox
  833. SendMessage(pFnt->hwndFixedCB, CB_ADDSTRING, 0, (LPARAM)elf->elfLogFont.lfFaceName);
  834. }
  835. }
  836. if (CB_ERR == SendMessage(pFnt->hwndPropCB, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)elf->elfLogFont.lfFaceName))
  837. {
  838. // add the font name to the combobox
  839. SendMessage(pFnt->hwndPropCB, CB_ADDSTRING, 0, (LPARAM)elf->elfLogFont.lfFaceName);
  840. }
  841. return TRUE;
  842. }
  843. //
  844. // FillFontComboBox()
  845. //
  846. // Fills hwndCB with the names of fonts of family dwCodePage.
  847. //
  848. BOOL FillFontComboBox(IN LPFONTSDATA pFnt, IN BYTE CodePage)
  849. {
  850. HDC hDC;
  851. LOGFONT lf;
  852. HWND hWnd;
  853. BOOL fReturn = FALSE;
  854. // get system font info
  855. hWnd = GetTopWindow(GetDesktopWindow());
  856. hDC = GetDC(hWnd);
  857. if (hDC)
  858. {
  859. lf.lfFaceName[0] = 0;
  860. lf.lfPitchAndFamily = 0;
  861. lf.lfCharSet = CodePage;
  862. EnumFontFamiliesEx(hDC, &lf, (FONTENUMPROC)EnumFontsProc,
  863. (LPARAM)pFnt, 0);
  864. // everthing went fine
  865. fReturn = TRUE;
  866. }
  867. ReleaseDC(hWnd, hDC);
  868. return fReturn;
  869. } // FillFontComboBox()
  870. //
  871. // FillSizeComboBox()
  872. //
  873. // Fills font size combobox with the size of fonts.
  874. //
  875. BOOL FillSizeComboBox(IN LPFONTSDATA pFnt)
  876. {
  877. int i;
  878. for (i = IDS_FONT_SIZE_SMALLEST; i <= IDS_FONT_SIZE_LARGEST ; i++)
  879. {
  880. TCHAR szSize[MAX_MIMEFACE_NAME];
  881. MLLoadString(i, szSize, sizeof(szSize));
  882. SendMessage(pFnt->hwndSizeCB, CB_ADDSTRING, 0, (LPARAM)szSize);
  883. }
  884. return TRUE;
  885. }
  886. //
  887. // FillCharsetComboBoxes()
  888. //
  889. // Fills the Fixed, Prop, and MIME comboboxes with the appropriate
  890. // font data
  891. //
  892. BOOL FillCharsetComboBoxes(LPFONTSDATA pFnt, DWORD dwCodePage)
  893. {
  894. UINT i;
  895. int iPageInfo = -1;
  896. DWORD grfFlag;
  897. // erase all the comboboxes to start fresh
  898. SendMessage(pFnt->hwndPropCB, CB_RESETCONTENT, 0, 0);
  899. SendMessage(pFnt->hwndFixedCB, CB_RESETCONTENT, 0, 0);
  900. SendMessage(pFnt->hwndSizeCB, CB_RESETCONTENT, 0, 0);
  901. SendMessage(pFnt->hwndMIMECB, CB_RESETCONTENT, 0, 0);
  902. // What happens if other one calls OpenFontDialog except Athena?
  903. grfFlag = StrCmpI(pFnt->lpszKeyPath, REGSTR_PATH_INTERNATIONAL)? MIMECONTF_MAILNEWS: MIMECONTF_BROWSER;
  904. for(i=0; i < g_cCPInfo; i++)
  905. {
  906. // find the codepage in our table
  907. if (g_pCPInfo[i].uiFamilyCodePage == (UINT)dwCodePage)
  908. {
  909. //
  910. // populate MIME combobox
  911. //
  912. if (g_pCPInfo[i].uiCodePage == (UINT)dwCodePage)
  913. iPageInfo = i; // we store info per family codepage here
  914. // add mime type to combobox
  915. if (grfFlag & g_pCPInfo[i].dwFlags)
  916. {
  917. // HACK: We need to remove Japanese JIS 1 Byte Kana and Korean for MAILNEWS.
  918. // 949 : Korean. We are using Korean (Auto Detect) instead
  919. // 50225 : Korean ISO
  920. // 50221 : Japanese JIS 1 byte Kana-ESC
  921. // 50222 : Japanese JIS 1 byte Kana-SIO
  922. if (grfFlag & MIMECONTF_MAILNEWS)
  923. {
  924. if (g_pCPInfo[i].uiCodePage == 949 || g_pCPInfo[i].uiCodePage == 50221 || g_pCPInfo[i].uiCodePage == 50222 || g_pCPInfo[i].uiCodePage == 50225)
  925. continue;
  926. }
  927. SendMessage(pFnt->hwndMIMECB, CB_ADDSTRING, 0, (LPARAM)g_pCPInfo[i].wszDescription);
  928. }
  929. } // if CodePage
  930. } // for i
  931. if (-1 != iPageInfo)
  932. {
  933. // if nothing is defined, then copy the first possible value that
  934. // we know of from our table
  935. if (!pFnt->page[iPageInfo].szMIMEFont[0])
  936. {
  937. if (grfFlag & g_pCPInfo[iPageInfo].dwFlags)
  938. StrCpyN(pFnt->page[iPageInfo].szMIMEFont, g_pCPInfo[iPageInfo].wszDescription, ARRAYSIZE(pFnt->page[iPageInfo].szMIMEFont));
  939. else
  940. {
  941. for (i = 0; i < g_cCPInfo; i++)
  942. {
  943. if (g_pCPInfo[iPageInfo].uiCodePage == g_pCPInfo[i].uiFamilyCodePage)
  944. {
  945. if (grfFlag & g_pCPInfo[i].dwFlags)
  946. {
  947. StrCpyN(pFnt->page[iPageInfo].szMIMEFont, g_pCPInfo[i].wszDescription, ARRAYSIZE(pFnt->page[iPageInfo].szMIMEFont));
  948. break;
  949. }
  950. }
  951. }
  952. }
  953. }
  954. // select the current default
  955. SendMessage(pFnt->hwndMIMECB, CB_SELECTSTRING, (WPARAM)-1,
  956. (LPARAM)pFnt->page[iPageInfo].szMIMEFont);
  957. // Enable/disable MIME is when there is only one possibility
  958. EnableWindow(pFnt->hwndMIMECB, (1 < SendMessage(pFnt->hwndMIMECB, CB_GETCOUNT, 0, (LPARAM)0)) && !g_restrict.fFonts);
  959. // Add fonts to combobox
  960. FillFontComboBox(pFnt, g_pCPInfo[iPageInfo].bGDICharset);
  961. #ifdef UNIX
  962. /* We would have called EnumFontFamiliesEx wherein we would have
  963. * have populated the fonts list boxes with substitute fonts if any
  964. *
  965. * So, before we populate the proportional and the fixed fonts below,
  966. * we must query and use substitute fonts if avbl.
  967. */
  968. {
  969. CHAR szSubstFont[MAX_MIMEFACE_NAME+1];
  970. DWORD cchSubstFont = MAX_MIMEFACE_NAME + 1;
  971. CHAR szFont[MAX_MIMEFACE_NAME + 1];
  972. WideCharToMultiByte(CP_ACP, 0, pFnt->page[iPageInfo].szPropFont, -1, szFont,
  973. MAX_MIMEFACE_NAME + 1, NULL, NULL);
  974. if ((ERROR_SUCCESS == MwGetSubstituteFont(szFont, szSubstFont, &cchSubstFont)) &&
  975. cchSubstFont)
  976. {
  977. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSubstFont, -1,
  978. pFnt->page[iPageInfo].szPropFont, MAX_MIMEFACE_NAME + 1);
  979. }
  980. WideCharToMultiByte(CP_ACP, 0, pFnt->page[iPageInfo].szFixedFont, -1, szFont,
  981. MAX_MIMEFACE_NAME + 1, NULL, NULL);
  982. cchSubstFont = MAX_MIMEFACE_NAME + 1;
  983. if ((ERROR_SUCCESS == MwGetSubstituteFont(szFont, szSubstFont, &cchSubstFont)) &&
  984. cchSubstFont)
  985. {
  986. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSubstFont, -1,
  987. pFnt->page[iPageInfo].szFixedFont, MAX_MIMEFACE_NAME + 1);
  988. }
  989. }
  990. #endif /* UNIX */
  991. // select the current prop default
  992. SendMessage(pFnt->hwndPropCB, CB_SELECTSTRING, (WPARAM)-1,
  993. (LPARAM)pFnt->page[iPageInfo].szPropFont);
  994. // select the current fixed default
  995. SendMessage(pFnt->hwndFixedCB, CB_SELECTSTRING, (WPARAM)-1,
  996. (LPARAM)pFnt->page[iPageInfo].szFixedFont);
  997. // Add font sizes to combobox
  998. FillSizeComboBox(pFnt);
  999. // select the current size default
  1000. SendMessage(pFnt->hwndSizeCB, CB_SETCURSEL, (WPARAM)pFnt->page[iPageInfo].dwFontSize, (LPARAM)0);
  1001. // we handled it
  1002. return TRUE;
  1003. }
  1004. return FALSE;
  1005. } // FillCharsetComboBoxes()
  1006. //
  1007. // FontsDlgInit()
  1008. //
  1009. // Initializes the Fonts dialog.
  1010. //
  1011. BOOL FontsDlgInit(IN HWND hDlg, LPCTSTR lpszKeyPath)
  1012. {
  1013. HKEY hkey;
  1014. DWORD grfFlag;
  1015. DWORD dw;
  1016. DWORD cb;
  1017. DWORD i;
  1018. BOOL bIsOE5 = FALSE;
  1019. TCHAR szKey[1024];
  1020. LPFONTSDATA pFnt; // localize data
  1021. if (!hDlg)
  1022. return FALSE; // nothing to initialize
  1023. // set system default character set where we possibly show
  1024. // the strings in native language.
  1025. SHSetDefaultDialogFont(hDlg, IDC_FONTS_PROP_FONT_COMBO);
  1026. SHSetDefaultDialogFont(hDlg, IDC_FONTS_FIXED_FONT_COMBO);
  1027. SHSetDefaultDialogFont(hDlg, IDC_FONTS_MIME_FONT_COMBO);
  1028. SHSetDefaultDialogFont(hDlg, IDC_FONTS_DEFAULT_LANG_TEXT);
  1029. SHSetDefaultDialogFont(hDlg, IDC_FONTS_CODE_PAGES_LIST);
  1030. // get some space to store local data
  1031. // NOTE: LocalAlloc already zeroes the memory
  1032. pFnt = (LPFONTSDATA)LocalAlloc(LPTR, sizeof(*pFnt));
  1033. if (!pFnt)
  1034. {
  1035. EndDialog(hDlg, 0);
  1036. return FALSE;
  1037. }
  1038. // We distinguish OE5 and OE4 by searching for "5.0" in its registry path,
  1039. // It works as long as there is no spec. change in OE5
  1040. if (NULL != StrStr(lpszKeyPath, TEXT("5.0")))
  1041. bIsOE5 = TRUE;
  1042. if (!InitMimeCsetTable(bIsOE5))
  1043. {
  1044. EndDialog(hDlg, 0);
  1045. return FALSE;
  1046. }
  1047. if (NULL == pFnt->page)
  1048. {
  1049. pFnt->page = (CODEPAGEDATA*)LocalAlloc(LPTR, sizeof(CODEPAGEDATA) * g_cCPInfo);
  1050. if (NULL == pFnt->page)
  1051. {
  1052. EndDialog(hDlg, 0);
  1053. return FALSE;
  1054. }
  1055. }
  1056. // associate the memory with the dialog window
  1057. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR) pFnt);
  1058. // save the dialog handle
  1059. pFnt->hDlg = hDlg;
  1060. // get the dialog items
  1061. pFnt->hwndPropCB = GetDlgItem(pFnt->hDlg, IDC_FONTS_PROP_FONT_COMBO);
  1062. pFnt->hwndFixedCB = GetDlgItem(pFnt->hDlg, IDC_FONTS_FIXED_FONT_COMBO);
  1063. pFnt->hwndSizeCB = GetDlgItem(pFnt->hDlg, IDC_FONTS_SIZE_FONT_COMBO);
  1064. pFnt->hwndMIMECB = GetDlgItem(pFnt->hDlg, IDC_FONTS_MIME_FONT_COMBO);
  1065. pFnt->hwndNamesLB = GetDlgItem(pFnt->hDlg, IDC_FONTS_CODE_PAGES_LIST);
  1066. pFnt->lpszKeyPath = lpszKeyPath ? lpszKeyPath: REGSTR_PATH_INTERNATIONAL;
  1067. pFnt->dwDefaultCodePage = GetACP();
  1068. // get values from registry
  1069. if (RegOpenKeyEx(HKEY_CURRENT_USER, pFnt->lpszKeyPath, NULL, KEY_READ, &hkey)
  1070. == ERROR_SUCCESS)
  1071. {
  1072. cb = sizeof(dw);
  1073. if (RegQueryValueEx(hkey, REGSTR_VAL_DEFAULT_CODEPAGE, NULL, NULL, (LPBYTE)&dw, &cb)
  1074. == ERROR_SUCCESS)
  1075. {
  1076. pFnt->dwDefaultCodePage = dw;
  1077. }
  1078. RegCloseKey(hkey);
  1079. }
  1080. // What happens if other one calls OpenFontDialog except Athena?
  1081. grfFlag = StrCmpI(pFnt->lpszKeyPath, REGSTR_PATH_INTERNATIONAL)? MIMECONTF_MAILNEWS: MIMECONTF_BROWSER;
  1082. for (i = 0; i < g_cCPInfo; i++)
  1083. {
  1084. if (g_pCPInfo[i].uiCodePage == g_pCPInfo[i].uiFamilyCodePage)
  1085. {
  1086. int iDef;
  1087. UINT j;
  1088. iDef = -1;
  1089. if (0 == (grfFlag & g_pCPInfo[i].dwFlags))
  1090. {
  1091. for (j = 0; j < g_cCPInfo; j++)
  1092. {
  1093. if (g_pCPInfo[i].uiCodePage == g_pCPInfo[j].uiFamilyCodePage)
  1094. {
  1095. if (grfFlag & g_pCPInfo[j].dwFlags)
  1096. {
  1097. iDef = j;
  1098. break;
  1099. }
  1100. }
  1101. }
  1102. if (-1 == iDef)
  1103. continue;
  1104. }
  1105. if (g_pCPInfo[i].uiCodePage == 50001) // skip CP_AUTO
  1106. continue;
  1107. wnsprintf(szKey, ARRAYSIZE(szKey), TEXT("%s\\%u"), pFnt->lpszKeyPath, g_pCPInfo[i].uiCodePage);
  1108. if (RegOpenKeyEx(HKEY_CURRENT_USER, szKey, NULL, KEY_READ, &hkey) == ERROR_SUCCESS)
  1109. {
  1110. cb = sizeof(pFnt->page[i].szFriendlyName);
  1111. if (RegQueryValueEx(hkey, REGSTR_VAL_FONT_SCRIPT, NULL, NULL,
  1112. (LPBYTE)&pFnt->page[i].szFriendlyName, &cb)
  1113. != ERROR_SUCCESS)
  1114. {
  1115. TCHAR *p;
  1116. StrCpyN(pFnt->page[i].szFriendlyName, g_pCPInfo[i].wszDescription, ARRAYSIZE(pFnt->page[i].szFriendlyName));
  1117. for (p = pFnt->page[i].szFriendlyName; *p != TEXT('\0'); p = CharNext(p))
  1118. {
  1119. // We'd better have a source of this string else where.
  1120. if (*p == TEXT('('))
  1121. {
  1122. *p = TEXT('\0');
  1123. break;
  1124. }
  1125. }
  1126. }
  1127. cb = sizeof(dw);
  1128. if (RegQueryValueEx(hkey, REGSTR_VAL_DEF_INETENCODING, NULL, NULL, (LPBYTE)&dw, &cb)
  1129. != ERROR_SUCCESS)
  1130. {
  1131. dw = (DWORD)g_pCPInfo[i].uiCodePage;
  1132. // HACK ! It's only for Japanese Auto Select as Japanese default.
  1133. if (dw == 932) // 932 : Japanese Windows CodePage
  1134. dw = 50932; // 50932 : Japanese Auto Select InternetEncoding
  1135. }
  1136. for (j = 0; j < g_cCPInfo; j++)
  1137. {
  1138. if (g_pCPInfo[j].uiCodePage == (UINT)dw)
  1139. {
  1140. if (grfFlag & g_pCPInfo[j].dwFlags)
  1141. StrCpyN(pFnt->page[i].szMIMEFont, g_pCPInfo[j].wszDescription, ARRAYSIZE(pFnt->page[i].szMIMEFont));
  1142. else if (-1 != iDef)
  1143. StrCpyN(pFnt->page[i].szMIMEFont, g_pCPInfo[iDef].wszDescription, ARRAYSIZE(pFnt->page[i].szMIMEFont));
  1144. else
  1145. pFnt->page[i].szMIMEFont[0] = TEXT('\0');
  1146. break;
  1147. }
  1148. }
  1149. cb = sizeof(pFnt->page[i].szFixedFont);
  1150. if (RegQueryValueEx(hkey, REGSTR_VAL_FIXED_FONT, NULL, NULL,
  1151. (LPBYTE)pFnt->page[i].szFixedFont, &cb)
  1152. != ERROR_SUCCESS)
  1153. {
  1154. StrCpyN(pFnt->page[i].szFixedFont, g_pCPInfo[i].wszFixedWidthFont, ARRAYSIZE(pFnt->page[i].szFixedFont));
  1155. }
  1156. cb = sizeof(pFnt->page[i].szPropFont);
  1157. if (RegQueryValueEx(hkey, REGSTR_VAL_PROP_FONT, NULL, NULL,
  1158. (LPBYTE)pFnt->page[i].szPropFont, &cb)
  1159. != ERROR_SUCCESS)
  1160. {
  1161. StrCpyN(pFnt->page[i].szPropFont, g_pCPInfo[i].wszProportionalFont, ARRAYSIZE(pFnt->page[i].szPropFont));
  1162. }
  1163. cb = sizeof(pFnt->page[i].dwFontSize);
  1164. if (RegQueryValueEx(hkey, REGSTR_VAL_FONT_SIZE, NULL, NULL,
  1165. (LPBYTE)&pFnt->page[i].dwFontSize, &cb)
  1166. != ERROR_SUCCESS)
  1167. {
  1168. pFnt->page[i].dwFontSize = REGSTR_VAL_FONT_SIZE_DEF;
  1169. }
  1170. RegCloseKey(hkey);
  1171. }
  1172. else
  1173. {
  1174. UINT j;
  1175. TCHAR *p;
  1176. StrCpyN(pFnt->page[i].szFriendlyName, g_pCPInfo[i].wszDescription, ARRAYSIZE(pFnt->page[i].szFriendlyName));
  1177. for (p = pFnt->page[i].szFriendlyName; *p != TEXT('\0'); p = CharNext(p))
  1178. {
  1179. if (*p == TEXT('('))
  1180. {
  1181. *p = TEXT('\0');
  1182. break;
  1183. }
  1184. }
  1185. j = (grfFlag & g_pCPInfo[i].dwFlags)? i: iDef;
  1186. // HACK ! It's only for Japanese Auto Select as Japanese default.
  1187. if (g_pCPInfo[j].uiCodePage == 932) // 932 : Japanese Windows CodePage
  1188. {
  1189. for (j = 0; j < g_cCPInfo; j++)
  1190. {
  1191. if (g_pCPInfo[j].uiCodePage == 50932) // 50932 : Japanese Auto Select InternetEncoding
  1192. break;
  1193. }
  1194. }
  1195. StrCpyN(pFnt->page[i].szMIMEFont, g_pCPInfo[j].wszDescription, ARRAYSIZE(pFnt->page[i].szMIMEFont));
  1196. StrCpyN(pFnt->page[i].szFixedFont, g_pCPInfo[i].wszFixedWidthFont, ARRAYSIZE(pFnt->page[i].szFixedFont));
  1197. StrCpyN(pFnt->page[i].szPropFont, g_pCPInfo[i].wszProportionalFont, ARRAYSIZE(pFnt->page[i].szPropFont));
  1198. pFnt->page[i].dwFontSize = REGSTR_VAL_FONT_SIZE_DEF;
  1199. }
  1200. // add the name to the listbox
  1201. SendMessage(pFnt->hwndNamesLB, LB_ADDSTRING, 0, (LPARAM)pFnt->page[i].szFriendlyName);
  1202. // check to see if it is the default code page
  1203. if (pFnt->dwDefaultCodePage == g_pCPInfo[i].uiCodePage)
  1204. {
  1205. if (LB_ERR == SendMessage(pFnt->hwndNamesLB, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)pFnt->page[i].szFriendlyName))
  1206. {
  1207. // Hack shlwapi problems for Win9x.
  1208. CHAR szAnsiString[1024] = {0};
  1209. WideCharToMultiByte(CP_ACP, 0, pFnt->page[i].szFriendlyName, -1, szAnsiString, 1024, NULL, NULL);
  1210. SendMessageA(pFnt->hwndNamesLB, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)szAnsiString);
  1211. }
  1212. SetDlgItemText(pFnt->hDlg, IDC_FONTS_DEFAULT_LANG_TEXT, pFnt->page[i].szFriendlyName);
  1213. }
  1214. }
  1215. }
  1216. FillCharsetComboBoxes(pFnt, pFnt->dwDefaultCodePage);
  1217. pFnt->bChanged = FALSE;
  1218. if( g_restrict.fFonts )
  1219. {
  1220. EnableWindow( GetDlgItem( hDlg, IDC_FONTS_PROP_FONT_COMBO ), FALSE);
  1221. EnableWindow( GetDlgItem( hDlg, IDC_FONTS_FIXED_FONT_COMBO ), FALSE);
  1222. EnableWindow( GetDlgItem( hDlg, IDC_FONTS_SIZE_FONT_COMBO ), FALSE);
  1223. EnableWindow( GetDlgItem( hDlg, IDC_FONTS_MIME_FONT_COMBO ), FALSE);
  1224. EnableWindow( GetDlgItem( hDlg, IDC_FONTS_CODE_PAGES_LIST ), FALSE);
  1225. EnableWindow( GetDlgItem( hDlg, IDC_FONTS_SETDEFAULT_BUTTON ), FALSE);
  1226. }
  1227. // everything ok
  1228. return TRUE;
  1229. } // FontsDlgInit()
  1230. //
  1231. // SaveFontsData()
  1232. //
  1233. // Save the new fonts settings into regestry
  1234. //
  1235. void SaveFontsData(LPFONTSDATA pFnt)
  1236. {
  1237. HKEY hkeyCodePage;
  1238. TCHAR szCodePage [MAX_MIMEFACE_NAME];
  1239. HKEY hkey;
  1240. DWORD dw;
  1241. // get values from registry
  1242. if (RegCreateKeyEx(HKEY_CURRENT_USER, pFnt->lpszKeyPath, NULL, NULL, NULL, KEY_WRITE, NULL, &hkey, &dw)
  1243. == ERROR_SUCCESS)
  1244. {
  1245. UINT i;
  1246. RegSetValueEx(hkey, REGSTR_VAL_DEFAULT_CODEPAGE, NULL, REG_BINARY, (LPBYTE)&pFnt->dwDefaultCodePage, sizeof(pFnt->dwDefaultCodePage));
  1247. for(i = 0; i < g_cCPInfo; i++)
  1248. {
  1249. if (g_pCPInfo[i].uiCodePage == g_pCPInfo[i].uiFamilyCodePage)
  1250. {
  1251. wnsprintf(szCodePage, ARRAYSIZE(szCodePage), TEXT("%u"), g_pCPInfo[i].uiCodePage);
  1252. if (RegCreateKeyEx(hkey, szCodePage, NULL, NULL, NULL, KEY_WRITE, NULL, &hkeyCodePage, &dw) == ERROR_SUCCESS)
  1253. {
  1254. UINT j;
  1255. RegSetValueEx(hkeyCodePage, REGSTR_VAL_FONT_SCRIPT, NULL, REG_SZ,
  1256. (LPBYTE)&pFnt->page[i].szFriendlyName,
  1257. (lstrlen(pFnt->page[i].szFriendlyName)+1)*sizeof(TCHAR));
  1258. for (j = 0; j < g_cCPInfo; j++)
  1259. {
  1260. if (!StrCmpI(g_pCPInfo[j].wszDescription, pFnt->page[i].szMIMEFont))
  1261. {
  1262. dw = g_pCPInfo[j].uiCodePage;
  1263. break;
  1264. }
  1265. }
  1266. RegSetValueEx(hkeyCodePage, REGSTR_VAL_DEF_INETENCODING, NULL, REG_BINARY,
  1267. (LPBYTE)&dw, sizeof(dw));
  1268. RegSetValueEx(hkeyCodePage, REGSTR_VAL_FIXED_FONT, NULL, REG_SZ,
  1269. (LPBYTE)pFnt->page[i].szFixedFont,
  1270. (lstrlen(pFnt->page[i].szFixedFont)+1)*sizeof(TCHAR));
  1271. RegSetValueEx(hkeyCodePage, REGSTR_VAL_PROP_FONT, NULL, REG_SZ,
  1272. (LPBYTE)pFnt->page[i].szPropFont,
  1273. (lstrlen(pFnt->page[i].szPropFont)+1)*sizeof(TCHAR));
  1274. RegSetValueEx(hkeyCodePage, REGSTR_VAL_FONT_SIZE, NULL, REG_BINARY,
  1275. (LPBYTE)&pFnt->page[i].dwFontSize,
  1276. sizeof(pFnt->page[i].dwFontSize));
  1277. RegCloseKey(hkeyCodePage);
  1278. } // if RegCreateKeyEx
  1279. } // if uiCodePage == uiFamilyCodePage
  1280. } // for
  1281. RegCloseKey(hkey);
  1282. } // if RegCreateKeyEx
  1283. } // SaveFontsData()
  1284. //
  1285. // FontsOnCommand()
  1286. //
  1287. // Handles WM_COMMAN Dmessage for the Fonts subdialog
  1288. //
  1289. BOOL FontsOnCommand(LPFONTSDATA pFnt, UINT id, UINT nCmd)
  1290. {
  1291. switch(id)
  1292. {
  1293. case IDOK:
  1294. if (pFnt->bChanged)
  1295. {
  1296. SaveFontsData(pFnt);
  1297. // tell MSHTML to pick up changes and update
  1298. UpdateAllWindows();
  1299. }
  1300. return TRUE; // exit dialog
  1301. case IDCANCEL:
  1302. return TRUE; // exit dialog
  1303. case IDC_FONTS_MIME_FONT_COMBO:
  1304. if (nCmd==CBN_SELCHANGE)
  1305. {
  1306. g_fChangedMime = TRUE; // tell MSHTML that the Mime has changed
  1307. }
  1308. // fall thru...
  1309. case IDC_FONTS_PROP_FONT_COMBO:
  1310. case IDC_FONTS_FIXED_FONT_COMBO:
  1311. case IDC_FONTS_SIZE_FONT_COMBO:
  1312. if (nCmd==CBN_SELCHANGE)
  1313. {
  1314. UINT i;
  1315. TCHAR szCodePage[MAX_MIMECP_NAME];
  1316. pFnt->bChanged = TRUE; // we need to save
  1317. // find the currently selected item in the list box
  1318. INT_PTR itmp = SendMessage(pFnt->hwndNamesLB, LB_GETCURSEL, 0, 0);
  1319. SendMessage(pFnt->hwndNamesLB, LB_GETTEXT, itmp, (LPARAM)szCodePage);
  1320. // find the code page from the text
  1321. for(i=0; i < g_cCPInfo; i++)
  1322. {
  1323. if (!StrCmpI(szCodePage, pFnt->page[i].szFriendlyName))
  1324. {
  1325. // grab the new values
  1326. GetDlgItemText(pFnt->hDlg, IDC_FONTS_PROP_FONT_COMBO,
  1327. pFnt->page[i].szPropFont, ARRAYSIZE(pFnt->page[i].szPropFont));
  1328. GetDlgItemText(pFnt->hDlg, IDC_FONTS_FIXED_FONT_COMBO,
  1329. pFnt->page[i].szFixedFont, ARRAYSIZE(pFnt->page[i].szFixedFont));
  1330. pFnt->page[i].dwFontSize = (int) SendMessage(pFnt->hwndSizeCB, CB_GETCURSEL, 0, 0);
  1331. GetDlgItemText(pFnt->hDlg, IDC_FONTS_MIME_FONT_COMBO,
  1332. pFnt->page[i].szMIMEFont, ARRAYSIZE(pFnt->page[i].szMIMEFont));
  1333. break;
  1334. }
  1335. }
  1336. // if we don't find it... we are going to keep the default
  1337. ASSERT(i < g_cCPInfo); // something went wrong
  1338. }
  1339. break;
  1340. case IDC_FONTS_SETDEFAULT_BUTTON:
  1341. {
  1342. UINT i;
  1343. TCHAR szCodePage[MAX_MIMECP_NAME];
  1344. pFnt->bChanged = TRUE; // we need to save
  1345. // get the newly selected charset
  1346. INT_PTR itmp = SendMessage(pFnt->hwndNamesLB, LB_GETCURSEL, 0, 0);
  1347. SendMessage(pFnt->hwndNamesLB, LB_GETTEXT, itmp, (LPARAM)szCodePage);
  1348. // set the newly selected charset text
  1349. SetDlgItemText(pFnt->hDlg, IDC_FONTS_DEFAULT_LANG_TEXT, szCodePage);
  1350. // find the code page from the text
  1351. for (i = 0; i < g_cCPInfo; i++)
  1352. {
  1353. if (!StrCmpI(szCodePage, pFnt->page[i].szFriendlyName))
  1354. {
  1355. pFnt->dwDefaultCodePage = g_pCPInfo[i].uiFamilyCodePage;
  1356. g_fChangedMime = TRUE;
  1357. break;
  1358. }
  1359. }
  1360. // if we don't find it... we are going to keep the default
  1361. ASSERT(i < g_cCPInfo); // something went wrong
  1362. }
  1363. break;
  1364. case IDC_FONTS_CODE_PAGES_LIST:
  1365. if (nCmd==LBN_SELCHANGE)
  1366. {
  1367. UINT i;
  1368. TCHAR szCodePage[MAX_MIMECP_NAME];
  1369. INT_PTR itmp = SendMessage(pFnt->hwndNamesLB, LB_GETCURSEL, 0, 0);
  1370. SendMessage(pFnt->hwndNamesLB, LB_GETTEXT, itmp, (LPARAM)szCodePage);
  1371. // find the code page from the text
  1372. for(i=0; i < g_cCPInfo; i++)
  1373. {
  1374. if (!StrCmpI(szCodePage, pFnt->page[i].szFriendlyName))
  1375. {
  1376. FillCharsetComboBoxes(pFnt, g_pCPInfo[i].uiFamilyCodePage);
  1377. break;
  1378. }
  1379. }
  1380. }
  1381. break;
  1382. }
  1383. // don't exit dialog
  1384. return FALSE;
  1385. }
  1386. //
  1387. // FontsDlgProc()
  1388. //
  1389. // Message handler for the "Fonts" subdialog.
  1390. //
  1391. INT_PTR CALLBACK FontsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1392. {
  1393. LPFONTSDATA pFnt = (LPFONTSDATA) GetWindowLongPtr(hDlg, DWLP_USER);
  1394. switch (uMsg)
  1395. {
  1396. case WM_INITDIALOG:
  1397. return FontsDlgInit(hDlg, (LPTSTR)lParam);
  1398. case WM_DESTROY:
  1399. // give back the memory
  1400. FreeMimeCsetTable();
  1401. // destroy font if we created
  1402. SHRemoveDefaultDialogFont(hDlg);
  1403. if (pFnt)
  1404. {
  1405. if (pFnt->page)
  1406. LocalFree(pFnt->page);
  1407. LocalFree(pFnt);
  1408. }
  1409. break;
  1410. case WM_COMMAND:
  1411. if (FontsOnCommand(pFnt, LOWORD(wParam), HIWORD(wParam)))
  1412. EndDialog(hDlg, LOWORD(wParam) == IDOK? 1: 0);
  1413. break;
  1414. case WM_HELP: // F1
  1415. ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  1416. HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1417. break;
  1418. case WM_CONTEXTMENU: // right mouse click
  1419. ResWinHelp( (HWND) wParam, IDS_HELPFILE,
  1420. HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1421. break;
  1422. default:
  1423. return FALSE;
  1424. }
  1425. return TRUE;
  1426. }
  1427. //
  1428. // EXTERNAL API
  1429. //
  1430. STDAPI_(INT_PTR) OpenFontsDialog(HWND hDlg, LPCSTR lpszKeyPath)
  1431. {
  1432. #ifdef UNICODE
  1433. WCHAR wszKeyPath[1024];
  1434. MultiByteToWideChar(CP_ACP, 0, (char *)lpszKeyPath, -1, wszKeyPath, ARRAYSIZE(wszKeyPath));
  1435. return DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_FONTS_IE4), hDlg, FontsDlgProc, (LPARAM) wszKeyPath);
  1436. #else
  1437. return DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_FONTS_IE4), hDlg, FontsDlgProc, (LPARAM) lpszKeyPath);
  1438. #endif // UNICODE
  1439. }
  1440. // provide script based font dialog
  1441. STDAPI_(INT_PTR) OpenFontsDialogEx(HWND hDlg, LPCTSTR lpszKeyPath)
  1442. {
  1443. INT_PTR nRet = -1;
  1444. HRESULT hr;
  1445. BOOL fOLEPresent;
  1446. if (hOLE32 != NULL)
  1447. {
  1448. fOLEPresent = TRUE;
  1449. }
  1450. else
  1451. {
  1452. fOLEPresent = _StartOLE32();
  1453. }
  1454. ASSERT(fOLEPresent);
  1455. if (fOLEPresent)
  1456. {
  1457. ASSERT(IS_VALID_HANDLE(hOLE32, MODULE));
  1458. ASSERT(IS_VALID_CODE_PTR(pCoInitialize, PCOINIT));
  1459. hr = pCoInitialize(NULL);
  1460. if (SUCCEEDED(hr))
  1461. {
  1462. nRet = DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_FONTS), hDlg, FontsDlgProcEx, (LPARAM) lpszKeyPath);
  1463. }
  1464. }
  1465. // Release interface
  1466. if (g_pMLFlnk2)
  1467. {
  1468. g_pMLFlnk2->Release();
  1469. g_pMLFlnk2 = NULL;
  1470. }
  1471. ASSERT(IS_VALID_CODE_PTR(pCoUninitialize, PCOUNIT));
  1472. pCoUninitialize();
  1473. return nRet;
  1474. }