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.

4508 lines
124 KiB

  1. /*++
  2. Copyright (c) 1990-1998, Microsoft Corporation All rights reserved.
  3. Module Name:
  4. font.c
  5. Abstract:
  6. This module implements the Win32 font dialog.
  7. Revision History:
  8. --*/
  9. // precompiled headers
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. #include "font.h"
  13. #include "cdids.h"
  14. #include "util.h"
  15. BOOL IsSimplifiedChineseUI(void)
  16. {
  17. BOOL bRet = FALSE;
  18. if (staticIsOS(OS_WIN2000ORGREATER)) // If NT5 or higher, we use system UI Language
  19. {
  20. static LANGID (CALLBACK* pfnGetUserDefaultUILanguage)(void) = NULL;
  21. if (pfnGetUserDefaultUILanguage == NULL)
  22. {
  23. HMODULE hmod = GetModuleHandle(TEXT("KERNEL32"));
  24. if (hmod)
  25. pfnGetUserDefaultUILanguage = (LANGID (CALLBACK*)(void))GetProcAddress(hmod, "GetUserDefaultUILanguage");
  26. }
  27. if (pfnGetUserDefaultUILanguage)
  28. {
  29. LANGID LangID = pfnGetUserDefaultUILanguage();
  30. if (LangID == MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED))
  31. bRet = TRUE;
  32. }
  33. }
  34. else // If Win9x and NT4, we use CP_ACP
  35. {
  36. if (936 == GetACP())
  37. bRet = TRUE;
  38. }
  39. return bRet;
  40. }
  41. #ifdef UNICODE
  42. ////////////////////////////////////////////////////////////////////////////
  43. //
  44. // ChooseFontA
  45. //
  46. // ANSI entry point for ChooseFont when this code is built UNICODE.
  47. //
  48. ////////////////////////////////////////////////////////////////////////////
  49. BOOL WINAPI ChooseFontA(
  50. LPCHOOSEFONTA pCFA)
  51. {
  52. LPCHOOSEFONTW pCFW;
  53. BOOL result;
  54. LPBYTE pStrMem;
  55. UNICODE_STRING usStyle;
  56. ANSI_STRING asStyle;
  57. int cchTemplateName = 0;
  58. FONTINFO FI;
  59. ZeroMemory(&FI, sizeof(FI));
  60. if (!pCFA)
  61. {
  62. StoreExtendedError(CDERR_INITIALIZATION);
  63. return (FALSE);
  64. }
  65. if (pCFA->lStructSize != sizeof(CHOOSEFONTA))
  66. {
  67. StoreExtendedError(CDERR_STRUCTSIZE);
  68. return (FALSE);
  69. }
  70. //
  71. // Setup and allocate CHOOSEFONTW structure.
  72. //
  73. if (!pCFA->lpLogFont && (pCFA->Flags & CF_INITTOLOGFONTSTRUCT))
  74. {
  75. StoreExtendedError(CDERR_INITIALIZATION);
  76. return (FALSE);
  77. }
  78. if (!(pCFW = (LPCHOOSEFONTW)LocalAlloc(
  79. LPTR,
  80. sizeof(CHOOSEFONTW) + sizeof(LOGFONTW) )))
  81. {
  82. StoreExtendedError(CDERR_MEMALLOCFAILURE);
  83. return (FALSE);
  84. }
  85. pCFW->lStructSize = sizeof(CHOOSEFONTW);
  86. pCFW->lpLogFont = (LPLOGFONTW)((LPCHOOSEFONTW)pCFW + 1);
  87. if (pCFA->Flags & CF_ENABLETEMPLATE)
  88. {
  89. if (!IS_INTRESOURCE(pCFA->lpTemplateName))
  90. {
  91. cchTemplateName = (lstrlenA(pCFA->lpTemplateName) + 1);
  92. if (!(pCFW->lpTemplateName = (LPWSTR)LocalAlloc( LPTR,
  93. cchTemplateName * sizeof(WCHAR))))
  94. {
  95. LocalFree(pCFW);
  96. StoreExtendedError(CDERR_MEMALLOCFAILURE);
  97. return (FALSE);
  98. }
  99. else
  100. {
  101. SHAnsiToUnicode(pCFA->lpTemplateName, (LPWSTR)pCFW->lpTemplateName, cchTemplateName);
  102. }
  103. }
  104. else
  105. {
  106. (DWORD_PTR)pCFW->lpTemplateName = (DWORD_PTR)pCFA->lpTemplateName;
  107. }
  108. }
  109. else
  110. {
  111. pCFW->lpTemplateName = NULL;
  112. }
  113. if ((pCFA->Flags & CF_USESTYLE) && (!IS_INTRESOURCE(pCFA->lpszStyle)))
  114. {
  115. asStyle.MaximumLength = LF_FACESIZE;
  116. asStyle.Length = (USHORT) (lstrlenA(pCFA->lpszStyle));
  117. if (asStyle.Length >= asStyle.MaximumLength)
  118. {
  119. asStyle.MaximumLength = asStyle.Length;
  120. }
  121. }
  122. else
  123. {
  124. asStyle.Length = usStyle.Length = 0;
  125. asStyle.MaximumLength = LF_FACESIZE;
  126. }
  127. usStyle.MaximumLength = asStyle.MaximumLength * sizeof(WCHAR);
  128. usStyle.Length = asStyle.Length * sizeof(WCHAR);
  129. if (!(pStrMem = (LPBYTE)LocalAlloc( LPTR,
  130. asStyle.MaximumLength +
  131. usStyle.MaximumLength )))
  132. {
  133. if (cchTemplateName)
  134. {
  135. LocalFree((LPWSTR)(pCFW->lpTemplateName));
  136. }
  137. LocalFree(pCFW);
  138. StoreExtendedError(CDERR_MEMALLOCFAILURE);
  139. return (FALSE);
  140. }
  141. asStyle.Buffer = pStrMem;
  142. pCFW->lpszStyle = usStyle.Buffer =
  143. (LPWSTR)(asStyle.Buffer + asStyle.MaximumLength);
  144. if ((pCFA->Flags & CF_USESTYLE) && (!IS_INTRESOURCE(pCFA->lpszStyle)))
  145. {
  146. // strcpy okay, Buffer is allocated to exact size
  147. lstrcpyA(asStyle.Buffer, pCFA->lpszStyle);
  148. }
  149. FI.pCF = pCFW;
  150. FI.pCFA = pCFA;
  151. FI.ApiType = COMDLG_ANSI;
  152. FI.pasStyle = &asStyle;
  153. FI.pusStyle = &usStyle;
  154. ThunkChooseFontA2W(&FI);
  155. if (result = ChooseFontX(&FI))
  156. {
  157. ThunkChooseFontW2A(&FI);
  158. //
  159. // Doesn't say how many characters there are here.
  160. //
  161. if ((pCFA->Flags & CF_USESTYLE) && (!IS_INTRESOURCE(pCFA->lpszStyle)))
  162. {
  163. LPSTR psz = pCFA->lpszStyle;
  164. LPSTR pszT = asStyle.Buffer;
  165. try
  166. {
  167. while (*psz++ = *pszT++);
  168. }
  169. except (EXCEPTION_ACCESS_VIOLATION)
  170. {
  171. //
  172. // Not enough space in the passed in string.
  173. //
  174. *--psz = '\0';
  175. }
  176. }
  177. }
  178. if (cchTemplateName)
  179. {
  180. LocalFree((LPWSTR)(pCFW->lpTemplateName));
  181. }
  182. LocalFree(pCFW);
  183. LocalFree(pStrMem);
  184. return (result);
  185. }
  186. #else
  187. ////////////////////////////////////////////////////////////////////////////
  188. //
  189. // ChooseFontW
  190. //
  191. // Stub UNICODE function for ChooseFont when this code is built ANSI.
  192. //
  193. ////////////////////////////////////////////////////////////////////////////
  194. BOOL WINAPI ChooseFontW(
  195. LPCHOOSEFONTW lpCFW)
  196. {
  197. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  198. return (FALSE);
  199. }
  200. #endif
  201. ////////////////////////////////////////////////////////////////////////////
  202. //
  203. // ChooseFont
  204. //
  205. // The ChooseFont function creates a system-defined dialog box from which
  206. // the user can select a font, a font style (such as bold or italic), a
  207. // point size, an effect (such as strikeout or underline), and a text
  208. // color.
  209. //
  210. ////////////////////////////////////////////////////////////////////////////
  211. BOOL WINAPI ChooseFont(
  212. LPCHOOSEFONT lpCF)
  213. {
  214. FONTINFO FI;
  215. ZeroMemory(&FI, sizeof(FI));
  216. FI.pCF = lpCF;
  217. FI.ApiType = COMDLG_WIDE;
  218. return ( ChooseFontX(&FI) );
  219. }
  220. ////////////////////////////////////////////////////////////////////////////
  221. //
  222. // ChooseFontX
  223. //
  224. // Invokes the font picker dialog, which lets the user specify common
  225. // character format attributes: facename, point size, text color and
  226. // attributes (bold, italic, strikeout or underline).
  227. //
  228. // lpCF - ptr to structure that will hold character attributes
  229. // ApiType - api type (COMDLG_WIDE or COMDLG_ANSI) so that the dialog
  230. // can remember which message to send to the user.
  231. //
  232. // Returns: TRUE - user pressed IDOK
  233. // FALSE - user pressed IDCANCEL
  234. //
  235. ////////////////////////////////////////////////////////////////////////////
  236. BOOL ChooseFontX(
  237. PFONTINFO pFI)
  238. {
  239. INT_PTR iRet; // font picker dialog return value
  240. HANDLE hDlgTemplate; // handle to loaded dialog resource
  241. HANDLE hRes; // handle of res. block with dialog
  242. int id;
  243. LPCHOOSEFONT lpCF = pFI->pCF;
  244. BOOL fAllocLogFont = FALSE;
  245. #ifdef UNICODE
  246. UINT uiWOWFlag = 0;
  247. #endif
  248. LANGID LangID;
  249. SetCursor(LoadCursor(NULL, IDC_WAIT));
  250. StoreExtendedError(0);
  251. g_bUserPressedCancel = FALSE;
  252. if (!lpCF)
  253. {
  254. StoreExtendedError(CDERR_INITIALIZATION);
  255. return (FALSE);
  256. }
  257. if (lpCF->lStructSize != sizeof(CHOOSEFONT))
  258. {
  259. StoreExtendedError(CDERR_STRUCTSIZE);
  260. return (FALSE);
  261. }
  262. if (!lpCF->lpLogFont)
  263. {
  264. if (!(lpCF->lpLogFont = (LPLOGFONT)LocalAlloc(LPTR, sizeof(LOGFONT))))
  265. {
  266. StoreExtendedError(CDERR_MEMALLOCFAILURE);
  267. return (FALSE);
  268. }
  269. fAllocLogFont = TRUE;
  270. }
  271. //
  272. // Get the process version of the app for later use.
  273. //
  274. pFI->ProcessVersion = GetProcessVersion(0);
  275. //
  276. // Get the default user language id for later use.
  277. //
  278. g_bIsSimplifiedChineseUI = IsSimplifiedChineseUI();
  279. //
  280. // Verify that lpfnHook is not null if CF_ENABLEHOOK is specified.
  281. //
  282. if (lpCF->Flags & CF_ENABLEHOOK)
  283. {
  284. if (!lpCF->lpfnHook)
  285. {
  286. if (fAllocLogFont)
  287. {
  288. LocalFree(lpCF->lpLogFont);
  289. lpCF->lpLogFont = NULL;
  290. }
  291. StoreExtendedError(CDERR_NOHOOK);
  292. return (FALSE);
  293. }
  294. }
  295. else
  296. {
  297. lpCF->lpfnHook = NULL;
  298. }
  299. if (lpCF->Flags & CF_ENABLETEMPLATE)
  300. {
  301. //
  302. // Both custom instance handle and the dialog template name are
  303. // user specified. Locate the dialog resource in the specified
  304. // instance block and load it.
  305. //
  306. if (!(hRes = FindResource(lpCF->hInstance, lpCF->lpTemplateName, RT_DIALOG)))
  307. {
  308. if (fAllocLogFont)
  309. {
  310. LocalFree(lpCF->lpLogFont);
  311. lpCF->lpLogFont = NULL;
  312. }
  313. StoreExtendedError(CDERR_FINDRESFAILURE);
  314. return (FALSE);
  315. }
  316. if (!(hDlgTemplate = LoadResource(lpCF->hInstance, hRes)))
  317. {
  318. if (fAllocLogFont)
  319. {
  320. LocalFree(lpCF->lpLogFont);
  321. lpCF->lpLogFont = NULL;
  322. }
  323. StoreExtendedError(CDERR_LOADRESFAILURE);
  324. return (FALSE);
  325. }
  326. LangID = GetDialogLanguage(lpCF->hwndOwner, hDlgTemplate);
  327. }
  328. else if (lpCF->Flags & CF_ENABLETEMPLATEHANDLE)
  329. {
  330. //
  331. // A handle to the pre-loaded resource has been specified.
  332. //
  333. hDlgTemplate = lpCF->hInstance;
  334. LangID = GetDialogLanguage(lpCF->hwndOwner, hDlgTemplate);
  335. }
  336. else
  337. {
  338. id = FORMATDLGORD31;
  339. LangID = GetDialogLanguage(lpCF->hwndOwner, NULL);
  340. if (!(hRes = FindResourceExFallback(g_hinst, RT_DIALOG, MAKEINTRESOURCE(id), LangID)))
  341. {
  342. if (fAllocLogFont)
  343. {
  344. LocalFree(lpCF->lpLogFont);
  345. lpCF->lpLogFont = NULL;
  346. }
  347. StoreExtendedError(CDERR_FINDRESFAILURE);
  348. return (FALSE);
  349. }
  350. if (!(hDlgTemplate = LoadResource(g_hinst, hRes)))
  351. {
  352. if (fAllocLogFont)
  353. {
  354. LocalFree(lpCF->lpLogFont);
  355. lpCF->lpLogFont = NULL;
  356. }
  357. StoreExtendedError(CDERR_LOADRESFAILURE);
  358. return (FALSE);
  359. }
  360. }
  361. //
  362. // Warning! Warning! Warning!
  363. //
  364. // We have to set g_tlsLangID before any call for CDLoadString
  365. //
  366. TlsSetValue(g_tlsLangID, (LPVOID) LangID);
  367. if (LockResource(hDlgTemplate))
  368. {
  369. if (lpCF->Flags & CF_ENABLEHOOK)
  370. {
  371. glpfnFontHook = GETHOOKFN(lpCF);
  372. }
  373. #ifdef UNICODE
  374. if (IS16BITWOWAPP(lpCF))
  375. {
  376. uiWOWFlag = SCDLG_16BIT;
  377. }
  378. iRet = DialogBoxIndirectParamAorW( g_hinst,
  379. (LPDLGTEMPLATE)hDlgTemplate,
  380. lpCF->hwndOwner,
  381. FormatCharDlgProc,
  382. (LPARAM)pFI,
  383. uiWOWFlag );
  384. #else
  385. iRet = DialogBoxIndirectParam( g_hinst,
  386. (LPDLGTEMPLATE)hDlgTemplate,
  387. lpCF->hwndOwner,
  388. FormatCharDlgProc,
  389. (LPARAM)pFI );
  390. #endif
  391. glpfnFontHook = 0;
  392. if (iRet == -1 || ((iRet == 0) && (!g_bUserPressedCancel) && (!GetStoredExtendedError())))
  393. {
  394. StoreExtendedError(CDERR_DIALOGFAILURE);
  395. }
  396. }
  397. else
  398. {
  399. iRet = -1;
  400. StoreExtendedError(CDERR_LOCKRESFAILURE);
  401. }
  402. if (fAllocLogFont)
  403. {
  404. LocalFree(lpCF->lpLogFont);
  405. lpCF->lpLogFont = NULL;
  406. }
  407. return (iRet == IDOK);
  408. }
  409. ////////////////////////////////////////////////////////////////////////////
  410. //
  411. // SetStyleSelection
  412. //
  413. ////////////////////////////////////////////////////////////////////////////
  414. VOID SetStyleSelection(
  415. HWND hDlg,
  416. LPCHOOSEFONT lpcf,
  417. BOOL bInit)
  418. {
  419. if (!(lpcf->Flags & CF_NOSTYLESEL))
  420. {
  421. if (bInit && (lpcf->Flags & CF_USESTYLE))
  422. {
  423. PLOGFONT plf;
  424. int iSel;
  425. iSel = CBSetSelFromText(GetDlgItem(hDlg, cmb2), lpcf->lpszStyle);
  426. if (iSel >= 0)
  427. {
  428. LPITEMDATA lpItemData =
  429. (LPITEMDATA)SendDlgItemMessage( hDlg,
  430. cmb2,
  431. CB_GETITEMDATA,
  432. iSel,
  433. 0L );
  434. if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR))
  435. {
  436. plf = lpItemData->pLogFont;
  437. lpcf->lpLogFont->lfWeight = plf->lfWeight;
  438. lpcf->lpLogFont->lfItalic = plf->lfItalic;
  439. }
  440. else
  441. {
  442. lpcf->lpLogFont->lfWeight = FW_NORMAL;
  443. lpcf->lpLogFont->lfItalic = 0;
  444. }
  445. }
  446. else
  447. {
  448. lpcf->lpLogFont->lfWeight = FW_NORMAL;
  449. lpcf->lpLogFont->lfItalic = 0;
  450. }
  451. }
  452. else
  453. {
  454. SelectStyleFromLF(GetDlgItem(hDlg, cmb2), lpcf->lpLogFont);
  455. }
  456. CBSetTextFromSel(GetDlgItem(hDlg, cmb2));
  457. }
  458. }
  459. ////////////////////////////////////////////////////////////////////////////
  460. //
  461. // HideDlgItem
  462. //
  463. ////////////////////////////////////////////////////////////////////////////
  464. VOID HideDlgItem(
  465. HWND hDlg,
  466. int id)
  467. {
  468. EnableWindow(GetDlgItem(hDlg, id), FALSE);
  469. ShowWindow(GetDlgItem(hDlg, id), SW_HIDE);
  470. }
  471. ////////////////////////////////////////////////////////////////////////////
  472. //
  473. // FixComboHeights
  474. //
  475. // Fixes the ownerdraw combo boxes to match the height of the non
  476. // ownerdraw combo boxes.
  477. //
  478. ////////////////////////////////////////////////////////////////////////////
  479. VOID FixComboHeights(
  480. HWND hDlg)
  481. {
  482. LPARAM height;
  483. height = SendDlgItemMessage(hDlg, cmb2, CB_GETITEMHEIGHT, (WPARAM)-1, 0L);
  484. SendDlgItemMessage(hDlg, cmb1, CB_SETITEMHEIGHT, (WPARAM)-1, height);
  485. SendDlgItemMessage(hDlg, cmb3, CB_SETITEMHEIGHT, (WPARAM)-1, height);
  486. }
  487. BOOL_PTR HandleFontDlgInitialize(FONTINFO *pFI, HWND hDlg, WPARAM wParam)
  488. {
  489. TCHAR szPoints[20];
  490. HDC hdc;
  491. HWND hWndHelp; // handle to Help... pushbutton
  492. LPCHOOSEFONT pCF;
  493. if (!CDLoadString(g_hinst, iszRegular, (LPTSTR)szRegular, ARRAYSIZE(szRegular)) ||
  494. !CDLoadString(g_hinst, iszBold, (LPTSTR)szBold, ARRAYSIZE(szBold)) ||
  495. !CDLoadString(g_hinst, iszItalic, (LPTSTR)szItalic, ARRAYSIZE(szItalic)) ||
  496. !CDLoadString(g_hinst, iszBoldItalic, (LPTSTR)szBoldItalic, ARRAYSIZE(szBoldItalic)))
  497. {
  498. StoreExtendedError(CDERR_LOADSTRFAILURE);
  499. EndDialog(hDlg, FALSE);
  500. return (FALSE);
  501. }
  502. pCF = pFI->pCF;
  503. if ((pCF->Flags & CF_LIMITSIZE) &&
  504. (pCF->nSizeMax < pCF->nSizeMin))
  505. {
  506. StoreExtendedError(CFERR_MAXLESSTHANMIN);
  507. EndDialog(hDlg, FALSE);
  508. return (FALSE);
  509. }
  510. //
  511. // Save ptr to CHOOSEFONT struct in the dialog's prop list.
  512. // Alloc a temp LOGFONT struct to be used for the length of
  513. // the dialog session, the contents of which will be copied
  514. // over to the final LOGFONT (pointed to by CHOOSEFONT)
  515. // only if <OK> is selected.
  516. //
  517. SetProp(hDlg, FONTPROP, (HANDLE)pFI);
  518. glpfnFontHook = 0;
  519. hDlgFont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0L);
  520. if (!hbmFont)
  521. {
  522. hbmFont = LoadBitmaps(BMFONT);
  523. }
  524. if (!(pCF->Flags & CF_APPLY))
  525. {
  526. HideDlgItem(hDlg, psh3);
  527. }
  528. if (!(pCF->Flags & CF_EFFECTS))
  529. {
  530. HideDlgItem(hDlg, stc4);
  531. HideDlgItem(hDlg, cmb4);
  532. }
  533. else
  534. {
  535. short nIndex;
  536. // Fill color list.
  537. FillColorCombo(hDlg);
  538. for (nIndex = CCHCOLORS - 1; nIndex > 0; nIndex--)
  539. {
  540. DWORD dw = (DWORD) SendDlgItemMessage(hDlg, cmb4, CB_GETITEMDATA, nIndex, 0);
  541. if (pCF->rgbColors == dw)
  542. {
  543. break;
  544. }
  545. }
  546. SendDlgItemMessage(hDlg, cmb4, CB_SETCURSEL, nIndex, 0);
  547. }
  548. GetWindowRect(GetDlgItem (hDlg, stc5), &pFI->rcText);
  549. MapWindowPoints(NULL, hDlg, (POINT *)(&pFI->rcText), 2);
  550. FixComboHeights(hDlg);
  551. // Init our LOGFONT.
  552. if (!(pCF->Flags & CF_INITTOLOGFONTSTRUCT))
  553. {
  554. InitLF(pCF->lpLogFont);
  555. }
  556. // Init effects.
  557. if (!(pCF->Flags & CF_EFFECTS))
  558. {
  559. HideDlgItem(hDlg, grp1);
  560. HideDlgItem(hDlg, chx1);
  561. HideDlgItem(hDlg, chx2);
  562. }
  563. else
  564. {
  565. CheckDlgButton(hDlg, chx1, pCF->lpLogFont->lfStrikeOut);
  566. CheckDlgButton(hDlg, chx2, pCF->lpLogFont->lfUnderline);
  567. }
  568. pFI->nLastFontType = 0;
  569. if (!GetFontFamily( hDlg,
  570. pCF->hDC,
  571. pCF->Flags,
  572. pCF->lpLogFont->lfCharSet ))
  573. {
  574. StoreExtendedError(CFERR_NOFONTS);
  575. if (pCF->Flags & CF_ENABLEHOOK)
  576. {
  577. glpfnFontHook = GETHOOKFN(pCF);
  578. }
  579. EndDialog(hDlg, FALSE);
  580. return (FALSE);
  581. }
  582. if (!(pCF->Flags & CF_NOFACESEL) && *pCF->lpLogFont->lfFaceName)
  583. {
  584. BOOL bContinueChecking;
  585. LPTSTR lpRealFontName, lpSubFontName;
  586. // We want to select the font the user has requested.
  587. int iResult = CBSetSelFromText(GetDlgItem(hDlg, cmb1), pCF->lpLogFont->lfFaceName);
  588. // If iResult == CB_ERR, then we could be working with a
  589. // font subsitution name (eg: MS Shell Dlg).
  590. if (iResult == CB_ERR)
  591. {
  592. lpSubFontName = pCF->lpLogFont->lfFaceName;
  593. }
  594. // Allocate a buffer to store the real font name in.
  595. lpRealFontName = GlobalAlloc(GPTR, MAX_PATH * sizeof(TCHAR));
  596. if (!lpRealFontName)
  597. {
  598. StoreExtendedError(CDERR_MEMALLOCFAILURE);
  599. EndDialog(hDlg, FALSE);
  600. return (FALSE);
  601. }
  602. // The while loop is necessary in order to resolve
  603. // substitions pointing to subsitutions.
  604. // eg: Helv->MS Shell Dlg->MS Sans Serif
  605. bContinueChecking = TRUE;
  606. while ((iResult == CB_ERR) && bContinueChecking)
  607. {
  608. bContinueChecking = LookUpFontSubs(lpSubFontName, lpRealFontName, MAX_PATH);
  609. // If bContinueChecking is TRUE, then we have a font
  610. // name. Try to select that in the list.
  611. if (bContinueChecking)
  612. {
  613. iResult = CBSetSelFromText(GetDlgItem(hDlg, cmb1), lpRealFontName );
  614. }
  615. lpSubFontName = lpRealFontName;
  616. }
  617. //
  618. // Free our buffer.
  619. //
  620. GlobalFree(lpRealFontName);
  621. //
  622. // Set the edit control text if appropriate.
  623. //
  624. if (iResult != CB_ERR)
  625. {
  626. CBSetTextFromSel(GetDlgItem(hDlg, cmb1));
  627. }
  628. }
  629. hdc = GetDC(NULL);
  630. if (pCF->Flags & CF_NOSCRIPTSEL)
  631. {
  632. hWndHelp = GetDlgItem(hDlg, cmb5);
  633. if (hWndHelp)
  634. {
  635. CDLoadString( g_hinst,
  636. iszNoScript,
  637. szPoints,
  638. ARRAYSIZE(szPoints));
  639. CBAddScript(hWndHelp, szPoints, DEFAULT_CHARSET);
  640. EnableWindow(hWndHelp, FALSE);
  641. }
  642. DefaultCharset = DEFAULT_CHARSET;
  643. pFI->iCharset = DEFAULT_CHARSET;
  644. }
  645. else if (pCF->Flags & (CF_SELECTSCRIPT | CF_INITTOLOGFONTSTRUCT))
  646. {
  647. //
  648. // We could come in here with a bogus value, if the app is
  649. // NOT 4.0, that would result in the bogus charset not
  650. // being found for the facename, and the default would be
  651. // put back again anyway.
  652. //
  653. pFI->iCharset = pCF->lpLogFont->lfCharSet;
  654. }
  655. else
  656. {
  657. DefaultCharset = GetTextCharset(hdc);
  658. pFI->iCharset = DefaultCharset;
  659. }
  660. GetFontStylesAndSizes(hDlg, pFI, pCF, TRUE);
  661. if (!(pCF->Flags & CF_NOSTYLESEL))
  662. {
  663. SetStyleSelection(hDlg, pCF, TRUE);
  664. }
  665. if (!(pCF->Flags & CF_NOSIZESEL) && pCF->lpLogFont->lfHeight)
  666. {
  667. GetPointString(szPoints, ARRAYSIZE(szPoints), hdc, pCF->lpLogFont->lfHeight);
  668. CBSetSelFromText(GetDlgItem(hDlg, cmb3), szPoints);
  669. SetDlgItemText(hDlg, cmb3, szPoints);
  670. }
  671. ReleaseDC(NULL, hdc);
  672. //
  673. // Hide the help button if it isn't needed.
  674. //
  675. if (!(pCF->Flags & CF_SHOWHELP))
  676. {
  677. ShowWindow(hWndHelp = GetDlgItem(hDlg, pshHelp), SW_HIDE);
  678. EnableWindow(hWndHelp, FALSE);
  679. }
  680. SendDlgItemMessage(hDlg, cmb1, CB_LIMITTEXT, LF_FACESIZE - 1, 0L);
  681. SendDlgItemMessage(hDlg, cmb2, CB_LIMITTEXT, LF_FACESIZE - 1, 0L);
  682. SendDlgItemMessage(hDlg, cmb3, CB_LIMITTEXT, 5, 0L);
  683. //
  684. // If hook function has been specified, let it do any additional
  685. // processing of this message.
  686. //
  687. if (pCF->lpfnHook)
  688. {
  689. BOOL_PTR bRet;
  690. LPCFHOOKPROC lpfnHook = GETHOOKFN(pCF);
  691. #ifdef UNICODE
  692. if (pFI->ApiType == COMDLG_ANSI)
  693. {
  694. ThunkChooseFontW2A(pFI);
  695. bRet = (*lpfnHook)(hDlg, WM_INITDIALOG, wParam, (LPARAM)pFI->pCFA);
  696. ThunkChooseFontA2W(pFI);
  697. }
  698. else
  699. #endif
  700. {
  701. bRet = (*lpfnHook)(hDlg, WM_INITDIALOG, wParam, (LPARAM)pCF);
  702. }
  703. return (bRet);
  704. }
  705. SetCursor(LoadCursor(NULL, IDC_ARROW));
  706. return TRUE;
  707. }
  708. ////////////////////////////////////////////////////////////////////////////
  709. //
  710. // FormatCharDlgProc
  711. //
  712. // Message handler for font dlg
  713. //
  714. // chx1 - "underline" checkbox
  715. // chx2 - "strikeout" checkbox
  716. // psh4 - "help" pushbutton
  717. //
  718. // On WM_INITDIALOG message, the choosefont is accessed via lParam,
  719. // and stored in the window's prop list. If a hook function has been
  720. // specified, it is invoked AFTER the current function has processed
  721. // WM_INITDIALOG.
  722. //
  723. // For all other messages, control is passed directly to the hook
  724. // function first. Depending on the latter's return value, the message
  725. // is processed by this function.
  726. //
  727. ////////////////////////////////////////////////////////////////////////////
  728. BOOL_PTR CALLBACK FormatCharDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  729. {
  730. PFONTINFO pFI;
  731. LPCHOOSEFONT pCF = NULL; // ptr to struct passed to ChooseFont()
  732. BOOL_PTR bRet;
  733. //
  734. // If CHOOSEFONT struct has already been accessed and if a hook
  735. // function is specified, let it do the processing first.
  736. //
  737. if (pFI = (PFONTINFO)GetProp(hDlg, FONTPROP))
  738. {
  739. if ((pCF = (LPCHOOSEFONT)pFI->pCF) &&
  740. (pCF->lpfnHook))
  741. {
  742. LPCFHOOKPROC lpfnHook = GETHOOKFN(pCF);
  743. if ((bRet = (*lpfnHook)(hDlg, wMsg, wParam, lParam)))
  744. {
  745. if ((wMsg == WM_COMMAND) &&
  746. (GET_WM_COMMAND_ID(wParam, lParam) == IDCANCEL))
  747. {
  748. //
  749. // Set global flag stating that the user pressed cancel.
  750. //
  751. g_bUserPressedCancel = TRUE;
  752. }
  753. return (bRet);
  754. }
  755. }
  756. }
  757. else
  758. {
  759. if (glpfnFontHook &&
  760. (wMsg != WM_INITDIALOG) &&
  761. (bRet = (* glpfnFontHook)(hDlg, wMsg, wParam, lParam)))
  762. {
  763. return (bRet);
  764. }
  765. }
  766. switch (wMsg)
  767. {
  768. case ( WM_INITDIALOG ) :
  769. {
  770. return HandleFontDlgInitialize((PFONTINFO)lParam, hDlg, wParam);
  771. }
  772. case ( WM_DESTROY ) :
  773. {
  774. if (pCF)
  775. {
  776. RemoveProp(hDlg, FONTPROP);
  777. }
  778. break;
  779. }
  780. case ( WM_PAINT ) :
  781. {
  782. PAINTSTRUCT ps;
  783. if (!pFI)
  784. {
  785. return (FALSE);
  786. }
  787. if (BeginPaint(hDlg, &ps))
  788. {
  789. DrawSampleText(hDlg, pFI, pCF, ps.hdc);
  790. EndPaint(hDlg, &ps);
  791. }
  792. break;
  793. }
  794. case ( WM_MEASUREITEM ) :
  795. {
  796. TEXTMETRIC tm;
  797. HDC hDC = GetDC(hDlg);
  798. HFONT hFont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0L);
  799. if (hFont)
  800. {
  801. hFont = SelectObject(hDC, hFont);
  802. }
  803. GetTextMetrics(hDC, &tm);
  804. if (hFont)
  805. {
  806. SelectObject(hDC, hFont);
  807. }
  808. ReleaseDC(hDlg, hDC);
  809. if (((LPMEASUREITEMSTRUCT)lParam)->itemID != -1)
  810. {
  811. ((LPMEASUREITEMSTRUCT)lParam)->itemHeight =
  812. max(tm.tmHeight, DY_BITMAP);
  813. }
  814. else
  815. {
  816. //
  817. // This is for 3.0 only. In 3.1, the CB_SETITEMHEIGHT
  818. // will fix this. Note, this is off by one on 8514.
  819. //
  820. ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = tm.tmHeight + 1;
  821. }
  822. break;
  823. }
  824. case ( WM_DRAWITEM ) :
  825. {
  826. #define lpdis ((LPDRAWITEMSTRUCT)lParam)
  827. if (lpdis->itemID == (UINT)-1)
  828. {
  829. break;
  830. }
  831. if (lpdis->CtlID == cmb4)
  832. {
  833. DrawColorComboItem(lpdis);
  834. }
  835. else if (lpdis->CtlID == cmb1)
  836. {
  837. DrawFamilyComboItem(lpdis);
  838. }
  839. else
  840. {
  841. DrawSizeComboItem(lpdis);
  842. }
  843. break;
  844. #undef lpdis
  845. }
  846. case ( WM_SYSCOLORCHANGE ) :
  847. {
  848. DeleteObject(hbmFont);
  849. hbmFont = LoadBitmaps(BMFONT);
  850. break;
  851. }
  852. case ( WM_COMMAND ) :
  853. {
  854. if (!pFI)
  855. {
  856. return (FALSE);
  857. }
  858. return (ProcessDlgCtrlCommand(hDlg, pFI,
  859. GET_WM_COMMAND_ID(wParam, lParam),
  860. GET_WM_COMMAND_CMD(wParam, lParam),
  861. GET_WM_COMMAND_HWND(wParam, lParam)));
  862. break;
  863. }
  864. case ( WM_HELP ) :
  865. {
  866. if (IsWindowEnabled(hDlg))
  867. {
  868. WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle,
  869. NULL,
  870. HELP_WM_HELP,
  871. (ULONG_PTR)(LPVOID)aFontHelpIDs );
  872. }
  873. break;
  874. }
  875. case ( WM_CONTEXTMENU ) :
  876. {
  877. if (IsWindowEnabled(hDlg))
  878. {
  879. WinHelp( (HWND)wParam,
  880. NULL,
  881. HELP_CONTEXTMENU,
  882. (ULONG_PTR)(LPVOID)aFontHelpIDs );
  883. }
  884. break;
  885. }
  886. case ( WM_CHOOSEFONT_GETLOGFONT ) :
  887. {
  888. Handle_WM_CHOOSEFONT_GETLOGFONT:
  889. if (!pFI)
  890. {
  891. return (FALSE);
  892. }
  893. #ifdef UNICODE
  894. if (pFI->ApiType == COMDLG_ANSI)
  895. {
  896. BOOL bRet;
  897. LOGFONT lf;
  898. bRet = FillInFont(hDlg, pFI, pCF, &lf, TRUE);
  899. ThunkLogFontW2A(&lf, (LPLOGFONTA)lParam);
  900. return (bRet);
  901. }
  902. else
  903. #endif
  904. {
  905. return (FillInFont(hDlg, pFI, pCF, (LPLOGFONT)lParam, TRUE));
  906. }
  907. }
  908. case ( WM_CHOOSEFONT_SETLOGFONT ) :
  909. {
  910. if (!pFI)
  911. {
  912. return (FALSE);
  913. }
  914. #ifdef UNICODE
  915. if (pFI->ApiType == COMDLG_ANSI)
  916. {
  917. LOGFONT lf;
  918. ThunkLogFontA2W((LPLOGFONTA)lParam, &lf);
  919. return (SetLogFont(hDlg, pCF, &lf));
  920. }
  921. else
  922. #endif
  923. {
  924. return (SetLogFont(hDlg, pCF, (LPLOGFONT)lParam));
  925. }
  926. break;
  927. }
  928. case ( WM_CHOOSEFONT_SETFLAGS ) :
  929. {
  930. if (pCF)
  931. {
  932. DWORD dwFlags = pCF->Flags;
  933. pCF->Flags = (DWORD) lParam;
  934. SetDlgMsgResult(hDlg, WM_CHOOSEFONT_SETFLAGS, dwFlags);
  935. }
  936. return (TRUE);
  937. }
  938. default :
  939. {
  940. if (wMsg == msgWOWCHOOSEFONT_GETLOGFONT)
  941. {
  942. goto Handle_WM_CHOOSEFONT_GETLOGFONT;
  943. }
  944. return (FALSE);
  945. }
  946. }
  947. return (TRUE);
  948. }
  949. ////////////////////////////////////////////////////////////////////////////
  950. //
  951. // SelectStyleFromLF
  952. //
  953. // Given a logfont, selects the closest match in the style list.
  954. //
  955. ////////////////////////////////////////////////////////////////////////////
  956. void SelectStyleFromLF(
  957. HWND hwnd,
  958. LPLOGFONT lplf)
  959. {
  960. int ctr, count, iSel;
  961. PLOGFONT plf;
  962. int weight_delta, best_weight_delta = 1000;
  963. BOOL bIgnoreItalic;
  964. LPITEMDATA lpItemData;
  965. count = (int)SendMessage(hwnd, CB_GETCOUNT, 0, 0L);
  966. iSel = 0;
  967. bIgnoreItalic = FALSE;
  968. TryAgain:
  969. for (ctr = 0; ctr < count; ctr++)
  970. {
  971. lpItemData = (LPITEMDATA)SendMessage(hwnd, CB_GETITEMDATA, ctr, 0L);
  972. if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR))
  973. {
  974. plf = lpItemData->pLogFont;
  975. if (bIgnoreItalic ||
  976. (plf->lfItalic && lplf->lfItalic) ||
  977. (!plf->lfItalic && !lplf->lfItalic))
  978. {
  979. weight_delta = lplf->lfWeight - plf->lfWeight;
  980. if (weight_delta < 0)
  981. {
  982. weight_delta = -weight_delta;
  983. }
  984. if (weight_delta < best_weight_delta)
  985. {
  986. best_weight_delta = weight_delta;
  987. iSel = ctr;
  988. }
  989. }
  990. }
  991. }
  992. if (!bIgnoreItalic && iSel == 0)
  993. {
  994. bIgnoreItalic = TRUE;
  995. goto TryAgain;
  996. }
  997. SendMessage(hwnd, CB_SETCURSEL, iSel, 0L);
  998. }
  999. ////////////////////////////////////////////////////////////////////////////
  1000. //
  1001. // CBSetTextFromSel
  1002. //
  1003. // Makes the currently selected item the edit text for a combo box.
  1004. //
  1005. ////////////////////////////////////////////////////////////////////////////
  1006. int CBSetTextFromSel(
  1007. HWND hwnd)
  1008. {
  1009. int iSel;
  1010. TCHAR szFace[LF_FACESIZE];
  1011. iSel = (int)SendMessage(hwnd, CB_GETCURSEL, 0, 0L);
  1012. if (iSel >= 0)
  1013. {
  1014. // hwnd edits cmb1, cmb2, cmb3 which this is called for have been limited to LF_FACESIZE - 1 or less.
  1015. SendMessage(hwnd, CB_GETLBTEXT, iSel, (LONG_PTR)(LPTSTR)szFace);
  1016. SetWindowText(hwnd, szFace);
  1017. }
  1018. return (iSel);
  1019. }
  1020. ////////////////////////////////////////////////////////////////////////////
  1021. //
  1022. // CBSetSelFromText
  1023. //
  1024. // Sets the selection based on lpszString. Sends notification messages
  1025. // if bNotify is TRUE.
  1026. //
  1027. ////////////////////////////////////////////////////////////////////////////
  1028. int CBSetSelFromText(
  1029. HWND hwnd,
  1030. LPTSTR lpszString)
  1031. {
  1032. int iInd;
  1033. iInd = CBFindString(hwnd, lpszString);
  1034. if (iInd >= 0)
  1035. {
  1036. SendMessage(hwnd, CB_SETCURSEL, iInd, 0L);
  1037. }
  1038. return (iInd);
  1039. }
  1040. ////////////////////////////////////////////////////////////////////////////
  1041. //
  1042. // CBGetTextAndData
  1043. //
  1044. // Returns the text and item data for a combo box based on the current
  1045. // edit text. If the current edit text does not match anything in the
  1046. // listbox, then CB_ERR is returned.
  1047. //
  1048. ////////////////////////////////////////////////////////////////////////////
  1049. int CBGetTextAndData(
  1050. HWND hwnd,
  1051. LPTSTR lpszString,
  1052. int iSize,
  1053. PULONG_PTR lpdw)
  1054. {
  1055. LRESULT Result;
  1056. int iSel;
  1057. if (lpszString == NULL)
  1058. {
  1059. if ((Result = SendMessage(hwnd, CB_GETITEMDATA, 0, 0L)) < 0)
  1060. {
  1061. return ((int) Result);
  1062. }
  1063. else
  1064. {
  1065. *lpdw = Result;
  1066. return (0);
  1067. }
  1068. }
  1069. GetWindowText(hwnd, lpszString, iSize);
  1070. iSel = CBFindString(hwnd, lpszString);
  1071. if (iSel < 0)
  1072. {
  1073. return (iSel);
  1074. }
  1075. *lpdw = SendMessage(hwnd, CB_GETITEMDATA, iSel, 0L);
  1076. return (iSel);
  1077. }
  1078. ////////////////////////////////////////////////////////////////////////////
  1079. //
  1080. // CBFindString
  1081. //
  1082. // Does an exact string find and returns the index.
  1083. //
  1084. ////////////////////////////////////////////////////////////////////////////
  1085. int CBFindString(
  1086. HWND hwnd,
  1087. LPTSTR lpszString)
  1088. {
  1089. return ((int)SendMessage( hwnd,
  1090. CB_FINDSTRINGEXACT,
  1091. (WPARAM)-1,
  1092. (LPARAM)(LPCSTR)lpszString ));
  1093. }
  1094. ////////////////////////////////////////////////////////////////////////////
  1095. //
  1096. // GetPointSizeInRange
  1097. //
  1098. // Ensures that the point size edit field is in range.
  1099. //
  1100. // Returns: Point Size - of the edit field limitted by MIN/MAX size
  1101. // 0 - if the field is empty
  1102. //
  1103. ////////////////////////////////////////////////////////////////////////////
  1104. #define GPS_COMPLAIN 0x0001
  1105. #define GPS_SETDEFSIZE 0x0002
  1106. BOOL GetPointSizeInRange(
  1107. HWND hDlg,
  1108. LPCHOOSEFONT lpcf,
  1109. LPINT pts,
  1110. WORD wFlags)
  1111. {
  1112. TCHAR szBuffer[90];
  1113. TCHAR szTitle[90];
  1114. int nTmp;
  1115. int nTmpFr = 0;
  1116. BOOL bOK;
  1117. *pts = 0;
  1118. if (GetDlgItemText(hDlg, cmb3, szBuffer, ARRAYSIZE(szBuffer)))
  1119. {
  1120. nTmp = GetDlgItemInt(hDlg, cmb3, &bOK, TRUE);
  1121. if (!bOK && g_bIsSimplifiedChineseUI)
  1122. {
  1123. int ctr;
  1124. LPTSTR lpsz = szBuffer;
  1125. //
  1126. // Skip leading white space.
  1127. //
  1128. while (*lpsz == TEXT(' '))
  1129. {
  1130. lpsz++;
  1131. }
  1132. for (ctr = 0; ctr < NUM_ZIHAO; ctr++)
  1133. {
  1134. if (!lstrcmpi(lpsz, stZihao[ctr].name))
  1135. {
  1136. bOK = TRUE;
  1137. nTmp = stZihao[ctr].size;
  1138. nTmpFr = stZihao[ctr].sizeFr;
  1139. break;
  1140. }
  1141. }
  1142. }
  1143. if (!bOK)
  1144. {
  1145. nTmp = 0;
  1146. }
  1147. }
  1148. else if (wFlags & GPS_SETDEFSIZE)
  1149. {
  1150. nTmp = DEF_POINT_SIZE;
  1151. bOK = TRUE;
  1152. }
  1153. else
  1154. {
  1155. //
  1156. // We're just returning with 0 in *pts.
  1157. //
  1158. return (FALSE);
  1159. }
  1160. //
  1161. // Check that we got a number in range.
  1162. //
  1163. if (wFlags & GPS_COMPLAIN)
  1164. {
  1165. if ((lpcf->Flags & CF_LIMITSIZE) &&
  1166. (!bOK || (nTmp > lpcf->nSizeMax) || (nTmp < lpcf->nSizeMin)))
  1167. {
  1168. bOK = FALSE;
  1169. CDLoadString( g_hinst,
  1170. iszSizeRange,
  1171. szTitle,
  1172. ARRAYSIZE(szTitle));
  1173. wnsprintf( (LPTSTR)szBuffer, ARRAYSIZE(szBuffer),
  1174. (LPTSTR)szTitle,
  1175. lpcf->nSizeMin,
  1176. lpcf->nSizeMax );
  1177. }
  1178. else if (!bOK)
  1179. {
  1180. CDLoadString( g_hinst,
  1181. iszSizeNumber,
  1182. szBuffer,
  1183. ARRAYSIZE(szBuffer));
  1184. }
  1185. if (!bOK)
  1186. {
  1187. GetWindowText(hDlg, szTitle, ARRAYSIZE(szTitle));
  1188. MessageBox(hDlg, szBuffer, szTitle, MB_OK | MB_ICONINFORMATION);
  1189. return (FALSE);
  1190. }
  1191. }
  1192. *pts = nTmp * 10 + nTmpFr;
  1193. return (TRUE);
  1194. }
  1195. const struct {
  1196. int nCharSet;
  1197. UINT uCodePage;
  1198. } g_CharSetTransTable[] =
  1199. {
  1200. ANSI_CHARSET, 1252,
  1201. EASTEUROPE_CHARSET, 1250,
  1202. RUSSIAN_CHARSET, 1251,
  1203. GREEK_CHARSET, 1253,
  1204. TURKISH_CHARSET, 1254,
  1205. HEBREW_CHARSET, 1255,
  1206. ARABIC_CHARSET, 1256,
  1207. BALTIC_CHARSET, 1257,
  1208. VIETNAMESE_CHARSET, 1258,
  1209. THAI_CHARSET, 874,
  1210. SHIFTJIS_CHARSET, 932,
  1211. GB2312_CHARSET, 936,
  1212. HANGEUL_CHARSET, 949,
  1213. CHINESEBIG5_CHARSET, 950,
  1214. JOHAB_CHARSET, 1361,
  1215. DEFAULT_CHARSET, 0,
  1216. };
  1217. UINT CharsetToCodepage(int iCharset)
  1218. {
  1219. int i;
  1220. for (i=0;i<ARRAYSIZE(g_CharSetTransTable);i++)
  1221. if (iCharset == g_CharSetTransTable[i].nCharSet)
  1222. return g_CharSetTransTable[i].uCodePage;
  1223. return 0;
  1224. }
  1225. ////////////////////////////////////////////////////////////////////////////
  1226. //
  1227. // ResetSampleFromScript
  1228. //
  1229. ////////////////////////////////////////////////////////////////////////////
  1230. BOOL ResetSampleFromScript(HWND hDlg, HWND hwndScript, PFONTINFO pFI)
  1231. {
  1232. int iSel;
  1233. TCHAR szScript[LF_FACESIZE];
  1234. LPITEMDATA lpItemData;
  1235. if (IsWindow(hwndScript) && IsWindowEnabled(hwndScript))
  1236. {
  1237. iSel = (int)SendMessage(hwndScript, CB_GETCURSEL, 0, 0L);
  1238. if (iSel >= 0)
  1239. {
  1240. lpItemData = (LPITEMDATA)SendMessage( hwndScript,
  1241. CB_GETITEMDATA,
  1242. iSel,
  1243. 0L );
  1244. if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR))
  1245. {
  1246. pFI->iCharset = lpItemData->nFontType;
  1247. }
  1248. }
  1249. }
  1250. if (!CDLoadStringEx(CharsetToCodepage(pFI->iCharset), g_hinst,
  1251. pFI->iCharset+iszFontSample, szScript, ARRAYSIZE(szScript)))
  1252. {
  1253. return (FALSE);
  1254. }
  1255. SetDlgItemText(hDlg, stc5, szScript);
  1256. return (TRUE);
  1257. }
  1258. BOOL DoKoreanHack(HWND hwnd)
  1259. {
  1260. // HACK: This is only for Korean input. Because Korean Edit control has
  1261. // level 3 implementation for DBCS input, we may have a problem if
  1262. // focus is moving like below with interim character.
  1263. // 0xE0000412 is Korean IME layout id.
  1264. //
  1265. // TIP keyboard layout is like 0x04120412, so the primary id checking
  1266. // more better.
  1267. LANGID langId = LOWORD(HandleToUlong(GetKeyboardLayout(0)));
  1268. if (PRIMARYLANGID(langId) == LANG_KOREAN)
  1269. {
  1270. HIMC hIMC = ImmGetContext(hwnd);
  1271. LONG cb = ImmGetCompositionString(hIMC, GCS_COMPSTR, NULL, 0);
  1272. ImmReleaseContext(hwnd, hIMC);
  1273. if (cb > 0)
  1274. return TRUE;
  1275. }
  1276. return FALSE;
  1277. }
  1278. ////////////////////////////////////////////////////////////////////////////
  1279. //
  1280. // ProcessDlgCtrlCommand
  1281. //
  1282. // Handles all WM_COMMAND messages for the font dialog.
  1283. //
  1284. // cmb1 - ID of font facename combobox
  1285. // cmb2 - style
  1286. // cmb3 - size
  1287. // chx1 - "Underline" checkbox
  1288. // chx2 - "Strikeout" checkbox
  1289. // stc5 - frame around text preview area
  1290. // psh4 - button that invokes the Help application
  1291. // IDOK - OK button to end dialog, retaining information
  1292. // IDCANCEL - button to cancel dialog, not doing anything
  1293. //
  1294. // Returns: TRUE - if message is processed successfully
  1295. // FALSE - otherwise
  1296. //
  1297. ////////////////////////////////////////////////////////////////////////////
  1298. BOOL ProcessDlgCtrlCommand(HWND hDlg, PFONTINFO pFI, WORD wId, WORD wCmd, HWND hwnd)
  1299. {
  1300. int iSel;
  1301. LPCHOOSEFONT pCF = (pFI ? pFI->pCF : NULL);
  1302. TCHAR szStyle[LF_FACESIZE];
  1303. LPITEMDATA lpItemData;
  1304. if (pCF)
  1305. {
  1306. switch (wId)
  1307. {
  1308. case ( IDABORT ) :
  1309. {
  1310. //
  1311. // This is how a hook can cause the dialog to go away.
  1312. //
  1313. FreeAllItemData(hDlg, pFI);
  1314. if (pCF->Flags & CF_ENABLEHOOK)
  1315. {
  1316. glpfnFontHook = GETHOOKFN(pCF);
  1317. }
  1318. // FEATURE: ARULK Why are we returning an HWND anyway?
  1319. // The caller (ChooseFontX) expects us to return a BOOL
  1320. EndDialog(hDlg, BOOLFROMPTR(hwnd));
  1321. break;
  1322. }
  1323. case ( IDOK ) :
  1324. {
  1325. WORD wCmbId;
  1326. // Make sure the focus is set to the OK button. Must do
  1327. // this so that when the user presses Enter from one of
  1328. // the combo boxes, the kill focus processing is done
  1329. // before the data is captured.
  1330. SetFocus(GetDlgItem(hDlg, IDOK));
  1331. if (!GetPointSizeInRange(hDlg, pCF, &iSel, GPS_COMPLAIN | GPS_SETDEFSIZE ))
  1332. {
  1333. PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, cmb3), 1L);
  1334. break;
  1335. }
  1336. pCF->iPointSize = iSel;
  1337. FillInFont(hDlg, pFI, pCF, pCF->lpLogFont, TRUE);
  1338. if (pCF->Flags & CF_FORCEFONTEXIST)
  1339. {
  1340. if (pCF->Flags & CF_NOFACESEL)
  1341. {
  1342. wCmbId = cmb1;
  1343. }
  1344. else if (pCF->Flags & CF_NOSTYLESEL)
  1345. {
  1346. wCmbId = cmb2;
  1347. }
  1348. else
  1349. {
  1350. wCmbId = 0;
  1351. }
  1352. // Error found.
  1353. if (wCmbId)
  1354. {
  1355. TCHAR szMsg[160], szTitle[160];
  1356. CDLoadString(g_hinst,
  1357. (wCmbId == cmb1) ? iszNoFaceSel: iszNoStyleSel,
  1358. szMsg, ARRAYSIZE(szMsg));
  1359. GetWindowText(hDlg, szTitle, ARRAYSIZE(szTitle));
  1360. MessageBox(hDlg, szMsg, szTitle, MB_OK | MB_ICONINFORMATION );
  1361. PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, wCmbId), 1);
  1362. break;
  1363. }
  1364. }
  1365. if (pCF->Flags & CF_EFFECTS)
  1366. {
  1367. //
  1368. // Get currently selected item in color combo box and
  1369. // the 32 bit color rgb value associated with it.
  1370. //
  1371. iSel = (int)SendDlgItemMessage(hDlg, cmb4, CB_GETCURSEL, 0, 0);
  1372. pCF->rgbColors = (DWORD) SendDlgItemMessage(hDlg, cmb4, CB_GETITEMDATA, iSel, 0);
  1373. }
  1374. //
  1375. // Get a valid nFontType.
  1376. //
  1377. iSel = CBGetTextAndData(GetDlgItem(hDlg, cmb2), szStyle, ARRAYSIZE(szStyle), (PULONG_PTR)&lpItemData );
  1378. if (iSel < 0)
  1379. {
  1380. lpItemData = 0;
  1381. iSel = CBGetTextAndData(GetDlgItem(hDlg, cmb2), (LPTSTR)NULL, 0, (PULONG_PTR)&lpItemData);
  1382. }
  1383. if (iSel >= 0 && lpItemData)
  1384. {
  1385. pCF->nFontType = (WORD)lpItemData->nFontType;
  1386. }
  1387. else
  1388. {
  1389. pCF->nFontType = 0;
  1390. }
  1391. if (pCF->Flags & CF_USESTYLE)
  1392. {
  1393. // strcpy apparently okay, lpszStyle is inited to a string bigger than szStyle.
  1394. // no good way to pass around buffer size anyway.
  1395. lstrcpy(pCF->lpszStyle, szStyle);
  1396. }
  1397. goto LeaveDialog;
  1398. }
  1399. case ( IDCANCEL ) :
  1400. {
  1401. g_bUserPressedCancel = TRUE;
  1402. LeaveDialog:
  1403. FreeAllItemData(hDlg, pFI);
  1404. if (pCF->Flags & CF_ENABLEHOOK)
  1405. {
  1406. glpfnFontHook = GETHOOKFN(pCF);
  1407. }
  1408. EndDialog(hDlg, wId == IDOK);
  1409. break;
  1410. }
  1411. case ( cmb1 ) : // facenames combobox
  1412. {
  1413. switch (wCmd)
  1414. {
  1415. case ( CBN_SELCHANGE ) :
  1416. {
  1417. TCHAR szPoints[10];
  1418. CBSetTextFromSel(hwnd);
  1419. FillStyles:
  1420. //
  1421. // Try to maintain the current point size and style.
  1422. //
  1423. GetDlgItemText( hDlg, cmb3, szPoints, ARRAYSIZE(szPoints));
  1424. GetFontStylesAndSizes(hDlg, pFI, pCF, FALSE);
  1425. SetStyleSelection(hDlg, pCF, FALSE);
  1426. //
  1427. // Preserve the point size selection or put it in
  1428. // the edit control if it is not in the list for
  1429. // this font.
  1430. //
  1431. iSel = CBFindString(GetDlgItem(hDlg, cmb3), szPoints);
  1432. if (iSel < 0)
  1433. {
  1434. SetDlgItemText(hDlg, cmb3, szPoints);
  1435. }
  1436. else
  1437. {
  1438. SendDlgItemMessage(hDlg, cmb3, CB_SETCURSEL, iSel, 0);
  1439. }
  1440. goto DrawSample;
  1441. break;
  1442. }
  1443. case ( CBN_EDITUPDATE ) :
  1444. {
  1445. PostMessage( hDlg,
  1446. WM_COMMAND,
  1447. GET_WM_COMMAND_MPS(wId, hwnd, CBN_MYEDITUPDATE));
  1448. break;
  1449. }
  1450. case ( CBN_MYEDITUPDATE ) :
  1451. {
  1452. GetWindowText(hwnd, szStyle, ARRAYSIZE(szStyle));
  1453. iSel = CBFindString(hwnd, szStyle);
  1454. if (iSel >= 0)
  1455. {
  1456. if (DoKoreanHack(hwnd))
  1457. break;
  1458. SendMessage(hwnd, CB_SETCURSEL, (WPARAM)iSel, 0);
  1459. SendMessage(hwnd, CB_SETEDITSEL, 0, 0x0000FFFF);
  1460. goto FillStyles;
  1461. }
  1462. break;
  1463. }
  1464. }
  1465. break;
  1466. }
  1467. case ( cmb2 ) : // styles combobox
  1468. case ( cmb3 ) : // point sizes combobox
  1469. {
  1470. switch (wCmd)
  1471. {
  1472. case ( CBN_EDITUPDATE ) :
  1473. {
  1474. PostMessage( hDlg,
  1475. WM_COMMAND,
  1476. GET_WM_COMMAND_MPS(wId,hwnd,CBN_MYEDITUPDATE) );
  1477. break;
  1478. }
  1479. case ( CBN_MYEDITUPDATE ) :
  1480. {
  1481. GetWindowText(hwnd, szStyle, ARRAYSIZE(szStyle));
  1482. iSel = CBFindString(hwnd, szStyle);
  1483. if (iSel >= 0)
  1484. {
  1485. if (DoKoreanHack(hwnd))
  1486. break;
  1487. SendMessage(hwnd, CB_SETCURSEL, iSel, 0);
  1488. SendMessage(hwnd, CB_SETEDITSEL, 0, 0x0000FFFF);
  1489. goto DrawSample;
  1490. }
  1491. break;
  1492. }
  1493. case ( CBN_SELCHANGE ) :
  1494. {
  1495. iSel = CBSetTextFromSel(hwnd);
  1496. //
  1497. // Make the style selection stick.
  1498. //
  1499. if ((iSel >= 0) && (wId == cmb2))
  1500. {
  1501. LPITEMDATA lpItemData;
  1502. PLOGFONT plf;
  1503. lpItemData = (LPITEMDATA)SendMessage(hwnd, CB_GETITEMDATA, iSel, 0);
  1504. if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR))
  1505. {
  1506. plf = lpItemData->pLogFont;
  1507. pCF->lpLogFont->lfWeight = plf->lfWeight;
  1508. pCF->lpLogFont->lfItalic = plf->lfItalic;
  1509. }
  1510. else
  1511. {
  1512. pCF->lpLogFont->lfWeight = FW_NORMAL;
  1513. pCF->lpLogFont->lfItalic = 0;
  1514. }
  1515. }
  1516. goto DrawSample;
  1517. }
  1518. case ( CBN_KILLFOCUS ) :
  1519. {
  1520. DrawSample:
  1521. #ifdef UNICODE
  1522. if (pFI->ApiType == COMDLG_ANSI)
  1523. {
  1524. //
  1525. // Send special WOW message to indicate the
  1526. // font style has changed.
  1527. //
  1528. LOGFONT lf;
  1529. if (FillInFont(hDlg, pFI, pCF, &lf, TRUE))
  1530. {
  1531. memcpy(pCF->lpLogFont, &lf, sizeof(LOGFONT));
  1532. ThunkLogFontW2A(pCF->lpLogFont, pFI->pCFA->lpLogFont);
  1533. SendMessage(hDlg, msgWOWLFCHANGE, 0, (LPARAM)(LPLOGFONT)pFI->pCFA->lpLogFont);
  1534. }
  1535. }
  1536. #endif
  1537. //
  1538. // Force redraw of preview text for any size change.
  1539. //
  1540. InvalidateRect(hDlg, &pFI->rcText, FALSE);
  1541. UpdateWindow(hDlg);
  1542. }
  1543. }
  1544. break;
  1545. }
  1546. case ( cmb5 ) : // script combobox
  1547. {
  1548. //
  1549. // Need to change the sample text to reflect the new script.
  1550. //
  1551. if (wCmd != CBN_SELCHANGE)
  1552. {
  1553. break;
  1554. }
  1555. if (pFI->ProcessVersion < 0x40000)
  1556. {
  1557. // Enabled template also has a cmb5!
  1558. return (FALSE);
  1559. }
  1560. if (ResetSampleFromScript(hDlg, hwnd, pFI ))
  1561. {
  1562. goto FillStyles;
  1563. }
  1564. else
  1565. {
  1566. break;
  1567. }
  1568. }
  1569. case ( cmb4 ) :
  1570. {
  1571. if (wCmd != CBN_SELCHANGE)
  1572. {
  1573. break;
  1574. }
  1575. // fall thru...
  1576. }
  1577. case ( chx1 ) : // bold
  1578. case ( chx2 ) : // italic
  1579. {
  1580. goto DrawSample;
  1581. }
  1582. case ( pshHelp ) : // help
  1583. {
  1584. #ifdef UNICODE
  1585. if (pFI->ApiType == COMDLG_ANSI)
  1586. {
  1587. if (msgHELPA && pCF->hwndOwner)
  1588. {
  1589. SendMessage(pCF->hwndOwner, msgHELPA, (WPARAM)hDlg, (LPARAM)pCF);
  1590. }
  1591. }
  1592. else
  1593. #endif
  1594. {
  1595. if (msgHELPW && pCF->hwndOwner)
  1596. {
  1597. SendMessage(pCF->hwndOwner, msgHELPW, (WPARAM)hDlg, (LPARAM)pCF);
  1598. }
  1599. }
  1600. break;
  1601. }
  1602. default :
  1603. {
  1604. return (FALSE);
  1605. }
  1606. }
  1607. }
  1608. return (TRUE);
  1609. }
  1610. ////////////////////////////////////////////////////////////////////////////
  1611. //
  1612. // CmpFontType
  1613. //
  1614. // Compares two font types. The values of the font type bits are
  1615. // monotonic except the low bit (RASTER_FONTTYPE). After flipping
  1616. // that bit the words can be compared directly.
  1617. //
  1618. // Returns the best of the two.
  1619. //
  1620. ////////////////////////////////////////////////////////////////////////////
  1621. int CmpFontType(
  1622. DWORD ft1,
  1623. DWORD ft2)
  1624. {
  1625. ft1 &= ~(SCREEN_FONTTYPE | PRINTER_FONTTYPE);
  1626. ft2 &= ~(SCREEN_FONTTYPE | PRINTER_FONTTYPE);
  1627. //
  1628. // Flip the RASTER_FONTTYPE bit so we can compare.
  1629. //
  1630. ft1 ^= RASTER_FONTTYPE;
  1631. ft2 ^= RASTER_FONTTYPE;
  1632. return ( (int)ft1 - (int)ft2 );
  1633. }
  1634. ////////////////////////////////////////////////////////////////////////////
  1635. //
  1636. // FontFamilyEnumProc
  1637. //
  1638. // nFontType bits
  1639. //
  1640. // SCALABLE DEVICE RASTER
  1641. // (TT) (not GDI) (not scalable)
  1642. // 0 0 0 vector, ATM screen
  1643. // 0 0 1 GDI raster font
  1644. // 0 1 0 PS/LJ III, ATM printer, ATI/LaserMaster
  1645. // 0 1 1 non scalable device font
  1646. // 1 0 x TT screen font
  1647. // 1 1 x TT dev font
  1648. //
  1649. ////////////////////////////////////////////////////////////////////////////
  1650. int FontFamilyEnumProc(
  1651. LPENUMLOGFONTEX lplf,
  1652. LPNEWTEXTMETRIC lptm,
  1653. DWORD nFontType,
  1654. LPENUM_FONT_DATA lpData)
  1655. {
  1656. int iItem;
  1657. DWORD nOldType, nNewType;
  1658. LPITEMDATA lpItemData;
  1659. LPITEMDATA lpOldItemData = NULL;
  1660. //
  1661. // Bounce non TT fonts.
  1662. //
  1663. if ((lpData->dwFlags & CF_TTONLY) &&
  1664. !(nFontType & TRUETYPE_FONTTYPE))
  1665. {
  1666. return (TRUE);
  1667. }
  1668. //
  1669. // Bounce non scalable fonts.
  1670. //
  1671. if ((lpData->dwFlags & CF_SCALABLEONLY) &&
  1672. (nFontType & RASTER_FONTTYPE))
  1673. {
  1674. return (TRUE);
  1675. }
  1676. //
  1677. // Bounce non ANSI fonts.
  1678. //
  1679. if ((lpData->dwFlags & CF_SCRIPTSONLY) &&
  1680. ((lplf->elfLogFont.lfCharSet == OEM_CHARSET) ||
  1681. (lplf->elfLogFont.lfCharSet == SYMBOL_CHARSET)))
  1682. {
  1683. return (TRUE);
  1684. }
  1685. //
  1686. // Bounce vertical fonts.
  1687. //
  1688. if ((lpData->dwFlags & CF_NOVERTFONTS) &&
  1689. (lplf->elfLogFont.lfFaceName[0] == TEXT('@'))
  1690. )
  1691. {
  1692. return (TRUE);
  1693. }
  1694. //
  1695. // Bounce proportional fonts.
  1696. //
  1697. if ((lpData->dwFlags & CF_FIXEDPITCHONLY) &&
  1698. (lplf->elfLogFont.lfPitchAndFamily & VARIABLE_PITCH))
  1699. {
  1700. return (TRUE);
  1701. }
  1702. //
  1703. // Bounce vector fonts.
  1704. //
  1705. if ((lpData->dwFlags & CF_NOVECTORFONTS) &&
  1706. (lplf->elfLogFont.lfCharSet == OEM_CHARSET))
  1707. {
  1708. return (TRUE);
  1709. }
  1710. if (lpData->bPrinterFont)
  1711. {
  1712. nFontType |= PRINTER_FONTTYPE;
  1713. }
  1714. else
  1715. {
  1716. nFontType |= SCREEN_FONTTYPE;
  1717. }
  1718. //
  1719. // Test for a name collision.
  1720. //
  1721. iItem = CBFindString(lpData->hwndFamily, lplf->elfLogFont.lfFaceName);
  1722. if (iItem >= 0)
  1723. {
  1724. lpItemData = (LPITEMDATA)SendMessage( lpData->hwndFamily,
  1725. CB_GETITEMDATA,
  1726. iItem,
  1727. 0L );
  1728. if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR))
  1729. {
  1730. nOldType = lpItemData->nFontType;
  1731. lpOldItemData = lpItemData;
  1732. }
  1733. else
  1734. {
  1735. nOldType = 0;
  1736. }
  1737. //
  1738. // If we don't want screen fonts, but do want printer fonts,
  1739. // the old font is a screen font and the new font is a
  1740. // printer font, take the new font regardless of other flags.
  1741. // Note that this means if a printer wants TRUETYPE fonts, it
  1742. // should enumerate them.
  1743. //
  1744. if (!(lpData->dwFlags & CF_SCREENFONTS) &&
  1745. (lpData->dwFlags & CF_PRINTERFONTS) &&
  1746. (nFontType & PRINTER_FONTTYPE) &&
  1747. (nOldType & SCREEN_FONTTYPE))
  1748. {
  1749. nOldType = 0; // for setting nNewType below
  1750. goto SetNewType;
  1751. }
  1752. if (CmpFontType(nFontType, nOldType) > 0)
  1753. {
  1754. SetNewType:
  1755. nNewType = nFontType;
  1756. SendMessage( lpData->hwndFamily,
  1757. CB_INSERTSTRING,
  1758. iItem,
  1759. (LONG_PTR)(LPTSTR)lplf->elfLogFont.lfFaceName );
  1760. SendMessage( lpData->hwndFamily,
  1761. CB_DELETESTRING,
  1762. iItem + 1,
  1763. 0L );
  1764. }
  1765. else
  1766. {
  1767. nNewType = nOldType;
  1768. }
  1769. //
  1770. // Accumulate the printer/screen ness of these fonts.
  1771. //
  1772. nNewType |= (nFontType | nOldType) &
  1773. (SCREEN_FONTTYPE | PRINTER_FONTTYPE);
  1774. lpItemData = (LPITEMDATA)LocalAlloc(LMEM_FIXED, sizeof(ITEMDATA));
  1775. if (!lpItemData)
  1776. {
  1777. return (FALSE);
  1778. }
  1779. lpItemData->pLogFont = 0L;
  1780. lpItemData->nFontType = nNewType;
  1781. SendMessage( lpData->hwndFamily,
  1782. CB_SETITEMDATA,
  1783. iItem,
  1784. (LONG_PTR)lpItemData );
  1785. if (lpOldItemData)
  1786. {
  1787. LocalFree(lpOldItemData);
  1788. }
  1789. return (TRUE);
  1790. }
  1791. iItem = (int)SendMessage( lpData->hwndFamily,
  1792. CB_ADDSTRING,
  1793. 0,
  1794. (LONG_PTR)(LPTSTR)lplf->elfLogFont.lfFaceName );
  1795. if (iItem < 0)
  1796. {
  1797. return (FALSE);
  1798. }
  1799. lpItemData = (LPITEMDATA)LocalAlloc(LMEM_FIXED, sizeof(ITEMDATA));
  1800. if (!lpItemData)
  1801. {
  1802. return (FALSE);
  1803. }
  1804. lpItemData->pLogFont = 0L;
  1805. #ifdef WINNT
  1806. if (lptm->ntmFlags & NTM_PS_OPENTYPE)
  1807. nFontType |= PS_OPENTYPE_FONTTYPE;
  1808. if (lptm->ntmFlags & NTM_TYPE1)
  1809. nFontType |= TYPE1_FONTTYPE;
  1810. if (lptm->ntmFlags & NTM_TT_OPENTYPE)
  1811. nFontType |= TT_OPENTYPE_FONTTYPE;
  1812. #endif // WINNT
  1813. lpItemData->nFontType = nFontType;
  1814. SendMessage(lpData->hwndFamily, CB_SETITEMDATA, iItem, (LONG_PTR)lpItemData);
  1815. return (TRUE);
  1816. }
  1817. ////////////////////////////////////////////////////////////////////////////
  1818. //
  1819. // GetFontFamily
  1820. //
  1821. // Fills the screen and/or printer font facenames into the font facenames
  1822. // combobox depending on the CF_?? flags passed in.
  1823. //
  1824. // cmb1 is the ID for the font facename combobox
  1825. //
  1826. // Both screen and printer fonts are listed into the same combobox
  1827. //
  1828. // Returns: TRUE if successful
  1829. // FALSE otherwise.
  1830. //
  1831. ////////////////////////////////////////////////////////////////////////////
  1832. BOOL GetFontFamily(
  1833. HWND hDlg,
  1834. HDC hDC,
  1835. DWORD dwEnumCode,
  1836. UINT iCharset)
  1837. {
  1838. ENUM_FONT_DATA data;
  1839. int iItem, iCount;
  1840. DWORD nFontType;
  1841. TCHAR szMsg[200], szTitle[40];
  1842. LPITEMDATA lpItemData;
  1843. LOGFONT lf;
  1844. data.hwndFamily = GetDlgItem(hDlg, cmb1);
  1845. data.dwFlags = dwEnumCode;
  1846. //
  1847. // This is a bit strange. We have to get all the screen fonts
  1848. // so if they ask for the printer fonts we can tell which
  1849. // are really printer fonts. This is so we don't list the
  1850. // vector and raster fonts as printer device fonts.
  1851. //
  1852. data.hDC = GetDC(NULL);
  1853. data.bPrinterFont = FALSE;
  1854. lf.lfFaceName[0] = CHAR_NULL;
  1855. lf.lfCharSet = (dwEnumCode & CF_SELECTSCRIPT) ? iCharset : DEFAULT_CHARSET;
  1856. EnumFontFamiliesEx( data.hDC,
  1857. &lf,
  1858. (FONTENUMPROC)FontFamilyEnumProc,
  1859. (LPARAM)&data,
  1860. 0L );
  1861. ReleaseDC(NULL, data.hDC);
  1862. //
  1863. // List out printer font facenames.
  1864. //
  1865. if (dwEnumCode & CF_PRINTERFONTS)
  1866. {
  1867. data.hDC = hDC;
  1868. data.bPrinterFont = TRUE;
  1869. EnumFontFamiliesEx( hDC,
  1870. &lf,
  1871. (FONTENUMPROC)FontFamilyEnumProc,
  1872. (LPARAM)&data,
  1873. 0L );
  1874. }
  1875. //
  1876. // Now we have to remove those screen fonts if they didn't
  1877. // ask for them.
  1878. //
  1879. if (!(dwEnumCode & CF_SCREENFONTS))
  1880. {
  1881. iCount = (int)SendMessage(data.hwndFamily, CB_GETCOUNT, 0, 0L);
  1882. for (iItem = iCount - 1; iItem >= 0; iItem--)
  1883. {
  1884. lpItemData = (LPITEMDATA)SendMessage( data.hwndFamily,
  1885. CB_GETITEMDATA,
  1886. iItem,
  1887. 0L );
  1888. if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR))
  1889. {
  1890. nFontType = lpItemData->nFontType;
  1891. }
  1892. else
  1893. {
  1894. nFontType = 0;
  1895. }
  1896. if ((nFontType & (SCREEN_FONTTYPE |
  1897. PRINTER_FONTTYPE)) == SCREEN_FONTTYPE)
  1898. {
  1899. SendMessage(data.hwndFamily, CB_DELETESTRING, iItem, 0L);
  1900. }
  1901. }
  1902. }
  1903. //
  1904. // For WYSIWYG mode we delete all the fonts that don't exist
  1905. // on the screen and the printer.
  1906. //
  1907. if (dwEnumCode & CF_WYSIWYG)
  1908. {
  1909. iCount = (int)SendMessage(data.hwndFamily, CB_GETCOUNT, 0, 0L);
  1910. for (iItem = iCount - 1; iItem >= 0; iItem--)
  1911. {
  1912. nFontType = ((LPITEMDATA)SendMessage( data.hwndFamily,
  1913. CB_GETITEMDATA,
  1914. iItem,
  1915. 0L ))->nFontType;
  1916. if ((nFontType & (SCREEN_FONTTYPE | PRINTER_FONTTYPE)) !=
  1917. (SCREEN_FONTTYPE | PRINTER_FONTTYPE))
  1918. {
  1919. SendMessage(data.hwndFamily, CB_DELETESTRING, iItem, 0L);
  1920. }
  1921. }
  1922. }
  1923. if ((int)SendMessage(data.hwndFamily, CB_GETCOUNT, 0, 0L) <= 0)
  1924. {
  1925. CDLoadString( g_hinst,
  1926. iszNoFontsTitle,
  1927. szTitle,
  1928. ARRAYSIZE(szTitle));
  1929. CDLoadString( g_hinst,
  1930. iszNoFontsMsg,
  1931. szMsg,
  1932. ARRAYSIZE(szMsg));
  1933. MessageBox(hDlg, szMsg, szTitle, MB_OK | MB_ICONINFORMATION);
  1934. return (FALSE);
  1935. }
  1936. return (TRUE);
  1937. }
  1938. ////////////////////////////////////////////////////////////////////////////
  1939. //
  1940. // CBAddSize
  1941. //
  1942. ////////////////////////////////////////////////////////////////////////////
  1943. VOID CBAddSize(
  1944. HWND hwnd,
  1945. int pts,
  1946. LPCHOOSEFONT lpcf)
  1947. {
  1948. int iInd;
  1949. TCHAR szSize[10];
  1950. int count, test_size;
  1951. LPITEMDATA lpItemData;
  1952. //
  1953. // See if the size is limited.
  1954. //
  1955. if ((lpcf->Flags & CF_LIMITSIZE) &&
  1956. ((pts > lpcf->nSizeMax) || (pts < lpcf->nSizeMin)))
  1957. {
  1958. return;
  1959. }
  1960. //
  1961. // Convert the point size to a string.
  1962. //
  1963. wnsprintf(szSize, ARRAYSIZE(szSize), szPtFormat, pts);
  1964. //
  1965. // Figure out where in the list the item should be added.
  1966. // All values should be in increasing order in the list box.
  1967. //
  1968. count = (int)SendMessage(hwnd, CB_GETCOUNT, 0, 0L);
  1969. test_size = -1;
  1970. for (iInd = 0; iInd < count; iInd++)
  1971. {
  1972. lpItemData = (LPITEMDATA)SendMessage(hwnd, CB_GETITEMDATA, iInd, 0L);
  1973. if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR))
  1974. {
  1975. test_size = (int)lpItemData->nFontType;
  1976. }
  1977. else
  1978. {
  1979. test_size = 0;
  1980. }
  1981. if (pts <= test_size)
  1982. {
  1983. break;
  1984. }
  1985. }
  1986. //
  1987. // Don't add duplicates.
  1988. //
  1989. if (pts == test_size)
  1990. {
  1991. return;
  1992. }
  1993. //
  1994. // Add the string and the associated item data to the list box.
  1995. //
  1996. iInd = (int) SendMessage(hwnd, CB_INSERTSTRING, iInd, (LPARAM)szSize);
  1997. if (iInd >= 0)
  1998. {
  1999. lpItemData = (LPITEMDATA)LocalAlloc(LMEM_FIXED, sizeof(ITEMDATA));
  2000. if (!lpItemData)
  2001. {
  2002. return;
  2003. }
  2004. lpItemData->pLogFont = 0L;
  2005. lpItemData->nFontType = (DWORD)pts;
  2006. SendMessage(hwnd, CB_SETITEMDATA, iInd, (LONG_PTR)lpItemData);
  2007. }
  2008. }
  2009. ////////////////////////////////////////////////////////////////////////////
  2010. //
  2011. // CBAddChineseSize
  2012. //
  2013. ////////////////////////////////////////////////////////////////////////////
  2014. VOID CBAddChineseSize(
  2015. HWND hwnd,
  2016. LPCHOOSEFONT lpcf)
  2017. {
  2018. int ctr, iInd = 0;
  2019. TCHAR szSize[10];
  2020. LPITEMDATA lpItemData;
  2021. //
  2022. // Look at each item in the Zihao structure to see if it should be
  2023. // added.
  2024. //
  2025. for (ctr = 0; ctr < NUM_ZIHAO; ctr++)
  2026. {
  2027. //
  2028. // See if the size is limited.
  2029. //
  2030. if ((lpcf->Flags & CF_LIMITSIZE) &&
  2031. ((stZihao[ctr].size > lpcf->nSizeMax) ||
  2032. (stZihao[ctr].size < lpcf->nSizeMin)))
  2033. {
  2034. continue;
  2035. }
  2036. //
  2037. // Convert the point size to a string.
  2038. //
  2039. wnsprintf(szSize, ARRAYSIZE(szSize), TEXT("%s"), stZihao[ctr].name);
  2040. //
  2041. // Add the string and the associated item data to the list box.
  2042. //
  2043. iInd = (int) SendMessage(hwnd, CB_INSERTSTRING, iInd, (LPARAM)szSize);
  2044. if (iInd >= 0)
  2045. {
  2046. lpItemData = (LPITEMDATA)LocalAlloc(LMEM_FIXED, sizeof(ITEMDATA));
  2047. if (!lpItemData)
  2048. {
  2049. return;
  2050. }
  2051. lpItemData->pLogFont = 0L;
  2052. lpItemData->nFontType = (DWORD)(stZihao[ctr].size * 10 +
  2053. stZihao[ctr].sizeFr);
  2054. SendMessage(hwnd, CB_SETITEMDATA, iInd, (LONG_PTR)lpItemData);
  2055. }
  2056. }
  2057. }
  2058. ////////////////////////////////////////////////////////////////////////////
  2059. //
  2060. // InsertStyleSorted
  2061. //
  2062. // Sort styles by weight first, then by italics.
  2063. //
  2064. // Returns the index of the place this was inserted.
  2065. //
  2066. ////////////////////////////////////////////////////////////////////////////
  2067. int InsertStyleSorted(
  2068. HWND hwnd,
  2069. LPTSTR lpszStyle,
  2070. LPLOGFONT lplf)
  2071. {
  2072. int count, ctr;
  2073. PLOGFONT plf;
  2074. LPITEMDATA lpItemData;
  2075. count = (int) SendMessage(hwnd, CB_GETCOUNT, 0, 0L);
  2076. for (ctr = 0; ctr < count; ctr++)
  2077. {
  2078. lpItemData = (LPITEMDATA)SendMessage(hwnd, CB_GETITEMDATA, ctr, 0L);
  2079. if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR))
  2080. {
  2081. plf = lpItemData->pLogFont;
  2082. if (lplf->lfWeight < plf->lfWeight)
  2083. {
  2084. break;
  2085. }
  2086. else if (lplf->lfWeight == plf->lfWeight)
  2087. {
  2088. if (lplf->lfItalic && !plf->lfItalic)
  2089. {
  2090. ctr++;
  2091. }
  2092. break;
  2093. }
  2094. }
  2095. }
  2096. return ((int)SendMessage(hwnd, CB_INSERTSTRING, ctr, (LONG_PTR)lpszStyle));
  2097. }
  2098. ////////////////////////////////////////////////////////////////////////////
  2099. //
  2100. // CBAddStyle
  2101. //
  2102. ////////////////////////////////////////////////////////////////////////////
  2103. PLOGFONT CBAddStyle(
  2104. HWND hwnd,
  2105. LPTSTR lpszStyle,
  2106. DWORD nFontType,
  2107. LPLOGFONT lplf)
  2108. {
  2109. int iItem;
  2110. PLOGFONT plf;
  2111. LPITEMDATA lpItemData;
  2112. //
  2113. // Don't add duplicates.
  2114. //
  2115. if (CBFindString(hwnd, lpszStyle) >= 0)
  2116. {
  2117. return (NULL);
  2118. }
  2119. iItem = (int)InsertStyleSorted(hwnd, lpszStyle, lplf);
  2120. if (iItem < 0)
  2121. {
  2122. return (NULL);
  2123. }
  2124. plf = (PLOGFONT)LocalAlloc(LMEM_FIXED, sizeof(LOGFONT));
  2125. if (!plf)
  2126. {
  2127. SendMessage(hwnd, CB_DELETESTRING, iItem, 0L);
  2128. return (NULL);
  2129. }
  2130. *plf = *lplf;
  2131. lpItemData = (LPITEMDATA)LocalAlloc(LMEM_FIXED, sizeof(ITEMDATA));
  2132. if (!lpItemData)
  2133. {
  2134. LocalFree(plf);
  2135. SendMessage(hwnd, CB_DELETESTRING, iItem, 0L);
  2136. return (NULL);
  2137. }
  2138. lpItemData->pLogFont = plf;
  2139. lpItemData->nFontType = nFontType;
  2140. SendMessage(hwnd, CB_SETITEMDATA, iItem, (LONG_PTR)lpItemData);
  2141. return (plf);
  2142. }
  2143. ////////////////////////////////////////////////////////////////////////////
  2144. //
  2145. // CBAddScript
  2146. //
  2147. ////////////////////////////////////////////////////////////////////////////
  2148. int CBAddScript(
  2149. HWND hwnd,
  2150. LPTSTR lpszScript,
  2151. UINT iCharset)
  2152. {
  2153. int iItem;
  2154. LPITEMDATA lpItemData;
  2155. //
  2156. // Don't add duplicates or empty strings.
  2157. //
  2158. if (!IsWindow(hwnd) || !IsWindowEnabled(hwnd) || (!*lpszScript) ||
  2159. (CBFindString(hwnd, lpszScript) >= 0))
  2160. {
  2161. return (-1);
  2162. }
  2163. iItem = (int)SendMessage(hwnd, CB_ADDSTRING, 0, (LONG_PTR)(LPTSTR)lpszScript);
  2164. if (iItem < 0)
  2165. {
  2166. return (-1);
  2167. }
  2168. lpItemData = (LPITEMDATA)LocalAlloc(LMEM_FIXED, sizeof(ITEMDATA));
  2169. if (!lpItemData)
  2170. {
  2171. SendMessage(hwnd, CB_DELETESTRING, iItem, 0L);
  2172. return (-1);
  2173. }
  2174. lpItemData->pLogFont = 0L;
  2175. lpItemData->nFontType = (DWORD)iCharset;
  2176. SendMessage(hwnd, CB_SETITEMDATA, iItem, (LONG_PTR)lpItemData);
  2177. return (iItem);
  2178. }
  2179. ////////////////////////////////////////////////////////////////////////////
  2180. //
  2181. // FillInMissingStyles
  2182. //
  2183. // Generates simulated forms from those that we have.
  2184. //
  2185. // reg -> bold
  2186. // reg -> italic
  2187. // bold || italic || reg -> bold italic
  2188. //
  2189. ////////////////////////////////////////////////////////////////////////////
  2190. VOID FillInMissingStyles(
  2191. HWND hwnd)
  2192. {
  2193. PLOGFONT plf, plf_reg, plf_bold, plf_italic;
  2194. DWORD nFontType;
  2195. int ctr, count;
  2196. BOOL bBold, bItalic, bBoldItalic;
  2197. LPITEMDATA lpItemData;
  2198. LOGFONT lf;
  2199. bBold = bItalic = bBoldItalic = FALSE;
  2200. plf_reg = plf_bold = plf_italic = NULL;
  2201. count = (int)SendMessage(hwnd, CB_GETCOUNT, 0, 0L);
  2202. for (ctr = 0; ctr < count; ctr++)
  2203. {
  2204. lpItemData = (LPITEMDATA)SendMessage(hwnd, CB_GETITEMDATA, ctr, 0L);
  2205. if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR))
  2206. {
  2207. plf = lpItemData->pLogFont;
  2208. nFontType = lpItemData->nFontType;
  2209. }
  2210. else
  2211. {
  2212. plf = NULL;
  2213. nFontType = 0;
  2214. }
  2215. if ((nFontType & BOLD_FONTTYPE) && (nFontType & ITALIC_FONTTYPE))
  2216. {
  2217. bBoldItalic = TRUE;
  2218. }
  2219. else if (nFontType & BOLD_FONTTYPE)
  2220. {
  2221. bBold = TRUE;
  2222. plf_bold = plf;
  2223. }
  2224. else if (nFontType & ITALIC_FONTTYPE)
  2225. {
  2226. bItalic = TRUE;
  2227. plf_italic = plf;
  2228. }
  2229. else
  2230. {
  2231. plf_reg = plf;
  2232. }
  2233. }
  2234. nFontType |= SIMULATED_FONTTYPE;
  2235. if (!bBold && plf_reg)
  2236. {
  2237. lf = *plf_reg;
  2238. lf.lfWeight = FW_BOLD;
  2239. CBAddStyle(hwnd, szBold, (nFontType | BOLD_FONTTYPE), &lf);
  2240. }
  2241. if (!bItalic && plf_reg)
  2242. {
  2243. lf = *plf_reg;
  2244. lf.lfItalic = TRUE;
  2245. CBAddStyle(hwnd, szItalic, (nFontType | ITALIC_FONTTYPE), &lf);
  2246. }
  2247. if (!bBoldItalic && (plf_bold || plf_italic || plf_reg))
  2248. {
  2249. if (plf_italic)
  2250. {
  2251. plf = plf_italic;
  2252. }
  2253. else if (plf_bold)
  2254. {
  2255. plf = plf_bold;
  2256. }
  2257. else
  2258. {
  2259. plf = plf_reg;
  2260. }
  2261. lf = *plf;
  2262. lf.lfItalic = (BYTE)TRUE;
  2263. lf.lfWeight = FW_BOLD;
  2264. CBAddStyle(hwnd, szBoldItalic, (nFontType | BOLD_FONTTYPE | ITALIC_FONTTYPE), &lf);
  2265. }
  2266. }
  2267. ////////////////////////////////////////////////////////////////////////////
  2268. //
  2269. // FillScalableSizes
  2270. //
  2271. ////////////////////////////////////////////////////////////////////////////
  2272. VOID FillScalableSizes(
  2273. HWND hwnd,
  2274. LPCHOOSEFONT lpcf)
  2275. {
  2276. if (g_bIsSimplifiedChineseUI)
  2277. {
  2278. CBAddChineseSize(hwnd, lpcf);
  2279. }
  2280. CBAddSize(hwnd, 8, lpcf);
  2281. CBAddSize(hwnd, 9, lpcf);
  2282. CBAddSize(hwnd, 10, lpcf);
  2283. CBAddSize(hwnd, 11, lpcf);
  2284. CBAddSize(hwnd, 12, lpcf);
  2285. CBAddSize(hwnd, 14, lpcf);
  2286. CBAddSize(hwnd, 16, lpcf);
  2287. CBAddSize(hwnd, 18, lpcf);
  2288. CBAddSize(hwnd, 20, lpcf);
  2289. CBAddSize(hwnd, 22, lpcf);
  2290. CBAddSize(hwnd, 24, lpcf);
  2291. CBAddSize(hwnd, 26, lpcf);
  2292. CBAddSize(hwnd, 28, lpcf);
  2293. CBAddSize(hwnd, 36, lpcf);
  2294. CBAddSize(hwnd, 48, lpcf);
  2295. CBAddSize(hwnd, 72, lpcf);
  2296. }
  2297. ////////////////////////////////////////////////////////////////////////////
  2298. //
  2299. // FontStyleEnumProc
  2300. //
  2301. ////////////////////////////////////////////////////////////////////////////
  2302. int FontStyleEnumProc(
  2303. LPENUMLOGFONTEX lplf,
  2304. LPNEWTEXTMETRIC lptm,
  2305. DWORD nFontType,
  2306. LPENUM_FONT_DATA lpData)
  2307. {
  2308. int height, pts;
  2309. TCHAR szBuf[10];
  2310. if (!(nFontType & RASTER_FONTTYPE))
  2311. {
  2312. //
  2313. // Vector or TT font.
  2314. //
  2315. if (lpData->bFillSize &&
  2316. (int)SendMessage(lpData->hwndSizes, CB_GETCOUNT, 0, 0L) == 0)
  2317. {
  2318. FillScalableSizes(lpData->hwndSizes, lpData->lpcf);
  2319. }
  2320. }
  2321. else
  2322. {
  2323. height = lptm->tmHeight - lptm->tmInternalLeading;
  2324. pts = GetPointString(szBuf, ARRAYSIZE(szBuf), lpData->hDC, height);
  2325. //
  2326. // Filter devices same size of multiple styles.
  2327. //
  2328. if (CBFindString(lpData->hwndSizes, szBuf) < 0)
  2329. {
  2330. CBAddSize(lpData->hwndSizes, pts, lpData->lpcf);
  2331. }
  2332. }
  2333. //
  2334. // Keep the printer/screen bits from the family list here too.
  2335. //
  2336. nFontType |= (lpData->nFontType & (SCREEN_FONTTYPE | PRINTER_FONTTYPE));
  2337. #ifdef WINNT
  2338. if (lptm->ntmFlags & NTM_PS_OPENTYPE)
  2339. nFontType |= PS_OPENTYPE_FONTTYPE;
  2340. if (lptm->ntmFlags & NTM_TYPE1)
  2341. nFontType |= TYPE1_FONTTYPE;
  2342. if (lptm->ntmFlags & NTM_TT_OPENTYPE)
  2343. nFontType |= TT_OPENTYPE_FONTTYPE;
  2344. #endif // WINNT
  2345. if (nFontType & TRUETYPE_FONTTYPE)
  2346. {
  2347. //
  2348. // If (lptm->ntmFlags & NTM_REGULAR)
  2349. //
  2350. if (!(lptm->ntmFlags & (NTM_BOLD | NTM_ITALIC)))
  2351. {
  2352. nFontType |= REGULAR_FONTTYPE;
  2353. }
  2354. if (lptm->ntmFlags & NTM_ITALIC)
  2355. {
  2356. nFontType |= ITALIC_FONTTYPE;
  2357. }
  2358. if (lptm->ntmFlags & NTM_BOLD)
  2359. {
  2360. nFontType |= BOLD_FONTTYPE;
  2361. }
  2362. //
  2363. // After the LOGFONT.lfFaceName there are 2 more names
  2364. // lfFullName[LF_FACESIZE * 2]
  2365. // lfStyle[LF_FACESIZE]
  2366. //
  2367. // If the font has one of the standard style strings in English,
  2368. // use the localized string instead.
  2369. //
  2370. if (!lstrcmp(c_szBoldItalic, lplf->elfStyle) ||
  2371. ((nFontType & BOLD_FONTTYPE) && (nFontType & ITALIC_FONTTYPE)))
  2372. {
  2373. CBAddStyle( lpData->hwndStyle,
  2374. szBoldItalic,
  2375. nFontType,
  2376. &lplf->elfLogFont);
  2377. }
  2378. else if (!lstrcmp(c_szRegular, lplf->elfStyle) ||
  2379. (nFontType & REGULAR_FONTTYPE))
  2380. {
  2381. CBAddStyle( lpData->hwndStyle,
  2382. szRegular,
  2383. nFontType,
  2384. &lplf->elfLogFont );
  2385. }
  2386. else if (!lstrcmp(c_szBold, lplf->elfStyle) ||
  2387. (nFontType & BOLD_FONTTYPE))
  2388. {
  2389. CBAddStyle( lpData->hwndStyle,
  2390. szBold,
  2391. nFontType,
  2392. &lplf->elfLogFont );
  2393. }
  2394. else if (!lstrcmp(c_szItalic, lplf->elfStyle) ||
  2395. (nFontType & ITALIC_FONTTYPE))
  2396. {
  2397. CBAddStyle( lpData->hwndStyle,
  2398. szItalic,
  2399. nFontType,
  2400. &lplf->elfLogFont);
  2401. }
  2402. }
  2403. else
  2404. {
  2405. if ((lplf->elfLogFont.lfWeight >= FW_BOLD) && lplf->elfLogFont.lfItalic)
  2406. {
  2407. CBAddStyle( lpData->hwndStyle,
  2408. szBoldItalic,
  2409. (nFontType | BOLD_FONTTYPE | ITALIC_FONTTYPE),
  2410. &lplf->elfLogFont );
  2411. }
  2412. else if (lplf->elfLogFont.lfWeight >= FW_BOLD)
  2413. {
  2414. CBAddStyle( lpData->hwndStyle,
  2415. szBold,
  2416. (nFontType | BOLD_FONTTYPE),
  2417. &lplf->elfLogFont );
  2418. }
  2419. else if (lplf->elfLogFont.lfItalic)
  2420. {
  2421. CBAddStyle( lpData->hwndStyle,
  2422. szItalic,
  2423. (nFontType | ITALIC_FONTTYPE),
  2424. &lplf->elfLogFont );
  2425. }
  2426. else
  2427. {
  2428. CBAddStyle( lpData->hwndStyle,
  2429. szRegular,
  2430. (nFontType | REGULAR_FONTTYPE),
  2431. &lplf->elfLogFont );
  2432. }
  2433. }
  2434. return (TRUE);
  2435. }
  2436. ////////////////////////////////////////////////////////////////////////////
  2437. //
  2438. // FreeFonts
  2439. //
  2440. ////////////////////////////////////////////////////////////////////////////
  2441. VOID FreeFonts(
  2442. HWND hwnd)
  2443. {
  2444. int ctr, count;
  2445. LPITEMDATA lpItemData;
  2446. count = (int)SendMessage(hwnd, CB_GETCOUNT, 0, 0L);
  2447. for (ctr = 0; ctr < count; ctr++)
  2448. {
  2449. lpItemData = (LPITEMDATA)SendMessage(hwnd, CB_GETITEMDATA, ctr, 0L);
  2450. if (!IS_INTRESOURCE(lpItemData) && (lpItemData != (LPITEMDATA)CB_ERR))
  2451. {
  2452. if (!IS_INTRESOURCE(lpItemData->pLogFont))
  2453. {
  2454. LocalFree((HANDLE)lpItemData->pLogFont);
  2455. }
  2456. LocalFree((HANDLE)lpItemData);
  2457. }
  2458. SendMessage(hwnd, CB_SETITEMDATA, ctr, 0L);
  2459. }
  2460. SendMessage(hwnd, CB_RESETCONTENT, 0, 0L);
  2461. }
  2462. ////////////////////////////////////////////////////////////////////////////
  2463. //
  2464. // FreeAllItemData
  2465. //
  2466. ////////////////////////////////////////////////////////////////////////////
  2467. VOID FreeAllItemData(
  2468. HWND hDlg,
  2469. PFONTINFO pFI)
  2470. {
  2471. HWND hwndTemp;
  2472. if (hwndTemp = GetDlgItem(hDlg, cmb1))
  2473. {
  2474. FreeFonts(hwndTemp);
  2475. }
  2476. if (hwndTemp = GetDlgItem(hDlg, cmb2))
  2477. {
  2478. FreeFonts(hwndTemp);
  2479. }
  2480. if (hwndTemp = GetDlgItem(hDlg, cmb3))
  2481. {
  2482. FreeFonts(hwndTemp);
  2483. }
  2484. if (((pFI->ProcessVersion >= 0x40000) ||
  2485. (pFI->pCF->Flags & CF_NOSCRIPTSEL)) &&
  2486. (hwndTemp = GetDlgItem(hDlg, cmb5)))
  2487. {
  2488. FreeFonts(hwndTemp);
  2489. }
  2490. }
  2491. ////////////////////////////////////////////////////////////////////////////
  2492. //
  2493. // InitLF
  2494. //
  2495. // Initalize a LOGFONT structure to some base generic regular type font.
  2496. //
  2497. ////////////////////////////////////////////////////////////////////////////
  2498. VOID InitLF(
  2499. LPLOGFONT lplf)
  2500. {
  2501. HDC hdc;
  2502. hdc = GetDC(NULL);
  2503. lplf->lfEscapement = 0;
  2504. lplf->lfOrientation = 0;
  2505. lplf->lfCharSet = (BYTE) GetTextCharset(hdc);
  2506. lplf->lfOutPrecision = OUT_DEFAULT_PRECIS;
  2507. lplf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
  2508. lplf->lfQuality = DEFAULT_QUALITY;
  2509. lplf->lfPitchAndFamily = DEFAULT_PITCH;
  2510. lplf->lfItalic = 0;
  2511. lplf->lfWeight = FW_NORMAL;
  2512. lplf->lfStrikeOut = 0;
  2513. lplf->lfUnderline = 0;
  2514. lplf->lfWidth = 0; // otherwise we get independant x-y scaling
  2515. lplf->lfFaceName[0] = 0;
  2516. lplf->lfHeight = -MulDiv( DEF_POINT_SIZE,
  2517. GetDeviceCaps(hdc, LOGPIXELSY),
  2518. POINTS_PER_INCH );
  2519. ReleaseDC(NULL, hdc);
  2520. }
  2521. ////////////////////////////////////////////////////////////////////////////
  2522. //
  2523. // FontScriptEnumProc
  2524. //
  2525. // Gets all of the charsets for the face we are enumerating.
  2526. //
  2527. // Fills in the script window if any, and sets the script property to
  2528. // the correct charset. If there is no window, then the first value
  2529. // enumerated is set into the script, and contol returned. If there is a
  2530. // window, then the scripts will all be filled in. If the correct value
  2531. // is found, then that will be filled in. If its not found, such as when
  2532. // the user changes from TimesNewRoman to WingDings, then the caller will
  2533. // fill in the property to be the first one.
  2534. //
  2535. ////////////////////////////////////////////////////////////////////////////
  2536. int FontScriptEnumProc(
  2537. LPENUMLOGFONTEX lplf,
  2538. LPNEWTEXTMETRIC lptm,
  2539. DWORD nFontType,
  2540. LPENUM_FONT_DATA lpData)
  2541. {
  2542. int script = -1;
  2543. //
  2544. // Need to check the charsets again as we have a face and are checking
  2545. // the family.
  2546. //
  2547. // Bounce non WANSI fonts.
  2548. //
  2549. if ( (lpData->dwFlags & CF_SCRIPTSONLY) &&
  2550. ((lplf->elfLogFont.lfCharSet == OEM_CHARSET) ||
  2551. (lplf->elfLogFont.lfCharSet == SYMBOL_CHARSET)) )
  2552. {
  2553. return (TRUE);
  2554. }
  2555. if (lpData->hwndScript)
  2556. {
  2557. script = CBAddScript( lpData->hwndScript,
  2558. lplf->elfScript,
  2559. lplf->elfLogFont.lfCharSet );
  2560. }
  2561. else if (lpData->iCharset == FONT_INVALID_CHARSET)
  2562. {
  2563. lpData->iCharset = lplf->elfLogFont.lfCharSet;
  2564. }
  2565. if (lplf->elfLogFont.lfCharSet == lpData->cfdCharset)
  2566. {
  2567. lpData->iCharset = lplf->elfLogFont.lfCharSet;
  2568. if (script >= 0)
  2569. {
  2570. SendMessage(lpData->hwndScript, CB_SETCURSEL, script, 0L);
  2571. }
  2572. else if (!(lpData->hwndScript))
  2573. {
  2574. return (FALSE);
  2575. }
  2576. }
  2577. if (lpData->lpcf->Flags & CF_SELECTSCRIPT)
  2578. {
  2579. //
  2580. // We just wanted the first one to fill in the script box, now stop.
  2581. //
  2582. return (FALSE);
  2583. }
  2584. return (TRUE);
  2585. }
  2586. ////////////////////////////////////////////////////////////////////////////
  2587. //
  2588. // GetFontStylesAndSizes
  2589. //
  2590. // Fills the point sizes combo box with the point sizes for the current
  2591. // selection in the facenames combobox.
  2592. //
  2593. // cmb1 is the ID for the font facename combobox.
  2594. //
  2595. // Returns: TRUE if successful
  2596. // FALSE otherwise.
  2597. //
  2598. ////////////////////////////////////////////////////////////////////////////
  2599. BOOL GetFontStylesAndSizes(
  2600. HWND hDlg,
  2601. PFONTINFO pFI,
  2602. LPCHOOSEFONT lpcf,
  2603. BOOL bForceSizeFill)
  2604. {
  2605. ENUM_FONT_DATA data;
  2606. TCHAR szFace[LF_FACESIZE];
  2607. int iSel;
  2608. int iMapMode;
  2609. SIZE ViewportExt, WindowExt;
  2610. LOGFONT lf;
  2611. LPITEMDATA lpItemData;
  2612. FreeFonts(GetDlgItem(hDlg, cmb2));
  2613. data.hwndStyle = GetDlgItem(hDlg, cmb2);
  2614. data.hwndSizes = GetDlgItem(hDlg, cmb3);
  2615. data.hwndScript = (pFI->ProcessVersion >= 0x40000)
  2616. ? GetDlgItem(hDlg, cmb5)
  2617. : NULL;
  2618. data.dwFlags = lpcf->Flags;
  2619. data.lpcf = lpcf;
  2620. if (!IsWindow(data.hwndScript) || !IsWindowEnabled(data.hwndScript))
  2621. {
  2622. data.hwndScript = NULL;
  2623. }
  2624. iSel = (int)SendDlgItemMessage(hDlg, cmb1, CB_GETCURSEL, 0, 0L);
  2625. if (iSel < 0)
  2626. {
  2627. //
  2628. // If we don't have a face name selected we will synthisize
  2629. // the standard font styles...
  2630. //
  2631. InitLF(&lf);
  2632. CBAddStyle(data.hwndStyle, szRegular, REGULAR_FONTTYPE, &lf);
  2633. lf.lfWeight = FW_BOLD;
  2634. CBAddStyle(data.hwndStyle, szBold, BOLD_FONTTYPE, &lf);
  2635. lf.lfWeight = FW_NORMAL;
  2636. lf.lfItalic = TRUE;
  2637. CBAddStyle(data.hwndStyle, szItalic, ITALIC_FONTTYPE, &lf);
  2638. lf.lfWeight = FW_BOLD;
  2639. CBAddStyle(data.hwndStyle, szBoldItalic, BOLD_FONTTYPE | ITALIC_FONTTYPE, &lf);
  2640. FillScalableSizes(data.hwndSizes, lpcf);
  2641. return (TRUE);
  2642. }
  2643. lpItemData = (LPITEMDATA)SendDlgItemMessage( hDlg,
  2644. cmb1,
  2645. CB_GETITEMDATA,
  2646. iSel,
  2647. 0L );
  2648. if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR))
  2649. {
  2650. data.nFontType = lpItemData->nFontType;
  2651. }
  2652. else
  2653. {
  2654. data.nFontType = 0;
  2655. }
  2656. data.bFillSize = TRUE;
  2657. //
  2658. // Free existing contents of font size combo box.
  2659. // Also sends CB_RESETCONTENT to control.
  2660. //
  2661. FreeFonts(data.hwndSizes);
  2662. SendMessage(data.hwndStyle, WM_SETREDRAW, FALSE, 0L);
  2663. GetDlgItemText(hDlg, cmb1, szFace, ARRAYSIZE(szFace));
  2664. lstrcpyn(lf.lfFaceName, szFace, ARRAYSIZE(lf.lfFaceName));
  2665. //
  2666. // Fill in the script box FIRST. That way we have something to play with.
  2667. //
  2668. if (data.hwndScript)
  2669. {
  2670. SendMessage(data.hwndScript, CB_RESETCONTENT, 0, 0L);
  2671. }
  2672. data.iCharset = FONT_INVALID_CHARSET; // impossible charset value.
  2673. data.cfdCharset = pFI->iCharset; // pass into enum procs
  2674. //
  2675. // If no script box exists, then we must get the appropriate charset
  2676. // based on the default ansi code page.
  2677. //
  2678. if (!data.hwndScript)
  2679. {
  2680. CHARSETINFO csi;
  2681. DWORD dwCodePage = GetACP();
  2682. if (TranslateCharsetInfo(IntToPtr_(DWORD*, dwCodePage), &csi, TCI_SRCCODEPAGE))
  2683. {
  2684. data.cfdCharset = csi.ciCharset;
  2685. }
  2686. }
  2687. lf.lfCharSet = (lpcf->Flags & CF_SELECTSCRIPT)
  2688. ? pFI->iCharset
  2689. : DEFAULT_CHARSET;
  2690. if (lpcf->Flags & CF_SCREENFONTS)
  2691. {
  2692. data.hDC = GetDC(NULL);
  2693. data.bPrinterFont = FALSE;
  2694. EnumFontFamiliesEx( data.hDC,
  2695. &lf,
  2696. (FONTENUMPROC)FontScriptEnumProc,
  2697. (LPARAM)&data,
  2698. 0L );
  2699. ReleaseDC(NULL, data.hDC);
  2700. }
  2701. if (lpcf->Flags & CF_PRINTERFONTS)
  2702. {
  2703. data.hDC = lpcf->hDC;
  2704. data.bPrinterFont = TRUE;
  2705. EnumFontFamiliesEx( lpcf->hDC,
  2706. &lf,
  2707. (FONTENUMPROC)FontScriptEnumProc,
  2708. (LPARAM)&data,
  2709. 0L );
  2710. }
  2711. //
  2712. // Put it back into the main structure.
  2713. //
  2714. if ((data.iCharset == FONT_INVALID_CHARSET) && (data.hwndScript))
  2715. {
  2716. //
  2717. // There MUST be a script window, and we didn't find the charset
  2718. // we were looking for.
  2719. //
  2720. SendMessage(data.hwndScript, CB_SETCURSEL, 0, 0L);
  2721. lpItemData = (LPITEMDATA)SendMessage( data.hwndScript,
  2722. CB_GETITEMDATA,
  2723. 0,
  2724. 0L );
  2725. if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR))
  2726. {
  2727. data.iCharset = lpItemData->nFontType;
  2728. }
  2729. else
  2730. {
  2731. data.iCharset = DEFAULT_CHARSET;
  2732. }
  2733. }
  2734. lf.lfCharSet = pFI->iCharset = data.iCharset;
  2735. if (lpcf->Flags & CF_SCREENFONTS)
  2736. {
  2737. data.hDC = GetDC(NULL);
  2738. data.bPrinterFont = FALSE;
  2739. EnumFontFamiliesEx( data.hDC,
  2740. &lf,
  2741. (FONTENUMPROC)FontStyleEnumProc,
  2742. (LPARAM)&data,
  2743. 0L );
  2744. ReleaseDC(NULL, data.hDC);
  2745. }
  2746. if (lpcf->Flags & CF_PRINTERFONTS)
  2747. {
  2748. //
  2749. // Save and restore the DC's mapping mode (and extents if needed)
  2750. // if it's been set by the app to something other than MM_TEXT.
  2751. //
  2752. if ((iMapMode = GetMapMode(lpcf->hDC)) != MM_TEXT)
  2753. {
  2754. if ((iMapMode == MM_ISOTROPIC) || (iMapMode == MM_ANISOTROPIC))
  2755. {
  2756. GetViewportExtEx(lpcf->hDC, &ViewportExt);
  2757. GetWindowExtEx(lpcf->hDC, &WindowExt);
  2758. }
  2759. SetMapMode(lpcf->hDC, MM_TEXT);
  2760. }
  2761. data.hDC = lpcf->hDC;
  2762. data.bPrinterFont = TRUE;
  2763. EnumFontFamiliesEx( lpcf->hDC,
  2764. &lf,
  2765. (FONTENUMPROC)FontStyleEnumProc,
  2766. (LPARAM)&data,
  2767. 0L );
  2768. if (iMapMode != MM_TEXT)
  2769. {
  2770. SetMapMode(lpcf->hDC, iMapMode);
  2771. if ((iMapMode == MM_ISOTROPIC) || (iMapMode == MM_ANISOTROPIC))
  2772. {
  2773. SetWindowExtEx( lpcf->hDC,
  2774. WindowExt.cx,
  2775. WindowExt.cy,
  2776. &WindowExt );
  2777. SetViewportExtEx( lpcf->hDC,
  2778. ViewportExt.cx,
  2779. ViewportExt.cy,
  2780. &ViewportExt );
  2781. }
  2782. }
  2783. }
  2784. if (!(lpcf->Flags & CF_NOSIMULATIONS))
  2785. {
  2786. FillInMissingStyles(data.hwndStyle);
  2787. }
  2788. SendMessage(data.hwndStyle, WM_SETREDRAW, TRUE, 0L);
  2789. if (wWinVer < 0x030A)
  2790. {
  2791. InvalidateRect(data.hwndStyle, NULL, TRUE);
  2792. }
  2793. if (data.bFillSize)
  2794. {
  2795. SendMessage(data.hwndSizes, WM_SETREDRAW, TRUE, 0L);
  2796. if (wWinVer < 0x030A)
  2797. {
  2798. InvalidateRect(data.hwndSizes, NULL, TRUE);
  2799. }
  2800. }
  2801. ResetSampleFromScript(hDlg, data.hwndScript, pFI);
  2802. if (lpcf->Flags & CF_NOSCRIPTSEL)
  2803. {
  2804. pFI->iCharset = DEFAULT_CHARSET;
  2805. }
  2806. bForceSizeFill;
  2807. return (TRUE);
  2808. }
  2809. ////////////////////////////////////////////////////////////////////////////
  2810. //
  2811. // FillColorCombo
  2812. //
  2813. // Adds the color name strings to the colors combobox.
  2814. //
  2815. // cmb4 is the ID for the color combobox.
  2816. //
  2817. // The color rectangles are drawn later in response to a WM_DRAWITEM msg.
  2818. //
  2819. ////////////////////////////////////////////////////////////////////////////
  2820. VOID FillColorCombo(
  2821. HWND hDlg)
  2822. {
  2823. int iT, item;
  2824. TCHAR szT[CCHCOLORNAMEMAX];
  2825. for (iT = 0; iT < CCHCOLORS; ++iT)
  2826. {
  2827. *szT = 0;
  2828. CDLoadString(g_hinst, iszBlack + iT, szT, ARRAYSIZE(szT));
  2829. item = (int) SendDlgItemMessage( hDlg,
  2830. cmb4,
  2831. CB_INSERTSTRING,
  2832. iT,
  2833. (LPARAM)szT );
  2834. if (item >= 0)
  2835. {
  2836. SendDlgItemMessage(hDlg, cmb4, CB_SETITEMDATA, item, rgbColors[iT]);
  2837. }
  2838. }
  2839. }
  2840. ////////////////////////////////////////////////////////////////////////////
  2841. //
  2842. // DrawSizeComboItem
  2843. //
  2844. ////////////////////////////////////////////////////////////////////////////
  2845. BOOL DrawSizeComboItem(
  2846. LPDRAWITEMSTRUCT lpdis)
  2847. {
  2848. HDC hDC;
  2849. DWORD rgbBack, rgbText;
  2850. TCHAR szFace[LF_FACESIZE + 10];
  2851. HFONT hFont;
  2852. hDC = lpdis->hDC;
  2853. //
  2854. // We must first select the dialog control font.
  2855. //
  2856. if (hDlgFont)
  2857. {
  2858. hFont = SelectObject(hDC, hDlgFont);
  2859. }
  2860. if (lpdis->itemState & ODS_SELECTED)
  2861. {
  2862. rgbBack = SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT));
  2863. rgbText = SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  2864. }
  2865. else
  2866. {
  2867. rgbBack = SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
  2868. rgbText = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  2869. }
  2870. // this is cmb2 or cmb3 which are limited to LF_FACESIZE - 1 or less
  2871. SendMessage( lpdis->hwndItem,
  2872. CB_GETLBTEXT,
  2873. lpdis->itemID,
  2874. (LONG_PTR)(LPTSTR)szFace );
  2875. ExtTextOut( hDC,
  2876. lpdis->rcItem.left + GetSystemMetrics(SM_CXBORDER),
  2877. lpdis->rcItem.top,
  2878. ETO_OPAQUE,
  2879. &lpdis->rcItem,
  2880. szFace,
  2881. lstrlen(szFace),
  2882. NULL );
  2883. //
  2884. // Reset font.
  2885. //
  2886. if (hFont)
  2887. {
  2888. SelectObject(hDC, hFont);
  2889. }
  2890. SetTextColor(hDC, rgbText);
  2891. SetBkColor(hDC, rgbBack);
  2892. return (TRUE);
  2893. }
  2894. ////////////////////////////////////////////////////////////////////////////
  2895. //
  2896. // DrawFamilyComboItem
  2897. //
  2898. ////////////////////////////////////////////////////////////////////////////
  2899. BOOL DrawFamilyComboItem(
  2900. LPDRAWITEMSTRUCT lpdis)
  2901. {
  2902. HDC hDC, hdcMem;
  2903. DWORD rgbBack, rgbText;
  2904. TCHAR szFace[LF_FACESIZE + 10];
  2905. HBITMAP hOld;
  2906. int dy, x;
  2907. HFONT hFont;
  2908. hDC = lpdis->hDC;
  2909. //
  2910. // We must first select the dialog control font.
  2911. //
  2912. if (hDlgFont)
  2913. {
  2914. hFont = SelectObject(hDC, hDlgFont);
  2915. }
  2916. if (lpdis->itemState & ODS_SELECTED)
  2917. {
  2918. rgbBack = SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT));
  2919. rgbText = SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  2920. }
  2921. else
  2922. {
  2923. rgbBack = SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
  2924. rgbText = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  2925. }
  2926. // wsprintf(szFace, "%4.4X", LOWORD(lpdis->itemData));
  2927. // this is for cmb1 which is limited to LF_FACESIZE - 1
  2928. SendMessage( lpdis->hwndItem,
  2929. CB_GETLBTEXT,
  2930. lpdis->itemID,
  2931. (LONG_PTR)(LPTSTR)szFace );
  2932. ExtTextOut( hDC,
  2933. lpdis->rcItem.left + DX_BITMAP,
  2934. lpdis->rcItem.top,
  2935. ETO_OPAQUE,
  2936. &lpdis->rcItem,
  2937. szFace,
  2938. lstrlen(szFace),
  2939. NULL );
  2940. //
  2941. // Reset font.
  2942. //
  2943. if (hFont)
  2944. {
  2945. SelectObject(hDC, hFont);
  2946. }
  2947. hdcMem = CreateCompatibleDC(hDC);
  2948. if (hdcMem)
  2949. {
  2950. if (hbmFont)
  2951. {
  2952. LPITEMDATA lpItemData = (LPITEMDATA)lpdis->itemData;
  2953. hOld = SelectObject(hdcMem, hbmFont);
  2954. if (!lpItemData)
  2955. {
  2956. goto SkipBlt;
  2957. }
  2958. if (lpItemData->nFontType & TRUETYPE_FONTTYPE)
  2959. {
  2960. #ifdef WINNT
  2961. if (lpItemData->nFontType & TT_OPENTYPE_FONTTYPE)
  2962. x = 2 * DX_BITMAP;
  2963. else
  2964. #endif
  2965. x = 0;
  2966. }
  2967. #ifdef WINNT
  2968. else if (lpItemData->nFontType & PS_OPENTYPE_FONTTYPE)
  2969. {
  2970. x = 3 * DX_BITMAP;
  2971. }
  2972. else if (lpItemData->nFontType & TYPE1_FONTTYPE)
  2973. {
  2974. x = 4 * DX_BITMAP;
  2975. }
  2976. #endif
  2977. else
  2978. {
  2979. if ((lpItemData->nFontType & (PRINTER_FONTTYPE |
  2980. DEVICE_FONTTYPE))
  2981. == (PRINTER_FONTTYPE | DEVICE_FONTTYPE))
  2982. {
  2983. //
  2984. // This may be a screen and printer font but
  2985. // we will call it a printer font here.
  2986. //
  2987. x = DX_BITMAP;
  2988. }
  2989. else
  2990. {
  2991. goto SkipBlt;
  2992. }
  2993. }
  2994. //If it a mirrored DC then the bitmaps are order from right to left.
  2995. if (IS_DC_RTL_MIRRORED(hdcMem)) {
  2996. x = ((NUM_OF_BITMAP - 1) - (x / DX_BITMAP)) * DX_BITMAP;
  2997. }
  2998. dy = ((lpdis->rcItem.bottom - lpdis->rcItem.top) - DY_BITMAP) / 2;
  2999. BitBlt( hDC,
  3000. lpdis->rcItem.left,
  3001. lpdis->rcItem.top + dy,
  3002. DX_BITMAP,
  3003. DY_BITMAP,
  3004. hdcMem,
  3005. x,
  3006. lpdis->itemState & ODS_SELECTED ? DY_BITMAP : 0,
  3007. SRCCOPY );
  3008. SkipBlt:
  3009. SelectObject(hdcMem, hOld);
  3010. }
  3011. DeleteDC(hdcMem);
  3012. }
  3013. SetTextColor(hDC, rgbText);
  3014. SetBkColor(hDC, rgbBack);
  3015. return (TRUE);
  3016. }
  3017. ////////////////////////////////////////////////////////////////////////////
  3018. //
  3019. // DrawColorComboItem
  3020. //
  3021. // Computes and draws the color combo items.
  3022. // Called by main dialog function in response to a WM_DRAWITEM msg.
  3023. //
  3024. // All color name strings have already been loaded and filled into
  3025. // the combobox.
  3026. //
  3027. // Returns: TRUE if succesful
  3028. // FALSE otherwise.
  3029. //
  3030. ////////////////////////////////////////////////////////////////////////////
  3031. BOOL DrawColorComboItem(
  3032. LPDRAWITEMSTRUCT lpdis)
  3033. {
  3034. HDC hDC;
  3035. HBRUSH hbr;
  3036. int dx, dy;
  3037. RECT rc;
  3038. TCHAR szColor[CCHCOLORNAMEMAX];
  3039. DWORD rgbBack, rgbText, dw;
  3040. HFONT hFont;
  3041. hDC = lpdis->hDC;
  3042. if (lpdis->itemState & ODS_SELECTED)
  3043. {
  3044. rgbBack = SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT));
  3045. rgbText = SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  3046. }
  3047. else
  3048. {
  3049. rgbBack = SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
  3050. rgbText = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  3051. }
  3052. ExtTextOut( hDC,
  3053. lpdis->rcItem.left,
  3054. lpdis->rcItem.top,
  3055. ETO_OPAQUE,
  3056. &lpdis->rcItem,
  3057. NULL,
  3058. 0,
  3059. NULL );
  3060. //
  3061. // Compute coordinates of color rectangle and draw it.
  3062. //
  3063. dx = GetSystemMetrics(SM_CXBORDER);
  3064. dy = GetSystemMetrics(SM_CYBORDER);
  3065. rc.top = lpdis->rcItem.top + dy;
  3066. rc.bottom = lpdis->rcItem.bottom - dy;
  3067. rc.left = lpdis->rcItem.left + dx;
  3068. rc.right = rc.left + 2 * (rc.bottom - rc.top);
  3069. dw = (DWORD) SendMessage(lpdis->hwndItem, CB_GETITEMDATA, lpdis->itemID, 0L);
  3070. hbr = CreateSolidBrush(dw);
  3071. if (!hbr)
  3072. {
  3073. return (FALSE);
  3074. }
  3075. hbr = SelectObject(hDC, hbr);
  3076. Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
  3077. DeleteObject(SelectObject(hDC, hbr));
  3078. //
  3079. // Shift the color text right by the width of the color rectangle.
  3080. //
  3081. *szColor = 0;
  3082. // items in cmb4 are limited to CCHCOLORNAMEMAX at population time
  3083. SendMessage( lpdis->hwndItem,
  3084. CB_GETLBTEXT,
  3085. lpdis->itemID,
  3086. (LONG_PTR)(LPTSTR)szColor );
  3087. //
  3088. // We must first select the dialog control font.
  3089. //
  3090. if (hDlgFont)
  3091. {
  3092. hFont = SelectObject(hDC, hDlgFont);
  3093. }
  3094. TextOut( hDC,
  3095. 2 * dx + rc.right,
  3096. lpdis->rcItem.top,
  3097. szColor,
  3098. lstrlen(szColor) );
  3099. //
  3100. // Reset font.
  3101. //
  3102. if (hFont)
  3103. {
  3104. SelectObject(hDC, hFont);
  3105. }
  3106. SetTextColor(hDC, rgbText);
  3107. SetBkColor(hDC, rgbBack);
  3108. return (TRUE);
  3109. }
  3110. ////////////////////////////////////////////////////////////////////////////
  3111. //
  3112. // DrawSampleText
  3113. //
  3114. // Displays sample text with given attributes. Assumes rcText holds the
  3115. // coordinates of the area within the frame (relative to dialog client)
  3116. // which text should be drawn in.
  3117. //
  3118. ////////////////////////////////////////////////////////////////////////////
  3119. VOID DrawSampleText(
  3120. HWND hDlg,
  3121. PFONTINFO pFI,
  3122. LPCHOOSEFONT lpcf,
  3123. HDC hDC)
  3124. {
  3125. DWORD rgbText;
  3126. DWORD rgbBack;
  3127. int iItem;
  3128. HFONT hFont, hTemp;
  3129. TCHAR szSample[50];
  3130. LOGFONT lf;
  3131. SIZE TextExtent;
  3132. int len, x, y;
  3133. TEXTMETRIC tm;
  3134. BOOL bCompleteFont;
  3135. RECT rcText;
  3136. bCompleteFont = FillInFont(hDlg, pFI, lpcf, &lf, FALSE);
  3137. lf.lfEscapement = 0;
  3138. lf.lfOrientation = 0;
  3139. hFont = CreateFontIndirect(&lf);
  3140. if (!hFont)
  3141. {
  3142. return;
  3143. }
  3144. hTemp = SelectObject(hDC, hFont);
  3145. rgbBack = SetBkColor(hDC, GetSysColor((pFI->ProcessVersion < 0x40000)
  3146. ? COLOR_WINDOW
  3147. : COLOR_3DFACE));
  3148. if (lpcf->Flags & CF_EFFECTS)
  3149. {
  3150. iItem = (int)SendDlgItemMessage(hDlg, cmb4, CB_GETCURSEL, 0, 0L);
  3151. if (iItem != CB_ERR)
  3152. {
  3153. rgbText = (DWORD) SendDlgItemMessage(hDlg, cmb4, CB_GETITEMDATA, iItem, 0L);
  3154. }
  3155. else
  3156. {
  3157. goto GetWindowTextColor;
  3158. }
  3159. }
  3160. else
  3161. {
  3162. GetWindowTextColor:
  3163. rgbText = GetSysColor(COLOR_WINDOWTEXT);
  3164. }
  3165. rgbText = SetTextColor(hDC, rgbText);
  3166. if (bCompleteFont)
  3167. {
  3168. if (GetUnicodeSampleText(hDC, szSample, ARRAYSIZE(szSample)))
  3169. {
  3170. //Empty Body
  3171. }
  3172. else
  3173. {
  3174. GetDlgItemText(hDlg, stc5, szSample, ARRAYSIZE(szSample));
  3175. }
  3176. }
  3177. else
  3178. {
  3179. szSample[0] = 0;
  3180. }
  3181. GetTextMetrics(hDC, &tm);
  3182. len = lstrlen(szSample);
  3183. GetTextExtentPoint(hDC, szSample, len, &TextExtent);
  3184. TextExtent.cy = tm.tmAscent - tm.tmInternalLeading;
  3185. rcText = pFI->rcText;
  3186. if (pFI->ProcessVersion >= 0x40000)
  3187. {
  3188. #ifdef UNICODE
  3189. if (!IS16BITWOWAPP(lpcf) || !(lpcf->Flags & CF_ENABLEHOOK))
  3190. #endif
  3191. {
  3192. DrawEdge(hDC, &rcText, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
  3193. }
  3194. }
  3195. #ifndef WINNT
  3196. else
  3197. {
  3198. //
  3199. // We only care about conforming if we have no border.
  3200. //
  3201. FORWARD_WM_CTLCOLORSTATIC(hDlg, hDC, NULL, SendMessage);
  3202. }
  3203. #endif
  3204. if ((TextExtent.cx >= (rcText.right - rcText.left)) ||
  3205. (TextExtent.cx <= 0))
  3206. {
  3207. x = rcText.left;
  3208. }
  3209. else
  3210. {
  3211. x = rcText.left + ((rcText.right - rcText.left) - TextExtent.cx) / 2;
  3212. }
  3213. y = min( rcText.bottom,
  3214. rcText.bottom - ((rcText.bottom - rcText.top) - TextExtent.cy) / 2);
  3215. ExtTextOut( hDC,
  3216. x,
  3217. y - (tm.tmAscent),
  3218. ETO_OPAQUE | ETO_CLIPPED,
  3219. &rcText,
  3220. szSample,
  3221. len,
  3222. NULL );
  3223. SetBkColor(hDC, rgbBack);
  3224. SetTextColor(hDC, rgbText);
  3225. if (hTemp)
  3226. {
  3227. DeleteObject(SelectObject(hDC, hTemp));
  3228. }
  3229. }
  3230. ////////////////////////////////////////////////////////////////////////////
  3231. //
  3232. // FillInFont
  3233. //
  3234. // Fills in the LOGFONT structure based on the current selection.
  3235. //
  3236. // bSetBits - if TRUE the Flags fields in the lpcf are set to indicate
  3237. // what parts (face, style, size) are not selected
  3238. //
  3239. // lplf - LOGFONT filled in upon return
  3240. //
  3241. // Returns: TRUE if there was an unambiguous selection
  3242. // (the LOGFONT is filled in as per the enumeration)
  3243. // FALSE there was not a complete selection
  3244. // (fields set in the LOGFONT with default values)
  3245. //
  3246. ////////////////////////////////////////////////////////////////////////////
  3247. BOOL FillInFont(
  3248. HWND hDlg,
  3249. PFONTINFO pFI,
  3250. LPCHOOSEFONT lpcf,
  3251. LPLOGFONT lplf,
  3252. BOOL bSetBits)
  3253. {
  3254. HDC hdc;
  3255. int iSel, id, pts;
  3256. LPITEMDATA lpItemData;
  3257. DWORD nFontType;
  3258. PLOGFONT plf;
  3259. TCHAR szStyle[LF_FACESIZE];
  3260. TCHAR szMessage[128];
  3261. BOOL bFontComplete = TRUE;
  3262. CHARSETINFO csi;
  3263. DWORD dwCodePage = GetACP();
  3264. if (!TranslateCharsetInfo(IntToPtr_(DWORD*, dwCodePage), &csi, TCI_SRCCODEPAGE))
  3265. {
  3266. csi.ciCharset = ANSI_CHARSET;
  3267. }
  3268. InitLF(lplf);
  3269. GetDlgItemText( hDlg,
  3270. cmb1,
  3271. lplf->lfFaceName,
  3272. ARRAYSIZE(lplf->lfFaceName));
  3273. if (CBFindString(GetDlgItem(hDlg, cmb1), lplf->lfFaceName) >= 0)
  3274. {
  3275. if (bSetBits)
  3276. {
  3277. lpcf->Flags &= ~CF_NOFACESEL;
  3278. }
  3279. }
  3280. else
  3281. {
  3282. bFontComplete = FALSE;
  3283. if (bSetBits)
  3284. {
  3285. lpcf->Flags |= CF_NOFACESEL;
  3286. }
  3287. }
  3288. iSel = CBGetTextAndData( GetDlgItem(hDlg, cmb2),
  3289. szStyle,
  3290. ARRAYSIZE(szStyle),
  3291. (PULONG_PTR)&lpItemData );
  3292. if ((iSel >= 0) && lpItemData)
  3293. {
  3294. nFontType = lpItemData->nFontType;
  3295. plf = lpItemData->pLogFont;
  3296. *lplf = *plf; // copy the LOGFONT
  3297. lplf->lfWidth = 0; // 1:1 x-y scaling
  3298. if (!lstrcmp(lplf->lfFaceName, TEXT("Small Fonts")))
  3299. {
  3300. lplf->lfCharSet = (BYTE) csi.ciCharset;
  3301. }
  3302. if (bSetBits)
  3303. {
  3304. lpcf->Flags &= ~CF_NOSTYLESEL;
  3305. }
  3306. }
  3307. else
  3308. {
  3309. //
  3310. // Even if the style is invalid, we still need the charset.
  3311. //
  3312. iSel = CBGetTextAndData( GetDlgItem(hDlg, cmb2),
  3313. (LPTSTR)NULL,
  3314. 0,
  3315. (PULONG_PTR)&lpItemData );
  3316. if ((iSel >= 0) && lpItemData)
  3317. {
  3318. nFontType = lpItemData->nFontType;
  3319. plf = lpItemData->pLogFont;
  3320. *lplf = *plf; // copy the LOGFONT
  3321. lplf->lfWidth = 0; // 1:1 x-y scaling
  3322. if (!lstrcmp(lplf->lfFaceName, TEXT("Small Fonts")) ||
  3323. !lstrcmp(lplf->lfFaceName, TEXT("Lucida Sans Unicode")))
  3324. {
  3325. lplf->lfCharSet = (BYTE) csi.ciCharset;
  3326. }
  3327. }
  3328. bFontComplete = FALSE;
  3329. if (bSetBits)
  3330. {
  3331. lpcf->Flags |= CF_NOSTYLESEL;
  3332. }
  3333. nFontType = 0;
  3334. }
  3335. //
  3336. // Now make sure the size is in range; pts will be 0 if not.
  3337. //
  3338. GetPointSizeInRange(hDlg, lpcf, &pts, 0);
  3339. hdc = GetDC(NULL);
  3340. if (pts)
  3341. {
  3342. if (g_bIsSimplifiedChineseUI)
  3343. {
  3344. UINT iHeight;
  3345. int iLogPixY = GetDeviceCaps(hdc, LOGPIXELSY);
  3346. int ptsfr = pts % 10; // fractional point size
  3347. pts /= 10; // real point size
  3348. iHeight = pts * iLogPixY;
  3349. if (ptsfr)
  3350. {
  3351. iHeight += MulDiv(ptsfr, iLogPixY, 10);
  3352. }
  3353. lplf->lfHeight = -((int)((iHeight + POINTS_PER_INCH / 2) /
  3354. POINTS_PER_INCH));
  3355. }
  3356. else
  3357. {
  3358. pts /= 10;
  3359. lplf->lfHeight = -MulDiv( pts,
  3360. GetDeviceCaps(hdc, LOGPIXELSY),
  3361. POINTS_PER_INCH );
  3362. }
  3363. if (bSetBits)
  3364. {
  3365. lpcf->Flags &= ~CF_NOSIZESEL;
  3366. }
  3367. }
  3368. else
  3369. {
  3370. lplf->lfHeight = -MulDiv( DEF_POINT_SIZE,
  3371. GetDeviceCaps(hdc, LOGPIXELSY),
  3372. POINTS_PER_INCH );
  3373. bFontComplete = FALSE;
  3374. if (bSetBits)
  3375. {
  3376. lpcf->Flags |= CF_NOSIZESEL;
  3377. }
  3378. }
  3379. ReleaseDC(NULL, hdc);
  3380. //
  3381. // And the attributes we control.
  3382. //
  3383. lplf->lfStrikeOut = (BYTE)IsDlgButtonChecked(hDlg, chx1);
  3384. lplf->lfUnderline = (BYTE)IsDlgButtonChecked(hDlg, chx2);
  3385. lplf->lfCharSet = (BYTE) pFI->iCharset;
  3386. if (nFontType != pFI->nLastFontType)
  3387. {
  3388. if (lpcf->Flags & CF_PRINTERFONTS)
  3389. {
  3390. if (nFontType & SIMULATED_FONTTYPE)
  3391. {
  3392. id = iszSynth;
  3393. }
  3394. #ifdef WINNT
  3395. else if (nFontType & TT_OPENTYPE_FONTTYPE)
  3396. {
  3397. id = iszTTOpenType;
  3398. }
  3399. else if (nFontType & PS_OPENTYPE_FONTTYPE)
  3400. {
  3401. id = iszPSOpenType;
  3402. }
  3403. else if (nFontType & TYPE1_FONTTYPE)
  3404. {
  3405. id = iszType1;
  3406. }
  3407. #endif
  3408. else if (nFontType & TRUETYPE_FONTTYPE)
  3409. {
  3410. id = iszTrueType;
  3411. }
  3412. else if ((nFontType & (PRINTER_FONTTYPE | DEVICE_FONTTYPE)) ==
  3413. (PRINTER_FONTTYPE | DEVICE_FONTTYPE))
  3414. {
  3415. //
  3416. // May be both screen and printer (ATM) but we'll just
  3417. // call this a printer font.
  3418. //
  3419. id = iszPrinterFont;
  3420. }
  3421. else if ((nFontType & (PRINTER_FONTTYPE | SCREEN_FONTTYPE)) ==
  3422. SCREEN_FONTTYPE)
  3423. {
  3424. id = iszGDIFont;
  3425. }
  3426. else
  3427. {
  3428. szMessage[0] = 0;
  3429. goto SetText;
  3430. }
  3431. CDLoadString( g_hinst,
  3432. id,
  3433. szMessage,
  3434. ARRAYSIZE(szMessage));
  3435. SetText:
  3436. SetDlgItemText(hDlg, stc6, szMessage);
  3437. }
  3438. }
  3439. pFI->nLastFontType = nFontType;
  3440. return (bFontComplete);
  3441. }
  3442. ////////////////////////////////////////////////////////////////////////////
  3443. //
  3444. // SetLogFont
  3445. //
  3446. // Sets the current selection based on the LOGFONT structure passed in.
  3447. //
  3448. // lpcf - CHOOSEFONT structure for the current dialog
  3449. // lplf - LOGFONT filled in upon return
  3450. //
  3451. // Returns: TRUE if there was an unambiguous selection
  3452. // (the LOGFONT is filled in as per the enumeration)
  3453. // FALSE there was not a complete selection
  3454. // (fields set in the LOGFONT with default values)
  3455. //
  3456. ////////////////////////////////////////////////////////////////////////////
  3457. BOOL SetLogFont(
  3458. HWND hDlg,
  3459. LPCHOOSEFONT lpcf,
  3460. LPLOGFONT lplf)
  3461. {
  3462. *(lpcf->lpLogFont) = *lplf; // Copies data & FaceName
  3463. FORWARD_WM_COMMAND( hDlg,
  3464. cmb1,
  3465. GetDlgItem(hDlg, cmb1),
  3466. CBN_SELCHANGE,
  3467. SendMessage );
  3468. return (TRUE);
  3469. }
  3470. ////////////////////////////////////////////////////////////////////////////
  3471. //
  3472. // TermFont
  3473. //
  3474. // Release any data required by functions in this module.
  3475. //
  3476. ////////////////////////////////////////////////////////////////////////////
  3477. VOID TermFont()
  3478. {
  3479. if (hbmFont)
  3480. {
  3481. DeleteObject(hbmFont);
  3482. }
  3483. }
  3484. ////////////////////////////////////////////////////////////////////////////
  3485. //
  3486. // GetPointString
  3487. //
  3488. // Converts font height into a string of digits representing point size.
  3489. //
  3490. // Returns: Size in points and fills in buffer with string
  3491. //
  3492. ////////////////////////////////////////////////////////////////////////////
  3493. int GetPointString(
  3494. LPTSTR buf,
  3495. UINT cch,
  3496. HDC hDC,
  3497. int height)
  3498. {
  3499. int pts;
  3500. if (g_bIsSimplifiedChineseUI)
  3501. {
  3502. int ptsfr, iLogPixY, ctr;
  3503. long lpts;
  3504. BOOL IsZihao = FALSE;
  3505. lpts = ((height < 0) ? -height : height) * 72;
  3506. //
  3507. // Get real point size.
  3508. //
  3509. pts = (int)(lpts / (iLogPixY = GetDeviceCaps(hDC, LOGPIXELSY)));
  3510. //
  3511. // Get fractional point size.
  3512. //
  3513. ptsfr = MulDiv((int)(lpts % iLogPixY), 10, iLogPixY);
  3514. //
  3515. // See if it's Zihao.
  3516. //
  3517. for (ctr = 0; ctr < NUM_ZIHAO; ctr++)
  3518. {
  3519. if ((pts == stZihao[ctr].size) &&
  3520. (abs(ptsfr - stZihao[ctr].sizeFr) <= 3))
  3521. {
  3522. IsZihao = TRUE;
  3523. wnsprintf(buf, cch, TEXT("%s"), stZihao[ctr].name);
  3524. break;
  3525. }
  3526. }
  3527. if (!IsZihao)
  3528. {
  3529. pts = MulDiv((height < 0) ? -height : height, 72, iLogPixY);
  3530. for (ctr = 0; ctr < NUM_ZIHAO; ctr++)
  3531. {
  3532. if ((pts == stZihao[ctr].size) && (!stZihao[ctr].sizeFr))
  3533. {
  3534. IsZihao = TRUE;
  3535. wnsprintf(buf, cch, TEXT("%s"), stZihao[ctr].name);
  3536. break;
  3537. }
  3538. }
  3539. }
  3540. if (!IsZihao)
  3541. {
  3542. wnsprintf(buf, cch, szPtFormat, pts);
  3543. }
  3544. }
  3545. else
  3546. {
  3547. pts = MulDiv( (height < 0) ? -height : height,
  3548. 72,
  3549. GetDeviceCaps(hDC, LOGPIXELSY) );
  3550. wnsprintf(buf, cch, szPtFormat, pts);
  3551. }
  3552. return (pts);
  3553. }
  3554. ////////////////////////////////////////////////////////////////////////////
  3555. //
  3556. // FlipColor
  3557. //
  3558. ////////////////////////////////////////////////////////////////////////////
  3559. DWORD FlipColor(
  3560. DWORD rgb)
  3561. {
  3562. return ( RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb)) );
  3563. }
  3564. ////////////////////////////////////////////////////////////////////////////
  3565. //
  3566. // LoadBitmaps
  3567. //
  3568. // This routine loads DIB bitmaps, and "fixes up" their color tables
  3569. // so that we get the desired result for the device we are on.
  3570. //
  3571. // This routine requires:
  3572. // the DIB is a 16 color DIB authored with the standard windows colors
  3573. // bright blue (00 00 FF) is converted to the background color
  3574. // light grey (C0 C0 C0) is replaced with the button face color
  3575. // dark grey (80 80 80) is replaced with the button shadow color
  3576. //
  3577. // This means you can't have any of these colors in your bitmap.
  3578. //
  3579. ////////////////////////////////////////////////////////////////////////////
  3580. #define BACKGROUND 0x000000FF // bright blue
  3581. #define BACKGROUNDSEL 0x00FF00FF // bright blue
  3582. #define BUTTONFACE 0x00C0C0C0 // bright grey
  3583. #define BUTTONSHADOW 0x00808080 // dark grey
  3584. HBITMAP LoadBitmaps(
  3585. int id)
  3586. {
  3587. HDC hdc;
  3588. HANDLE h;
  3589. DWORD *p;
  3590. BYTE *lpBits;
  3591. HANDLE hRes;
  3592. LPBITMAPINFOHEADER lpBitmapInfo;
  3593. int numcolors;
  3594. DWORD rgbSelected;
  3595. DWORD rgbUnselected;
  3596. HBITMAP hbm;
  3597. UINT cbBitmapSize;
  3598. LPBITMAPINFOHEADER lpBitmapData;
  3599. rgbSelected = FlipColor(GetSysColor(COLOR_HIGHLIGHT));
  3600. rgbUnselected = FlipColor(GetSysColor(COLOR_WINDOW));
  3601. h = FindResource(g_hinst, MAKEINTRESOURCE(id), RT_BITMAP);
  3602. hRes = LoadResource(g_hinst, h);
  3603. //
  3604. // Lock the bitmap and get a pointer to the color table.
  3605. //
  3606. lpBitmapInfo = (LPBITMAPINFOHEADER)LockResource(hRes);
  3607. if (!lpBitmapInfo)
  3608. {
  3609. return (FALSE);
  3610. }
  3611. //
  3612. // Lock the bitmap data and make a copy of it for the mask and the
  3613. // bitmap.
  3614. //
  3615. cbBitmapSize = SizeofResource(g_hinst, h);
  3616. lpBitmapData = (LPBITMAPINFOHEADER)LocalAlloc(LPTR, cbBitmapSize);
  3617. if (!lpBitmapData)
  3618. {
  3619. return (NULL);
  3620. }
  3621. memcpy((TCHAR *)lpBitmapData, (TCHAR *)lpBitmapInfo, cbBitmapSize);
  3622. p = (DWORD *)((LPTSTR)(lpBitmapData) + lpBitmapData->biSize);
  3623. //
  3624. // Search for the Solid Blue entry and replace it with the current
  3625. // background RGB.
  3626. //
  3627. numcolors = 16;
  3628. while (numcolors-- > 0)
  3629. {
  3630. if (*p == BACKGROUND)
  3631. {
  3632. *p = rgbUnselected;
  3633. }
  3634. else if (*p == BACKGROUNDSEL)
  3635. {
  3636. *p = rgbSelected;
  3637. }
  3638. #if 0
  3639. else if (*p == BUTTONFACE)
  3640. {
  3641. *p = FlipColor(GetSysColor(COLOR_BTNFACE));
  3642. }
  3643. else if (*p == BUTTONSHADOW)
  3644. {
  3645. *p = FlipColor(GetSysColor(COLOR_BTNSHADOW));
  3646. }
  3647. #endif
  3648. p++;
  3649. }
  3650. //
  3651. // First skip over the header structure.
  3652. //
  3653. lpBits = (BYTE *)(lpBitmapData + 1);
  3654. //
  3655. // Skip the color table entries, if any.
  3656. //
  3657. lpBits += (1 << (lpBitmapData->biBitCount)) * sizeof(RGBQUAD);
  3658. //
  3659. // Create a color bitmap compatible with the display device.
  3660. //
  3661. hdc = GetDC(NULL);
  3662. hbm = CreateDIBitmap( hdc,
  3663. lpBitmapData,
  3664. (DWORD)CBM_INIT,
  3665. lpBits,
  3666. (LPBITMAPINFO)lpBitmapData,
  3667. DIB_RGB_COLORS );
  3668. ReleaseDC(NULL, hdc);
  3669. LocalFree(lpBitmapData);
  3670. return (hbm);
  3671. }
  3672. ////////////////////////////////////////////////////////////////////////////
  3673. //
  3674. // LookUpFontSubs
  3675. //
  3676. // Looks in the font substitute list for a real font name.
  3677. //
  3678. // lpSubFontName - substitute font name
  3679. // lpRealFontName - real font name buffer
  3680. //
  3681. // Returns: TRUE if lpRealFontName is filled in
  3682. // FALSE if not
  3683. //
  3684. ////////////////////////////////////////////////////////////////////////////
  3685. BOOL LookUpFontSubs(LPCTSTR lpSubFontName, LPTSTR lpRealFontName, UINT cch)
  3686. {
  3687. LONG lResult;
  3688. HKEY hKey;
  3689. TCHAR szValueName[MAX_PATH];
  3690. TCHAR szValueData[MAX_PATH];
  3691. DWORD cchValueSize;
  3692. DWORD dwIndex = 0;
  3693. DWORD dwType, cbSize;
  3694. //
  3695. // Open the font substitution's key.
  3696. //
  3697. lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  3698. KEY_FONT_SUBS,
  3699. 0,
  3700. KEY_READ,
  3701. &hKey );
  3702. if (lResult != ERROR_SUCCESS)
  3703. {
  3704. return (FALSE);
  3705. }
  3706. //
  3707. // Loop through the values in the key
  3708. //
  3709. cchValueSize = ARRAYSIZE(szValueName);
  3710. cbSize = sizeof(szValueData);
  3711. while (RegEnumValue( hKey,
  3712. dwIndex,
  3713. szValueName,
  3714. &cchValueSize,
  3715. NULL,
  3716. &dwType,
  3717. (LPBYTE)szValueData,
  3718. &cbSize ) == ERROR_SUCCESS)
  3719. {
  3720. //
  3721. // If the value name matches the requested font name, then
  3722. // copy the real font name to the output buffer.
  3723. //
  3724. if (!lstrcmpi(szValueName, lpSubFontName))
  3725. {
  3726. lstrcpyn(lpRealFontName, szValueData, cch);
  3727. RegCloseKey(hKey);
  3728. return (TRUE);
  3729. }
  3730. //
  3731. // Re-initialize for the next time through the loop.
  3732. //
  3733. cchValueSize = ARRAYSIZE(szValueName);
  3734. cbSize = sizeof(szValueData);
  3735. dwIndex++;
  3736. }
  3737. //
  3738. // Clean up.
  3739. //
  3740. *lpRealFontName = CHAR_NULL;
  3741. RegCloseKey(hKey);
  3742. return (FALSE);
  3743. }
  3744. ////////////////////////////////////////////////////////////////////////////
  3745. //
  3746. // GetUnicodeSampleText
  3747. //
  3748. // Gets the sample text for the font selected in the HDC
  3749. //
  3750. ////////////////////////////////////////////////////////////////////////////
  3751. BOOL GetUnicodeSampleText(HDC hdc, LPTSTR lpString, int cchMaxCount)
  3752. {
  3753. FONTSIGNATURE sig;
  3754. int i, j;
  3755. int iLang = 0;
  3756. int base = 0;
  3757. int mask;
  3758. if (!lpString || !cchMaxCount)
  3759. {
  3760. return FALSE;
  3761. }
  3762. //Make sure return value is nulled
  3763. lpString[0] = 0;
  3764. //First Get the Font Signature
  3765. GetTextCharsetInfo(hdc, &sig, 0);
  3766. //Select the first unicode range supported by this font
  3767. //For each of Unicode dwords
  3768. for (i=0; i < 4; i++)
  3769. {
  3770. // See if a particular bit is set
  3771. for (j=0; j < sizeof(DWORD) * 8 ; j++)
  3772. {
  3773. mask = 1 << j;
  3774. if (sig.fsUsb[i] & mask)
  3775. {
  3776. //if set the get the language id for that bit
  3777. iLang = base + j;
  3778. goto LoadString;
  3779. }
  3780. }
  3781. base +=32;
  3782. }
  3783. LoadString:
  3784. //Do we have lang id and string for that language ?
  3785. if (iLang && LoadString(g_hinst, iszUnicode + iLang, lpString, cchMaxCount))
  3786. {
  3787. return TRUE;
  3788. }
  3789. return FALSE;
  3790. }
  3791. /*========================================================================*/
  3792. /* Ansi->Unicode Thunk routines */
  3793. /*========================================================================*/
  3794. #ifdef UNICODE
  3795. ////////////////////////////////////////////////////////////////////////////
  3796. //
  3797. // ThunkChooseFontA2W
  3798. //
  3799. ////////////////////////////////////////////////////////////////////////////
  3800. void ThunkChooseFontA2W(
  3801. PFONTINFO pFI)
  3802. {
  3803. LPCHOOSEFONTW pCFW = pFI->pCF;
  3804. LPCHOOSEFONTA pCFA = pFI->pCFA;
  3805. pCFW->hwndOwner = pCFA->hwndOwner;
  3806. pCFW->lCustData = pCFA->lCustData;
  3807. pCFW->Flags = pCFA->Flags;
  3808. //
  3809. // !!! hack, should not be based on flag value, since this could happen
  3810. // at any time.
  3811. //
  3812. if (pCFA->Flags & CF_INITTOLOGFONTSTRUCT)
  3813. {
  3814. ThunkLogFontA2W( pCFA->lpLogFont, pCFW->lpLogFont);
  3815. }
  3816. pCFW->hInstance = pCFA->hInstance;
  3817. pCFW->lpfnHook = pCFA->lpfnHook;
  3818. if (pCFW->Flags & CF_PRINTERFONTS)
  3819. {
  3820. pCFW->hDC = pCFA->hDC;
  3821. }
  3822. if (pCFW->Flags & CF_USESTYLE)
  3823. {
  3824. RtlAnsiStringToUnicodeString(pFI->pusStyle, pFI->pasStyle, FALSE);
  3825. }
  3826. pCFW->nSizeMin = pCFA->nSizeMin;
  3827. pCFW->nSizeMax = pCFA->nSizeMax;
  3828. pCFW->rgbColors = pCFA->rgbColors;
  3829. pCFW->iPointSize = pCFA->iPointSize;
  3830. pCFW->nFontType = pCFA->nFontType;
  3831. }
  3832. ////////////////////////////////////////////////////////////////////////////
  3833. //
  3834. // ThunkChooseFontW2A
  3835. //
  3836. ////////////////////////////////////////////////////////////////////////////
  3837. void ThunkChooseFontW2A(
  3838. PFONTINFO pFI)
  3839. {
  3840. LPCHOOSEFONTA pCFA = pFI->pCFA;
  3841. LPCHOOSEFONTW pCFW = pFI->pCF;
  3842. ThunkLogFontW2A( pCFW->lpLogFont, pCFA->lpLogFont);
  3843. pCFA->hInstance = pCFW->hInstance;
  3844. pCFA->lpfnHook = pCFW->lpfnHook;
  3845. if (pCFA->Flags & CF_USESTYLE)
  3846. {
  3847. pFI->pusStyle->Length = (USHORT)((lstrlen(pFI->pusStyle->Buffer) + 1) * sizeof(WCHAR));
  3848. RtlUnicodeStringToAnsiString(pFI->pasStyle, pFI->pusStyle, FALSE);
  3849. }
  3850. pCFA->Flags = pCFW->Flags;
  3851. pCFA->nSizeMin = pCFW->nSizeMin;
  3852. pCFA->nSizeMax = pCFW->nSizeMax;
  3853. pCFA->rgbColors = pCFW->rgbColors;
  3854. pCFA->iPointSize = pCFW->iPointSize;
  3855. pCFA->nFontType = pCFW->nFontType;
  3856. pCFA->lCustData = pCFW->lCustData;
  3857. }
  3858. ////////////////////////////////////////////////////////////////////////////
  3859. //
  3860. // ThunkLogFontA2W
  3861. //
  3862. ////////////////////////////////////////////////////////////////////////////
  3863. VOID ThunkLogFontA2W(
  3864. LPLOGFONTA lpLFA,
  3865. LPLOGFONTW lpLFW)
  3866. {
  3867. lpLFW->lfHeight = lpLFA->lfHeight;
  3868. lpLFW->lfWidth = lpLFA->lfWidth;
  3869. lpLFW->lfEscapement = lpLFA->lfEscapement;
  3870. lpLFW->lfOrientation = lpLFA->lfOrientation;
  3871. lpLFW->lfWeight = lpLFA->lfWeight;
  3872. lpLFW->lfItalic = lpLFA->lfItalic;
  3873. lpLFW->lfUnderline = lpLFA->lfUnderline;
  3874. lpLFW->lfStrikeOut = lpLFA->lfStrikeOut;
  3875. lpLFW->lfCharSet = lpLFA->lfCharSet;
  3876. lpLFW->lfOutPrecision = lpLFA->lfOutPrecision;
  3877. lpLFW->lfClipPrecision = lpLFA->lfClipPrecision;
  3878. lpLFW->lfQuality = lpLFA->lfQuality;
  3879. lpLFW->lfPitchAndFamily = lpLFA->lfPitchAndFamily;
  3880. SHAnsiToUnicode(lpLFA->lfFaceName, lpLFW->lfFaceName, ARRAYSIZE(lpLFW->lfFaceName));
  3881. }
  3882. ////////////////////////////////////////////////////////////////////////////
  3883. //
  3884. // ThunkLogFontW2A
  3885. //
  3886. ////////////////////////////////////////////////////////////////////////////
  3887. VOID ThunkLogFontW2A(
  3888. LPLOGFONTW lpLFW,
  3889. LPLOGFONTA lpLFA)
  3890. {
  3891. if (lpLFW && lpLFA)
  3892. {
  3893. lpLFA->lfHeight = lpLFW->lfHeight;
  3894. lpLFA->lfWidth = lpLFW->lfWidth;
  3895. lpLFA->lfEscapement = lpLFW->lfEscapement;
  3896. lpLFA->lfOrientation = lpLFW->lfOrientation;
  3897. lpLFA->lfWeight = lpLFW->lfWeight;
  3898. lpLFA->lfItalic = lpLFW->lfItalic;
  3899. lpLFA->lfUnderline = lpLFW->lfUnderline;
  3900. lpLFA->lfStrikeOut = lpLFW->lfStrikeOut;
  3901. lpLFA->lfCharSet = lpLFW->lfCharSet;
  3902. lpLFA->lfOutPrecision = lpLFW->lfOutPrecision;
  3903. lpLFA->lfClipPrecision = lpLFW->lfClipPrecision;
  3904. lpLFA->lfQuality = lpLFW->lfQuality;
  3905. lpLFA->lfPitchAndFamily = lpLFW->lfPitchAndFamily;
  3906. SHUnicodeToAnsi(lpLFW->lfFaceName, lpLFA->lfFaceName, ARRAYSIZE(lpLFA->lfFaceName));
  3907. }
  3908. }
  3909. #ifdef WINNT
  3910. ////////////////////////////////////////////////////////////////////////////
  3911. //
  3912. // Ssync_ANSI_UNICODE_CF_For_WOW
  3913. //
  3914. // Function to allow NT WOW to keep the ANSI & UNICODE versions of
  3915. // the CHOOSEFONT structure in ssync as required by many 16-bit apps.
  3916. // See notes for Ssync_ANSI_UNICODE_Struct_For_WOW() in dlgs.c.
  3917. //
  3918. ////////////////////////////////////////////////////////////////////////////
  3919. VOID Ssync_ANSI_UNICODE_CF_For_WOW(
  3920. HWND hDlg,
  3921. BOOL f_ANSI_to_UNICODE)
  3922. {
  3923. PFONTINFO pFI;
  3924. if (pFI = (PFONTINFO)GetProp(hDlg, FONTPROP))
  3925. {
  3926. if (pFI->pCF && pFI->pCFA)
  3927. {
  3928. if (f_ANSI_to_UNICODE)
  3929. {
  3930. ThunkChooseFontA2W(pFI);
  3931. }
  3932. else
  3933. {
  3934. ThunkChooseFontW2A(pFI);
  3935. }
  3936. }
  3937. }
  3938. }
  3939. #endif // WINNT
  3940. #endif // UNICODE