Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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