xref: /reactos/dll/win32/comdlg32/fontdlg.c (revision 4a7f3bdb)
1 /*
2  * COMMDLG - Font Dialog
3  *
4  * Copyright 1994 Martin Ayotte
5  * Copyright 1996 Albrecht Kleine
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include "cdlg.h"
23 
24 typedef struct
25 {
26   HWND hWnd1;
27   HWND hWnd2;
28   LPCHOOSEFONTW lpcf32w;
29   int  added;
30 } CFn_ENUMSTRUCT, *LPCFn_ENUMSTRUCT;
31 
32 
33 static const WCHAR strWineFontData[] = {'_','_','W','I','N','E','_','F','O','N','T','D','L','G','D','A','T','A',0};
34 static const WCHAR strWineFontData_a[] =
35                                {'_','_','W','I','N','E','_','F','O','N','T','D','L','G','D','A','T','A','_','A',0};
36 static const WCHAR chooseFontW[] = {'C','H','O','O','S','E','_','F','O','N','T',0};
37 static const WCHAR fontsizefmtW[] = {'%','d',0};
38 
39 /* image list with TrueType bitmaps and more */
40 static HIMAGELIST himlTT = 0;
41 #define TTBITMAP_XSIZE 20 /* x-size of the bitmaps */
42 
43 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
44 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
45 
46 /* There is a table here of all charsets, and the sample text for each.
47  * There is a second table that translates a charset into an index into
48  * the first table.
49  */
50 
51 #define CI(cs) ((IDS_CHARSET_##cs)-IDS_CHARSET_ANSI)
52 
53 
54 static const WCHAR stWestern[]={'A','a','B','b','Y','y','Z','z',0}; /* Western and default */
55 static const WCHAR stSymbol[]={'S','y','m','b','o','l',0}; /* Symbol */
56 static const WCHAR stShiftJis[]={'A','a',0x3042,0x3041,0x30a2,0x30a1,0x4e9c,0x5b87,0}; /* Shift JIS */
57 static const WCHAR stHangul[]={0xac00,0xb098,0xb2e4,'A','a','B','Y','y','Z','z',0}; /* Hangul */
58 static const WCHAR stGB2312[]={0x5fae,0x8f6f,0x4e2d,0x6587,0x8f6f,0x4ef6,0}; /* GB2312 */
59 static const WCHAR stBIG5[]={0x4e2d,0x6587,0x5b57,0x578b,0x7bc4,0x4f8b,0}; /* BIG5 */
60 static const WCHAR stGreek[]={'A','a','B','b',0x0391,0x03b1,0x0392,0x03b2,0}; /* Greek */
61 static const WCHAR stTurkish[]={'A','a','B','b',0x011e,0x011f,0x015e,0x015f,0}; /* Turkish */
62 static const WCHAR stHebrew[]={'A','a','B','b',0x05e0,0x05e1,0x05e9,0x05ea,0}; /* Hebrew */
63 static const WCHAR stArabic[]={'A','a','B','b',0x0627,0x0628,0x062c,0x062f,0x0647,0x0648,0x0632,0};/* Arabic */
64 static const WCHAR stBaltic[]={'A','a','B','b','Y','y','Z','z',0}; /* Baltic */
65 static const WCHAR stVietname[]={'A','a','B','b',0x01a0,0x01a1,0x01af,0x01b0,0}; /* Vietnamese */
66 static const WCHAR stCyrillic[]={'A','a','B','b',0x0411,0x0431,0x0424,0x0444,0}; /* Cyrillic */
67 static const WCHAR stEastEur[]={'A','a','B','b',0xc1,0xe1,0xd4,0xf4,0}; /* East European */
68 static const WCHAR stThai[]={'A','a','B','b',0x0e2d,0x0e31,0x0e01,0x0e29,0x0e23,0x0e44,0x0e17,0x0e22,0}; /* Thai */
69 static const WCHAR stJohab[]={0xac00,0xb098,0xb2e4,'A','a','B','Y','y','Z','z',0}; /* Johab */
70 static const WCHAR stMac[]={'A','a','B','b','Y','y','Z','z',0}; /* Mac */
71 static const WCHAR stOEM[]={'A','a','B','b',0xf8,0xf1,0xfd,0}; /* OEM */
72 /* the following character sets actually behave different (Win2K observation):
73  * the sample string is 'sticky': it uses the sample string of the previous
74  * selected character set. That behaviour looks like some default, which is
75  * not (yet) implemented. */
76 static const WCHAR stVISCII[]={'A','a','B','b',0}; /* VISCII */
77 static const WCHAR stTCVN[]={'A','a','B','b',0}; /* TCVN */
78 static const WCHAR stKOI8[]={'A','a','B','b',0}; /* KOI-8 */
79 static const WCHAR stIso88593[]={'A','a','B','b',0}; /* ISO-8859-3 */
80 static const WCHAR stIso88594[]={'A','a','B','b',0}; /* ISO-8859-4 */
81 static const WCHAR stIso885910[]={'A','a','B','b',0}; /* ISO-8859-10 */
82 static const WCHAR stCeltic[]={'A','a','B','b',0};/* Celtic */
83 
84 static const WCHAR * const sample_lang_text[]={
85     stWestern,stSymbol,stShiftJis,stHangul,stGB2312,
86     stBIG5,stGreek,stTurkish,stHebrew,stArabic,
87     stBaltic,stVietname,stCyrillic,stEastEur,stThai,
88     stJohab,stMac,stOEM,stVISCII,stTCVN,
89     stKOI8,stIso88593,stIso88594,stIso885910,stCeltic};
90 
91 
92 static const BYTE CHARSET_ORDER[256]={
93     CI(ANSI), 0, CI(SYMBOL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
94     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
95     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
96     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
97     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(MAC), 0, 0,
98     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
99     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
100     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101     CI(JIS), CI(HANGUL), CI(JOHAB), 0, 0, 0, CI(GB2312), 0, CI(BIG5), 0, 0, 0, 0, 0, 0, 0,
102     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103     0, CI(GREEK), CI(TURKISH), CI(VIETNAMESE), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104     0, CI(HEBREW), CI(ARABIC), 0, 0, 0, 0, 0, 0, 0, CI(BALTIC), 0, 0, 0, 0, 0,
105     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(RUSSIAN), 0, 0, 0,
106     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(THAI), 0,
107     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(EE), 0,
108     CI(VISCII), CI(TCVN), CI(KOI8), CI(ISO3), CI(ISO4), CI(ISO10), CI(CELTIC), 0, 0, 0, 0, 0, 0, 0, 0, CI(OEM),
109 };
110 
111 static const struct {
112     DWORD       mask;
113     const char *name;
114 } cfflags[] = {
115 #define XX(x) { x, #x },
116     XX(CF_SCREENFONTS)
117     XX(CF_PRINTERFONTS)
118     XX(CF_SHOWHELP)
119     XX(CF_ENABLEHOOK)
120     XX(CF_ENABLETEMPLATE)
121     XX(CF_ENABLETEMPLATEHANDLE)
122     XX(CF_INITTOLOGFONTSTRUCT)
123     XX(CF_USESTYLE)
124     XX(CF_EFFECTS)
125     XX(CF_APPLY)
126     XX(CF_ANSIONLY)
127     XX(CF_NOVECTORFONTS)
128     XX(CF_NOSIMULATIONS)
129     XX(CF_LIMITSIZE)
130     XX(CF_FIXEDPITCHONLY)
131     XX(CF_WYSIWYG)
132     XX(CF_FORCEFONTEXIST)
133     XX(CF_SCALABLEONLY)
134     XX(CF_TTONLY)
135     XX(CF_NOFACESEL)
136     XX(CF_NOSTYLESEL)
137     XX(CF_NOSIZESEL)
138     XX(CF_SELECTSCRIPT)
139     XX(CF_NOSCRIPTSEL)
140     XX(CF_NOVERTFONTS)
141 #undef XX
142 };
143 
144 static void _dump_cf_flags(DWORD cflags)
145 {
146     unsigned int i;
147 
148     for (i = 0; i < sizeof(cfflags)/sizeof(cfflags[0]); i++)
149         if (cfflags[i].mask & cflags)
150             TRACE("%s|",cfflags[i].name);
151     TRACE("\n");
152 }
153 
154 /***********************************************************************
155  *           ChooseFontW   (COMDLG32.@)
156  *
157  * Create a font dialog box.
158  *
159  * PARAMS
160  *  lpChFont [I/O] in:  information to initialize the dialog box.
161  *                 out: User's color selection
162  *
163  * RETURNS
164  *  TRUE:  Ok button clicked.
165  *  FALSE: Cancel button clicked, or error.
166  */
167 BOOL WINAPI ChooseFontW(LPCHOOSEFONTW lpChFont)
168 {
169     LPCVOID template;
170     HRSRC hResInfo;
171     HINSTANCE hDlginst;
172     HGLOBAL hDlgTmpl;
173 
174     TRACE("(%p)\n", lpChFont);
175 
176     if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 )
177     {
178         template=lpChFont->hInstance;
179     } else
180     {
181         if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 )
182         {
183             hDlginst=lpChFont->hInstance;
184             if( !(hResInfo = FindResourceW(hDlginst, lpChFont->lpTemplateName,
185                             (LPWSTR)RT_DIALOG)))
186             {
187                 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
188                 return FALSE;
189             }
190         } else
191         {
192             hDlginst=COMDLG32_hInstance;
193             if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG)))
194             {
195                 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
196                 return FALSE;
197             }
198         }
199         if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) ||
200                 !(template = LockResource( hDlgTmpl )))
201         {
202             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
203             return FALSE;
204         }
205     }
206     if (TRACE_ON(commdlg))
207         _dump_cf_flags(lpChFont->Flags);
208 
209     if (lpChFont->Flags & CF_SELECTSCRIPT)
210         FIXME(": unimplemented flag (ignored)\n");
211 
212     return DialogBoxIndirectParamW(COMDLG32_hInstance, template,
213             lpChFont->hwndOwner, FormatCharDlgProcW, (LPARAM)lpChFont );
214 }
215 
216 /***********************************************************************
217  *           ChooseFontA   (COMDLG32.@)
218  *
219  * See ChooseFontW.
220  */
221 BOOL WINAPI ChooseFontA(LPCHOOSEFONTA lpChFont)
222 {
223     LPCVOID template;
224     HRSRC hResInfo;
225     HINSTANCE hDlginst;
226     HGLOBAL hDlgTmpl;
227 
228     TRACE("(%p)\n", lpChFont);
229 
230     if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 )
231     {
232         template=lpChFont->hInstance;
233     } else
234     {
235         if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 )
236         {
237             hDlginst=lpChFont->hInstance;
238             if( !(hResInfo = FindResourceA(hDlginst, lpChFont->lpTemplateName,
239                             (LPSTR)RT_DIALOG)))
240             {
241                 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
242                 return FALSE;
243             }
244         } else
245         {
246             hDlginst=COMDLG32_hInstance;
247             if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG)))
248             {
249                 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
250                 return FALSE;
251             }
252         }
253         if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) ||
254                 !(template = LockResource( hDlgTmpl )))
255         {
256             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
257             return FALSE;
258         }
259     }
260     if (TRACE_ON(commdlg))
261         _dump_cf_flags(lpChFont->Flags);
262     if (lpChFont->Flags & CF_SELECTSCRIPT)
263         FIXME(": unimplemented flag (ignored)\n");
264 
265     return DialogBoxIndirectParamA(COMDLG32_hInstance, template,
266             lpChFont->hwndOwner, FormatCharDlgProcA, (LPARAM)lpChFont );
267 }
268 
269 #define TEXT_EXTRAS 4
270 #define TEXT_COLORS 16
271 
272 static const COLORREF textcolors[TEXT_COLORS]=
273 {
274     0x00000000L,0x00000080L,0x00008000L,0x00008080L,
275     0x00800000L,0x00800080L,0x00808000L,0x00808080L,
276     0x00c0c0c0L,0x000000ffL,0x0000ff00L,0x0000ffffL,
277     0x00ff0000L,0x00ff00ffL,0x00ffff00L,0x00FFFFFFL
278 };
279 
280 /***********************************************************************
281  *                          CFn_HookCallChk32                 [internal]
282  */
283 static BOOL CFn_HookCallChk32(const CHOOSEFONTW *lpcf)
284 {
285     if (lpcf)
286         if(lpcf->Flags & CF_ENABLEHOOK)
287             if (lpcf->lpfnHook)
288                 return TRUE;
289     return FALSE;
290 }
291 
292 /*************************************************************************
293  *              AddFontFamily                               [internal]
294  */
295 static INT AddFontFamily(const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM,
296                          UINT nFontType, const CHOOSEFONTW *lpcf, HWND hwnd, LPCFn_ENUMSTRUCT e)
297 {
298     int i;
299     WORD w;
300     const LOGFONTW *lplf = &(lpElfex->elfLogFont);
301 
302     TRACE("font=%s (nFontType=%d)\n", debugstr_w(lplf->lfFaceName), nFontType);
303 
304     if (lpcf->Flags & CF_FIXEDPITCHONLY)
305         if (!(lplf->lfPitchAndFamily & FIXED_PITCH))
306             return 1;
307     if (lpcf->Flags & CF_ANSIONLY)
308         if (lplf->lfCharSet != ANSI_CHARSET)
309             return 1;
310     if (lpcf->Flags & CF_TTONLY)
311         if (!(nFontType & TRUETYPE_FONTTYPE))
312             return 1;
313     if (lpcf->Flags & CF_NOVERTFONTS)
314         if (lplf->lfFaceName[0] == '@')
315             return 1;
316 
317     if (e) e->added++;
318 
319     i=SendMessageW(hwnd, CB_FINDSTRINGEXACT, 0, (LPARAM)lplf->lfFaceName);
320     if (i == CB_ERR) {
321         i = SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)lplf->lfFaceName);
322         if( i != CB_ERR) {
323             /* store some important font information */
324             w = (lplf->lfPitchAndFamily) << 8 |
325                 (HIWORD(lpNTM->ntmTm.ntmFlags) & 0xff);
326             SendMessageW(hwnd, CB_SETITEMDATA, i, MAKELONG(nFontType,w));
327         }
328     }
329     return 1;
330 }
331 
332 /*************************************************************************
333  *              FontFamilyEnumProc32                           [internal]
334  */
335 static INT WINAPI FontFamilyEnumProc(const ENUMLOGFONTEXW *lpElfex,
336         const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam)
337 {
338     LPCFn_ENUMSTRUCT e;
339     e=(LPCFn_ENUMSTRUCT)lParam;
340     return AddFontFamily( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
341             dwFontType, e->lpcf32w, e->hWnd1, e);
342 }
343 
344 /*************************************************************************
345  *              SetFontStylesToCombo2                           [internal]
346  *
347  * Fill font style information into combobox  (without using font.c directly)
348  */
349 static BOOL SetFontStylesToCombo2(HWND hwnd, HDC hdc, const LOGFONTW *lplf)
350 {
351 #define FSTYLES 4
352     struct FONTSTYLE
353     {
354         int italic;
355         int weight;
356         UINT resId;
357     };
358     static const struct FONTSTYLE fontstyles[FSTYLES]={
359         { 0, FW_NORMAL, IDS_FONT_REGULAR },
360         { 1, FW_NORMAL, IDS_FONT_ITALIC },
361         { 0, FW_BOLD,   IDS_FONT_BOLD },
362         { 1, FW_BOLD,   IDS_FONT_BOLD_ITALIC }
363     };
364     HFONT hf;
365     TEXTMETRICW tm;
366     int i,j;
367     LOGFONTW lf;
368 
369     lf = *lplf;
370 
371     for (i=0;i<FSTYLES;i++)
372     {
373         lf.lfItalic=fontstyles[i].italic;
374         lf.lfWeight=fontstyles[i].weight;
375         hf=CreateFontIndirectW(&lf);
376         hf=SelectObject(hdc,hf);
377         GetTextMetricsW(hdc,&tm);
378         hf=SelectObject(hdc,hf);
379         DeleteObject(hf);
380                 /* font successful created ? */
381         if (((fontstyles[i].weight == FW_NORMAL && tm.tmWeight <= FW_MEDIUM) ||
382              (fontstyles[i].weight == FW_BOLD && tm.tmWeight > FW_MEDIUM)) &&
383             ((tm.tmItalic != 0)==fontstyles[i].italic))
384         {
385             WCHAR name[64];
386             LoadStringW(COMDLG32_hInstance, fontstyles[i].resId, name, 64);
387             j=SendMessageW(hwnd,CB_ADDSTRING,0,(LPARAM)name );
388             if (j==CB_ERR) return TRUE;
389             j=SendMessageW(hwnd, CB_SETITEMDATA, j,
390                            MAKELONG(tm.tmWeight,fontstyles[i].italic));
391             if (j==CB_ERR) return TRUE;
392         }
393     }
394     return FALSE;
395 }
396 
397 /*************************************************************************
398  *              AddFontSizeToCombo3                           [internal]
399  */
400 static BOOL AddFontSizeToCombo3(HWND hwnd, UINT h, const CHOOSEFONTW *lpcf)
401 {
402     int j;
403     WCHAR buffer[20];
404 
405     if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
406             ((lpcf->Flags & CF_LIMITSIZE) && (h >= lpcf->nSizeMin) && (h <= lpcf->nSizeMax)))
407     {
408         sprintfW(buffer, fontsizefmtW, h);
409         j=SendMessageW(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)buffer);
410         if (j==CB_ERR)
411         {
412             j=SendMessageW(hwnd, CB_INSERTSTRING, -1, (LPARAM)buffer);
413             if (j!=CB_ERR) j = SendMessageW(hwnd, CB_SETITEMDATA, j, h);
414             if (j==CB_ERR) return TRUE;
415         }
416     }
417     return FALSE;
418 }
419 
420 /*************************************************************************
421  *              SetFontSizesToCombo3                           [internal]
422  */
423 static BOOL SetFontSizesToCombo3(HWND hwnd, const CHOOSEFONTW *lpcf)
424 {
425     static const BYTE sizes[]={6,7,8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
426     unsigned int i;
427 
428     for (i = 0; i < sizeof(sizes)/sizeof(sizes[0]); i++)
429         if (AddFontSizeToCombo3(hwnd, sizes[i], lpcf)) return TRUE;
430     return FALSE;
431 }
432 
433 /*************************************************************************
434  *              CFn_GetDC                           [internal]
435  */
436 static inline HDC CFn_GetDC(const CHOOSEFONTW *lpcf)
437 {
438     HDC ret = ((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC) ?
439         lpcf->hDC :
440         GetDC(0);
441     if(!ret) ERR("HDC failure!!!\n");
442     return ret;
443 }
444 
445 /*************************************************************************
446  *              GetScreenDPI                           [internal]
447  */
448 static inline int GetScreenDPI(void)
449 {
450     HDC hdc;
451     int result;
452 
453     hdc = GetDC(0);
454     result = GetDeviceCaps(hdc, LOGPIXELSY);
455     ReleaseDC(0, hdc);
456 
457     return result;
458 }
459 
460 /*************************************************************************
461  *              CFn_ReleaseDC                           [internal]
462  */
463 static inline void CFn_ReleaseDC(const CHOOSEFONTW *lpcf, HDC hdc)
464 {
465         if(!((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC))
466             ReleaseDC(0, hdc);
467 }
468 
469 /***********************************************************************
470  *                 AddFontStyle                          [internal]
471  */
472 static INT AddFontStyle( const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM,
473                          UINT nFontType, const CHOOSEFONTW *lpcf, HWND hcmb2, HWND hcmb3, HWND hDlg)
474 {
475     int i;
476     const LOGFONTW *lplf = &(lpElfex->elfLogFont);
477     HWND hcmb5;
478     HDC hdc;
479 
480     TRACE("(nFontType=%d)\n",nFontType);
481     TRACE("  %s h=%d w=%d e=%d o=%d wg=%d i=%d u=%d s=%d"
482             " ch=%d op=%d cp=%d q=%d pf=%xh\n",
483             debugstr_w(lplf->lfFaceName),lplf->lfHeight,lplf->lfWidth,
484             lplf->lfEscapement,lplf->lfOrientation,
485             lplf->lfWeight,lplf->lfItalic,lplf->lfUnderline,
486             lplf->lfStrikeOut,lplf->lfCharSet, lplf->lfOutPrecision,
487             lplf->lfClipPrecision,lplf->lfQuality, lplf->lfPitchAndFamily);
488     if (nFontType & RASTER_FONTTYPE)
489     {
490         INT points;
491         points = MulDiv( lpNTM->ntmTm.tmHeight - lpNTM->ntmTm.tmInternalLeading,
492                 72, GetScreenDPI());
493         if (AddFontSizeToCombo3(hcmb3, points, lpcf))
494             return 0;
495     } else if (SetFontSizesToCombo3(hcmb3, lpcf)) return 0;
496 
497     if (!SendMessageW(hcmb2, CB_GETCOUNT, 0, 0))
498     {
499         BOOL res;
500         if(!(hdc = CFn_GetDC(lpcf))) return 0;
501         res = SetFontStylesToCombo2(hcmb2,hdc,lplf);
502         CFn_ReleaseDC(lpcf, hdc);
503         if (res)
504             return 0;
505     }
506     if (!( hcmb5 = GetDlgItem(hDlg, cmb5))) return 1;
507     i = SendMessageW( hcmb5, CB_FINDSTRINGEXACT, 0,
508                 (LPARAM)lpElfex->elfScript);
509     if( i == CB_ERR) {
510         i = SendMessageW( hcmb5, CB_ADDSTRING, 0,
511                 (LPARAM)lpElfex->elfScript);
512         if( i != CB_ERR)
513             SendMessageW( hcmb5, CB_SETITEMDATA, i, lplf->lfCharSet);
514     }
515     return 1 ;
516 }
517 
518 static void CFn_FitFontSize( HWND hDlg, int points)
519 {
520     int i,n;
521 
522     /* look for fitting font size in combobox3 */
523     n=SendDlgItemMessageW(hDlg, cmb3, CB_GETCOUNT, 0, 0);
524     for (i=0;i<n;i++)
525     {
526         if (points == (int)SendDlgItemMessageW
527                 (hDlg,cmb3, CB_GETITEMDATA,i,0))
528         {
529             SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,i,0);
530             SendMessageW(hDlg, WM_COMMAND,
531                     MAKEWPARAM(cmb3, CBN_SELCHANGE),
532                     (LPARAM)GetDlgItem(hDlg,cmb3));
533             return;
534         }
535     }
536 
537     /* no default matching size, set text manually */
538     SetDlgItemInt(hDlg, cmb3, points, TRUE);
539 }
540 
541 static BOOL CFn_FitFontStyle( HWND hDlg, LONG packedstyle )
542 {
543     LONG id;
544     int i;
545     BOOL ret = FALSE;
546     /* look for fitting font style in combobox2 */
547     for (i=0;i<TEXT_EXTRAS;i++)
548     {
549         id = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
550         if (packedstyle == id)
551         {
552             SendDlgItemMessageW(hDlg, cmb2, CB_SETCURSEL, i, 0);
553             SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
554                     (LPARAM)GetDlgItem(hDlg,cmb2));
555             ret = TRUE;
556             break;
557         }
558     }
559     return ret;
560 }
561 
562 
563 static BOOL CFn_FitCharSet( HWND hDlg, int charset )
564 {
565     int i,n,cs;
566     /* look for fitting char set in combobox5 */
567     n=SendDlgItemMessageW(hDlg, cmb5, CB_GETCOUNT, 0, 0);
568     for (i=0;i<n;i++)
569     {
570         cs =SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
571         if (charset == cs)
572         {
573             SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, i, 0);
574             SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
575                     (LPARAM)GetDlgItem(hDlg,cmb2));
576             return TRUE;
577         }
578     }
579     /* no charset fits: select the first one in the list */
580     SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, 0, 0);
581     SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
582             (LPARAM)GetDlgItem(hDlg,cmb2));
583     return FALSE;
584 }
585 
586 /***********************************************************************
587  *                 FontStyleEnumProc32                     [internal]
588  */
589 static INT WINAPI FontStyleEnumProc( const ENUMLOGFONTEXW *lpElfex,
590         const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam )
591 {
592     LPCFn_ENUMSTRUCT s=(LPCFn_ENUMSTRUCT)lParam;
593     HWND hcmb2=s->hWnd1;
594     HWND hcmb3=s->hWnd2;
595     HWND hDlg=GetParent(hcmb3);
596     return AddFontStyle( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
597                          dwFontType, s->lpcf32w, hcmb2, hcmb3, hDlg);
598 }
599 
600 /***********************************************************************
601  *           CFn_WMInitDialog                            [internal]
602  */
603 static LRESULT CFn_WMInitDialog(HWND hDlg, LPARAM lParam, LPCHOOSEFONTW lpcf)
604 {
605     HDC hdc;
606     int i,j;
607     BOOL init = FALSE;
608     long pstyle;
609     CFn_ENUMSTRUCT s;
610     LPLOGFONTW lpxx;
611     HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
612     static const WCHAR strColorName[] = {'[','c','o','l','o','r',' ','n','a','m','e',']',0};
613 
614     SetPropW(hDlg, strWineFontData, lpcf);
615     lpxx=lpcf->lpLogFont;
616     TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
617 
618     if (lpcf->lStructSize != sizeof(CHOOSEFONTW))
619     {
620         ERR("structure size failure!!!\n");
621         EndDialog (hDlg, 0);
622         return FALSE;
623     }
624     if (!himlTT)
625         himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
626                 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
627 
628     /* Set effect flags */
629     if((lpcf->Flags & CF_EFFECTS) && (lpcf->Flags & CF_INITTOLOGFONTSTRUCT))
630     {
631         if(lpxx->lfUnderline)
632             CheckDlgButton(hDlg, chx2, TRUE);
633         if(lpxx->lfStrikeOut)
634             CheckDlgButton(hDlg, chx1, TRUE);
635     }
636 
637     if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow(lpcf->hwndOwner))
638         ShowWindow(GetDlgItem(hDlg,pshHelp),SW_HIDE);
639     if (!(lpcf->Flags & CF_APPLY))
640         ShowWindow(GetDlgItem(hDlg,psh3),SW_HIDE);
641     if (lpcf->Flags & CF_NOSCRIPTSEL)
642         EnableWindow(GetDlgItem(hDlg,cmb5),FALSE);
643     if (lpcf->Flags & CF_EFFECTS)
644     {
645         for (i=0;i<TEXT_COLORS;i++)
646         {
647             WCHAR name[30];
648 
649             if( LoadStringW(COMDLG32_hInstance, IDS_COLOR_BLACK+i, name,
650                         sizeof(name)/sizeof(*name) )==0 )
651             {
652                 memcpy(name, strColorName, sizeof(strColorName));
653             }
654             j=SendDlgItemMessageW(hDlg, cmb4, CB_ADDSTRING, 0, (LPARAM)name);
655             SendDlgItemMessageW(hDlg, cmb4, CB_SETITEMDATA, j, textcolors[i]);
656             /* look for a fitting value in color combobox */
657             if (textcolors[i]==lpcf->rgbColors)
658                 SendDlgItemMessageW(hDlg,cmb4, CB_SETCURSEL,j,0);
659         }
660     }
661     else
662     {
663         ShowWindow(GetDlgItem(hDlg,cmb4),SW_HIDE);
664         ShowWindow(GetDlgItem(hDlg,chx1),SW_HIDE);
665         ShowWindow(GetDlgItem(hDlg,chx2),SW_HIDE);
666         ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
667         ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
668     }
669     if(!(hdc = CFn_GetDC(lpcf)))
670     {
671         EndDialog (hDlg, 0);
672         return FALSE;
673     }
674     s.hWnd1=GetDlgItem(hDlg,cmb1);
675     s.lpcf32w=lpcf;
676     do {
677         LOGFONTW elf;
678         s.added = 0;
679         elf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
680         elf.lfPitchAndFamily = 0;
681         elf.lfFaceName[0] = '\0'; /* enum all fonts */
682         if (!EnumFontFamiliesExW(hdc, &elf, (FONTENUMPROCW)FontFamilyEnumProc, (LPARAM)&s, 0))
683         {
684             TRACE("EnumFontFamiliesEx returns 0\n");
685             break;
686         }
687         if (s.added) break;
688         if (lpcf->Flags & CF_FIXEDPITCHONLY) {
689             FIXME("No font found with fixed pitch only, dropping flag.\n");
690             lpcf->Flags &= ~CF_FIXEDPITCHONLY;
691             continue;
692         }
693         if (lpcf->Flags & CF_TTONLY) {
694             FIXME("No font found with truetype only, dropping flag.\n");
695             lpcf->Flags &= ~CF_TTONLY;
696             continue;
697         }
698         break;
699     } while (1);
700 
701 
702     if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
703     {
704         /* look for fitting font name in combobox1 */
705         j=SendDlgItemMessageW(hDlg,cmb1,CB_FINDSTRING,-1,(LPARAM)lpxx->lfFaceName);
706         if (j!=CB_ERR)
707         {
708             INT height = lpxx->lfHeight < 0 ? -lpxx->lfHeight :
709                 lpxx->lfHeight;
710             INT points;
711             int charset = lpxx->lfCharSet;
712             points = MulDiv( height, 72, GetScreenDPI());
713             pstyle = MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD:
714                     FW_NORMAL,lpxx->lfItalic !=0);
715             SendDlgItemMessageW(hDlg, cmb1, CB_SETCURSEL, j, 0);
716             SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
717                     (LPARAM)GetDlgItem(hDlg,cmb1));
718             init = TRUE;
719             /* look for fitting font style in combobox2 */
720             CFn_FitFontStyle(hDlg, pstyle);
721             /* look for fitting font size in combobox3 */
722             CFn_FitFontSize(hDlg, points);
723             CFn_FitCharSet( hDlg, charset );
724         }
725     }
726     if (!init)
727     {
728         SendDlgItemMessageW(hDlg,cmb1,CB_SETCURSEL,0,0);
729         SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
730                 (LPARAM)GetDlgItem(hDlg,cmb1));
731         SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,0,0);
732         SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
733                 (LPARAM)GetDlgItem(hDlg,cmb1));
734         SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,0,0);
735         SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb3, CBN_SELCHANGE),
736                 (LPARAM)GetDlgItem(hDlg,cmb3));
737         SendDlgItemMessageW(hDlg,cmb5,CB_SETCURSEL,0,0);
738         SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
739                 (LPARAM)GetDlgItem(hDlg,cmb5));
740     }
741     /* limit text length user can type in as font size */
742     SendDlgItemMessageW(hDlg, cmb3, CB_LIMITTEXT, 5, 0);
743 
744     if ((lpcf->Flags & CF_USESTYLE) && lpcf->lpszStyle)
745     {
746         j=SendDlgItemMessageW(hDlg,cmb2,CB_FINDSTRING,-1,(LPARAM)lpcf->lpszStyle);
747         if (j!=CB_ERR)
748         {
749             j=SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,j,0);
750             SendMessageW(hDlg,WM_COMMAND,cmb2,
751                     MAKELONG(LOWORD(GetDlgItem(hDlg,cmb2)),CBN_SELCHANGE));
752         }
753     }
754     CFn_ReleaseDC(lpcf, hdc);
755     SetCursor(hcursor);
756     return TRUE;
757 }
758 
759 
760 /***********************************************************************
761  *           CFn_WMMeasureItem                           [internal]
762  */
763 static LRESULT CFn_WMMeasureItem(HWND hDlg, LPARAM lParam)
764 {
765     HDC hdc;
766     HFONT hfontprev;
767     TEXTMETRICW tm;
768     LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam;
769     INT height = 0, cx;
770 
771     if (!himlTT)
772         himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
773                 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
774     ImageList_GetIconSize( himlTT, &cx, &height);
775     lpmi->itemHeight = height + 2;
776     /* use MAX of bitmap height and tm.tmHeight .*/
777     hdc=GetDC(hDlg);
778     if(!hdc) return 0;
779     hfontprev = SelectObject( hdc, (HFONT)SendMessageW( hDlg, WM_GETFONT, 0, 0 ));
780     GetTextMetricsW(hdc, &tm);
781     if( tm.tmHeight > lpmi->itemHeight) lpmi->itemHeight = tm.tmHeight;
782     SelectObject(hdc, hfontprev);
783     ReleaseDC(hDlg, hdc);
784     return 0;
785 }
786 
787 
788 /***********************************************************************
789  *           CFn_WMDrawItem                              [internal]
790  */
791 static LRESULT CFn_WMDrawItem(LPARAM lParam)
792 {
793     HBRUSH hBrush;
794     WCHAR buffer[40];
795     COLORREF cr, oldText=0, oldBk=0;
796     RECT rect;
797     int nFontType;
798     int cx, cy, idx;
799     LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam;
800 
801     if (lpdi->itemID == (UINT)-1)  /* got no items */
802         DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
803     else
804     {
805         if (lpdi->CtlType == ODT_COMBOBOX)
806         {
807             if (lpdi->itemState & ODS_SELECTED)
808             {
809                 hBrush=GetSysColorBrush(COLOR_HIGHLIGHT);
810                 oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
811                 oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT));
812             }  else
813             {
814                 hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
815                 SelectObject(lpdi->hDC, hBrush);
816             }
817             FillRect(lpdi->hDC, &lpdi->rcItem, hBrush);
818         }
819         else
820             return TRUE;        /* this should never happen */
821 
822         rect=lpdi->rcItem;
823         switch (lpdi->CtlID)
824         {
825         case cmb1:
826             /* TRACE(commdlg,"WM_Drawitem cmb1\n"); */
827             ImageList_GetIconSize( himlTT, &cx, &cy);
828             SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
829                          (LPARAM)buffer);
830             TextOutW(lpdi->hDC, lpdi->rcItem.left + cx + 4,
831                      lpdi->rcItem.top, buffer, lstrlenW(buffer));
832             nFontType = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
833             idx = -1;
834             if (nFontType & TRUETYPE_FONTTYPE) {
835                 idx = 0;  /* picture: TT */
836                 if( nFontType & NTM_TT_OPENTYPE)
837                     idx = 2; /* picture: O */
838             } else if( nFontType & NTM_PS_OPENTYPE)
839                 idx = 3; /* picture: O+ps */
840             else if( nFontType & NTM_TYPE1)
841                 idx = 4; /* picture: a */
842             else if( nFontType & DEVICE_FONTTYPE)
843                 idx = 1; /* picture: printer */
844             if( idx >= 0)
845                 ImageList_Draw( himlTT, idx, lpdi->hDC, lpdi->rcItem.left,
846                                 (lpdi->rcItem.top + lpdi->rcItem.bottom - cy) / 2, ILD_TRANSPARENT);
847             break;
848         case cmb2:
849         case cmb3:
850             /* TRACE(commdlg,"WM_DRAWITEN cmb2,cmb3\n"); */
851         case cmb5:
852             SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
853                          (LPARAM)buffer);
854             TextOutW(lpdi->hDC, lpdi->rcItem.left,
855                      lpdi->rcItem.top, buffer, lstrlenW(buffer));
856             break;
857 
858         case cmb4:
859             /* TRACE(commdlg,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
860             SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
861                      (LPARAM)buffer);
862             TextOutW(lpdi->hDC, lpdi->rcItem.left +  25+5,
863                      lpdi->rcItem.top, buffer, lstrlenW(buffer));
864             cr = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
865             hBrush = CreateSolidBrush(cr);
866             if (hBrush)
867             {
868                 hBrush = SelectObject (lpdi->hDC, hBrush) ;
869                 rect.right=rect.left+25;
870                 rect.top++;
871                 rect.left+=5;
872                 rect.bottom--;
873                 Rectangle( lpdi->hDC, rect.left, rect.top,
874                            rect.right, rect.bottom );
875                 DeleteObject( SelectObject (lpdi->hDC, hBrush)) ;
876             }
877             rect=lpdi->rcItem;
878             rect.left+=25+5;
879             break;
880 
881         default:
882             return TRUE;  /* this should never happen */
883         }
884         if (lpdi->itemState & ODS_SELECTED)
885         {
886             SetTextColor(lpdi->hDC, oldText);
887             SetBkColor(lpdi->hDC, oldBk);
888         }
889     }
890     return TRUE;
891 }
892 
893 static INT get_dialog_font_point_size(HWND hDlg, CHOOSEFONTW *cf)
894 {
895     BOOL invalid_size = FALSE;
896     INT i, size;
897 
898     i = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
899     if (i != CB_ERR)
900         size = LOWORD(SendDlgItemMessageW(hDlg, cmb3, CB_GETITEMDATA , i, 0));
901     else
902     {
903         WCHAR buffW[8], *endptrW;
904 
905         GetDlgItemTextW(hDlg, cmb3, buffW, sizeof(buffW)/sizeof(*buffW));
906         size = strtolW(buffW, &endptrW, 10);
907         invalid_size = size == 0 && *endptrW;
908 
909         if (size == 0)
910             size = 10;
911     }
912 
913     cf->iPointSize = 10 * size;
914     cf->lpLogFont->lfHeight = -MulDiv(cf->iPointSize, GetScreenDPI(), 720);
915     return invalid_size ? -1 : size;
916 }
917 
918 /***********************************************************************
919  *           CFn_WMCommand                               [internal]
920  */
921 static LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcf)
922 {
923     int i;
924     long l;
925     HDC hdc;
926     BOOL cmb_selected_by_edit = FALSE;
927 
928     if (!lpcf) return FALSE;
929 
930     if(HIWORD(wParam) == CBN_EDITCHANGE)
931     {
932         int idx;
933         WCHAR str_edit[256], str_cmb[256];
934         int cmb = LOWORD(wParam);
935 
936         GetDlgItemTextW(hDlg, cmb, str_edit, sizeof(str_edit) / sizeof(str_edit[0]));
937         idx = SendDlgItemMessageW(hDlg, cmb, CB_FINDSTRING, -1, (LPARAM)str_edit);
938         if(idx != -1)
939         {
940             SendDlgItemMessageW(hDlg, cmb, CB_GETLBTEXT, idx, (LPARAM)str_cmb);
941 
942             /* Select listbox entry only if we have an exact match */
943             if(lstrcmpiW(str_edit, str_cmb) == 0)
944             {
945                  SendDlgItemMessageW(hDlg, cmb, CB_SETCURSEL, idx, 0);
946                  SendDlgItemMessageW(hDlg, cmb, CB_SETEDITSEL, 0, -1); /* Remove edit field selection */
947                  cmb_selected_by_edit = TRUE;
948             }
949         }
950     }
951 
952     TRACE("WM_COMMAND wParam=%08X lParam=%08lX\n", (LONG)wParam, lParam);
953     switch (LOWORD(wParam))
954     {
955     case cmb1:
956         if (HIWORD(wParam) == CBN_SELCHANGE || cmb_selected_by_edit)
957         {
958             INT pointsize; /* save current pointsize */
959             LONG pstyle;  /* save current style */
960             int charset;
961             int idx;
962             if(!(hdc = CFn_GetDC(lpcf)))
963             {
964                 EndDialog (hDlg, 0);
965                 return TRUE;
966             }
967             idx = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
968             pointsize = (int)SendDlgItemMessageW( hDlg, cmb3, CB_GETITEMDATA,
969                     idx, 0);
970             idx = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
971             pstyle = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, idx, 0);
972             idx = SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
973             charset = SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, idx, 0);
974 
975             SendDlgItemMessageW(hDlg, cmb2, CB_RESETCONTENT, 0, 0);
976             SendDlgItemMessageW(hDlg, cmb3, CB_RESETCONTENT, 0, 0);
977             SendDlgItemMessageW(hDlg, cmb5, CB_RESETCONTENT, 0, 0);
978             i=SendDlgItemMessageW(hDlg, cmb1, CB_GETCURSEL, 0, 0);
979             if (i!=CB_ERR)
980             {
981                 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
982                 CFn_ENUMSTRUCT s;
983                 LOGFONTW enumlf;
984                 SendDlgItemMessageW(hDlg, cmb1, CB_GETLBTEXT, i,
985                                     (LPARAM)enumlf.lfFaceName);
986                 TRACE("WM_COMMAND/cmb1 =>%s\n", debugstr_w(enumlf.lfFaceName));
987                 s.hWnd1=GetDlgItem(hDlg, cmb2);
988                 s.hWnd2=GetDlgItem(hDlg, cmb3);
989                 s.lpcf32w=lpcf;
990                 enumlf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
991                 enumlf.lfPitchAndFamily = 0;
992                 EnumFontFamiliesExW(hdc, &enumlf,
993                         (FONTENUMPROCW)FontStyleEnumProc, (LPARAM)&s, 0);
994                 CFn_FitFontStyle(hDlg, pstyle);
995                 if( pointsize != CB_ERR) CFn_FitFontSize(hDlg, pointsize);
996                 if( charset != CB_ERR) CFn_FitCharSet( hDlg, charset );
997                 SetCursor(hcursor);
998             }
999             CFn_ReleaseDC(lpcf, hdc);
1000         }
1001         break;
1002     case chx1:
1003     case chx2:
1004     case cmb2:
1005     case cmb3:
1006     case cmb5:
1007         if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == BN_CLICKED || cmb_selected_by_edit)
1008         {
1009             WCHAR str[256];
1010             WINDOWINFO wininfo;
1011             LPLOGFONTW lpxx=lpcf->lpLogFont;
1012 
1013             TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
1014 
1015             /* face name */
1016             i=SendDlgItemMessageW(hDlg,cmb1,CB_GETCURSEL,0,0);
1017             if (i==CB_ERR)
1018                 GetDlgItemTextW( hDlg, cmb1, str, sizeof(str)/sizeof(str[0]) );
1019             else
1020             {
1021                 SendDlgItemMessageW(hDlg,cmb1,CB_GETLBTEXT,i,
1022                                     (LPARAM)str);
1023                 l=SendDlgItemMessageW(hDlg,cmb1,CB_GETITEMDATA,i,0);
1024                 lpcf->nFontType = LOWORD(l);
1025                 /* FIXME:   lpcf->nFontType |= ....  SIMULATED_FONTTYPE and so */
1026                 /* same value reported to the EnumFonts
1027                    call back with the extra FONTTYPE_...  bits added */
1028                 lpxx->lfPitchAndFamily = HIWORD(l) >> 8;
1029             }
1030             lstrcpynW(lpxx->lfFaceName, str, sizeof(lpxx->lfFaceName)/sizeof(lpxx->lfFaceName[0]));
1031 
1032             /* style */
1033             i=SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
1034             if (i!=CB_ERR)
1035             {
1036                 l=SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
1037                 if (0!=(lpxx->lfItalic=HIWORD(l)))
1038                     lpcf->nFontType |= ITALIC_FONTTYPE;
1039                 if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
1040                     lpcf->nFontType |= BOLD_FONTTYPE;
1041             }
1042 
1043             /* size */
1044             get_dialog_font_point_size(hDlg, lpcf);
1045 
1046             /* charset */
1047             i=SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
1048             if (i!=CB_ERR)
1049                 lpxx->lfCharSet=SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
1050             else
1051                 lpxx->lfCharSet = DEFAULT_CHARSET;
1052             lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
1053             lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
1054             lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
1055             lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
1056             lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
1057             lpxx->lfQuality=DEFAULT_QUALITY;
1058 
1059             wininfo.cbSize=sizeof(wininfo);
1060 
1061             if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1062             {
1063                 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1064                 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1065             }
1066         }
1067         break;
1068 
1069     case cmb4:
1070         i=SendDlgItemMessageW(hDlg, cmb4, CB_GETCURSEL, 0, 0);
1071         if (i!=CB_ERR)
1072         {
1073             WINDOWINFO wininfo;
1074 
1075             lpcf->rgbColors = SendDlgItemMessageW(hDlg, cmb4, CB_GETITEMDATA, i, 0);
1076             wininfo.cbSize=sizeof(wininfo);
1077 
1078             if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1079             {
1080                 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1081                 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1082             }
1083         }
1084         break;
1085 
1086     case psh15:
1087         i=RegisterWindowMessageW( HELPMSGSTRINGW );
1088         if (lpcf->hwndOwner)
1089             SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData));
1090         break;
1091 
1092     case IDOK:
1093     {
1094         WCHAR msgW[80];
1095         INT pointsize;
1096 
1097         pointsize = get_dialog_font_point_size(hDlg, lpcf);
1098         if (pointsize == -1)
1099         {
1100             LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE_INPUT, msgW, sizeof(msgW)/sizeof(*msgW));
1101             MessageBoxW(hDlg, msgW, NULL, MB_OK | MB_ICONINFORMATION);
1102             return TRUE;
1103         }
1104 
1105         if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
1106               ( (lpcf->Flags & CF_LIMITSIZE) &&
1107                 (lpcf->iPointSize >= 10 * lpcf->nSizeMin) &&
1108                 (lpcf->iPointSize <= 10 * lpcf->nSizeMax)))
1109             EndDialog(hDlg, TRUE);
1110         else
1111         {
1112             WCHAR format[80];
1113             DWORD_PTR args[2];
1114             LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE, format, sizeof(format)/sizeof(WCHAR));
1115             args[0] = lpcf->nSizeMin;
1116             args[1] = lpcf->nSizeMax;
1117             FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
1118                            format, 0, 0, msgW, sizeof(msgW)/sizeof(*msgW),
1119                            (__ms_va_list*)args);
1120             MessageBoxW(hDlg, msgW, NULL, MB_OK);
1121         }
1122         return(TRUE);
1123     }
1124     case IDCANCEL:
1125         EndDialog(hDlg, FALSE);
1126         return(TRUE);
1127     }
1128     return(FALSE);
1129 }
1130 
1131 static LRESULT CFn_WMDestroy(HWND hwnd, LPCHOOSEFONTW lpcfw)
1132 {
1133     LPCHOOSEFONTA lpcfa;
1134     LPSTR lpszStyle;
1135     LPLOGFONTA lpLogFonta;
1136     int len;
1137 
1138     if (!lpcfw) return FALSE;
1139 
1140     lpcfa = GetPropW(hwnd, strWineFontData_a);
1141     lpLogFonta = lpcfa->lpLogFont;
1142     lpszStyle = lpcfa->lpszStyle;
1143     memcpy(lpcfa, lpcfw, sizeof(CHOOSEFONTA));
1144     lpcfa->lpLogFont = lpLogFonta;
1145     lpcfa->lpszStyle = lpszStyle;
1146     memcpy(lpcfa->lpLogFont, lpcfw->lpLogFont, sizeof(LOGFONTA));
1147     WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName,
1148                         LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0);
1149 
1150     if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) {
1151         len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, 0, 0, 0);
1152         WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0);
1153         HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle);
1154     }
1155 
1156     HeapFree(GetProcessHeap(), 0, lpcfw->lpLogFont);
1157     HeapFree(GetProcessHeap(), 0, lpcfw);
1158     SetPropW(hwnd, strWineFontData, 0);
1159 
1160     return TRUE;
1161 }
1162 
1163 static LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW *lpcf)
1164 {
1165     WINDOWINFO info;
1166 
1167     if (!lpcf) return FALSE;
1168 
1169     info.cbSize=sizeof(info);
1170     if( GetWindowInfo( GetDlgItem( hDlg, stc5), &info ) )
1171     {
1172         PAINTSTRUCT ps;
1173         HDC hdc;
1174         HFONT hOrigFont;
1175         LOGFONTW lf = *(lpcf->lpLogFont);
1176 
1177         MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2);
1178         hdc = BeginPaint( hDlg, &ps );
1179 
1180         TRACE("erase %d, rect=%s\n", ps.fErase, wine_dbgstr_rect(&ps.rcPaint));
1181 
1182         /* Paint frame */
1183         DrawEdge( hdc, &info.rcWindow, EDGE_SUNKEN, BF_RECT|BF_ADJUST );
1184 
1185         /* Draw the sample text itself */
1186         hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
1187         SetTextColor( hdc, lpcf->rgbColors );
1188 
1189         DrawTextW( hdc,
1190                 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]],
1191                 -1, &info.rcWindow, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
1192 
1193         DeleteObject(SelectObject( hdc, hOrigFont ));
1194         EndPaint( hDlg, &ps );
1195     }
1196     return FALSE;
1197 }
1198 
1199 /***********************************************************************
1200  *           FormatCharDlgProcA   [internal]
1201  */
1202 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1203 {
1204     LPCHOOSEFONTW lpcfw;
1205     LPCHOOSEFONTA lpcfa;
1206     INT_PTR res = FALSE;
1207     int len;
1208 
1209     if (uMsg!=WM_INITDIALOG) {
1210         lpcfw = GetPropW(hDlg, strWineFontData);
1211         if (lpcfw && CFn_HookCallChk32(lpcfw))
1212             res=CallWindowProcA((WNDPROC)lpcfw->lpfnHook, hDlg, uMsg, wParam, lParam);
1213         if (res)
1214             return res;
1215     } else {
1216         lpcfa=(LPCHOOSEFONTA)lParam;
1217         SetPropW(hDlg, strWineFontData_a, (HANDLE)lParam);
1218 
1219         lpcfw = HeapAlloc(GetProcessHeap(), 0, sizeof(CHOOSEFONTW));
1220         memcpy(lpcfw, lpcfa, sizeof(CHOOSEFONTA));
1221         lpcfw->lpLogFont = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGFONTW));
1222         memcpy(lpcfw->lpLogFont, lpcfa->lpLogFont, sizeof(LOGFONTA));
1223         MultiByteToWideChar(CP_ACP, 0, lpcfa->lpLogFont->lfFaceName,
1224                             LF_FACESIZE, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE);
1225 
1226         if((lpcfa->Flags & CF_USESTYLE) && lpcfa->lpszStyle)  {
1227             len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, NULL, 0);
1228             lpcfw->lpszStyle = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
1229             MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len);
1230         }
1231 
1232         if (!CFn_WMInitDialog(hDlg, lParam, lpcfw))
1233         {
1234             TRACE("CFn_WMInitDialog returned FALSE\n");
1235             return FALSE;
1236         }
1237         if (CFn_HookCallChk32(lpcfw))
1238             return CallWindowProcA((WNDPROC)lpcfa->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1239     }
1240     switch (uMsg)
1241     {
1242     case WM_MEASUREITEM:
1243         return CFn_WMMeasureItem(hDlg,lParam);
1244     case WM_DRAWITEM:
1245         return CFn_WMDrawItem(lParam);
1246     case WM_COMMAND:
1247         return CFn_WMCommand(hDlg, wParam, lParam, lpcfw);
1248     case WM_DESTROY:
1249         return CFn_WMDestroy(hDlg, lpcfw);
1250     case WM_CHOOSEFONT_GETLOGFONT:
1251     {
1252         LOGFONTA *logfont = (LOGFONTA *)lParam;
1253         TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1254         memcpy( logfont, lpcfw->lpLogFont, FIELD_OFFSET( LOGFONTA, lfFaceName ));
1255         WideCharToMultiByte( CP_ACP, 0, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE,
1256                              logfont->lfFaceName, LF_FACESIZE, NULL, NULL );
1257         break;
1258     }
1259     case WM_PAINT:
1260         return CFn_WMPaint(hDlg, wParam, lParam, lpcfw);
1261     }
1262     return res;
1263 }
1264 
1265 /***********************************************************************
1266  *           FormatCharDlgProcW   [internal]
1267  */
1268 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1269 {
1270     LPCHOOSEFONTW lpcf;
1271     INT_PTR res = FALSE;
1272 
1273     if (uMsg!=WM_INITDIALOG)
1274     {
1275         lpcf= GetPropW(hDlg, strWineFontData);
1276         if (lpcf && CFn_HookCallChk32(lpcf))
1277             res=CallWindowProcW((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam);
1278         if (res)
1279             return res;
1280     }
1281     else
1282     {
1283         lpcf=(LPCHOOSEFONTW)lParam;
1284         if (!CFn_WMInitDialog(hDlg, lParam, lpcf))
1285         {
1286             TRACE("CFn_WMInitDialog returned FALSE\n");
1287             return FALSE;
1288         }
1289         if (CFn_HookCallChk32(lpcf))
1290             return CallWindowProcW((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1291     }
1292     switch (uMsg)
1293     {
1294     case WM_MEASUREITEM:
1295         return CFn_WMMeasureItem(hDlg, lParam);
1296     case WM_DRAWITEM:
1297         return CFn_WMDrawItem(lParam);
1298     case WM_COMMAND:
1299         return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
1300     case WM_DESTROY:
1301         return TRUE;
1302     case WM_CHOOSEFONT_GETLOGFONT:
1303         TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1304         memcpy( (LOGFONTW *)lParam, lpcf->lpLogFont, sizeof(LOGFONTW) );
1305         break;
1306     case WM_PAINT:
1307         return CFn_WMPaint(hDlg, wParam, lParam, lpcf);
1308     }
1309     return res;
1310 }
1311