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