ntdll: Verify the tail contents when validating an in-use block with tail checking...
[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  *              CFn_ReleaseDC                           [internal]
460  */
461 static inline void CFn_ReleaseDC(const CHOOSEFONTW *lpcf, HDC hdc)
462 {
463         if(!((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC))
464             ReleaseDC(0, hdc);
465 }
466
467 /***********************************************************************
468  *                 AddFontStyle                          [internal]
469  */
470 static INT AddFontStyle( const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM,
471                          UINT nFontType, const CHOOSEFONTW *lpcf, HWND hcmb2, HWND hcmb3, HWND hDlg)
472 {
473     int i;
474     const LOGFONTW *lplf = &(lpElfex->elfLogFont);
475     HWND hcmb5;
476     HDC hdc;
477
478     TRACE("(nFontType=%d)\n",nFontType);
479     TRACE("  %s h=%d w=%d e=%d o=%d wg=%d i=%d u=%d s=%d"
480             " ch=%d op=%d cp=%d q=%d pf=%xh\n",
481             debugstr_w(lplf->lfFaceName),lplf->lfHeight,lplf->lfWidth,
482             lplf->lfEscapement,lplf->lfOrientation,
483             lplf->lfWeight,lplf->lfItalic,lplf->lfUnderline,
484             lplf->lfStrikeOut,lplf->lfCharSet, lplf->lfOutPrecision,
485             lplf->lfClipPrecision,lplf->lfQuality, lplf->lfPitchAndFamily);
486     if (nFontType & RASTER_FONTTYPE)
487     {
488         INT points;
489         if(!(hdc = CFn_GetDC(lpcf))) return 0;
490         points = MulDiv( lpNTM->ntmTm.tmHeight - lpNTM->ntmTm.tmInternalLeading,
491                 72, GetDeviceCaps(hdc, LOGPIXELSY));
492         CFn_ReleaseDC(lpcf, hdc);
493         i = AddFontSizeToCombo3(hcmb3, points, lpcf);
494         if(i) return 0;
495     } else if (SetFontSizesToCombo3(hcmb3, lpcf)) return 0;
496
497     if (!SendMessageW(hcmb2, CB_GETCOUNT, 0, 0))
498     {
499         if(!(hdc = CFn_GetDC(lpcf))) return 0;
500         i=SetFontStylesToCombo2(hcmb2,hdc,lplf);
501         CFn_ReleaseDC(lpcf, hdc);
502         if (i)
503             return 0;
504     }
505     if (!( hcmb5 = GetDlgItem(hDlg, cmb5))) return 1;
506     i = SendMessageW( hcmb5, CB_FINDSTRINGEXACT, 0,
507                 (LPARAM)lpElfex->elfScript);
508     if( i == CB_ERR) {
509         i = SendMessageW( hcmb5, CB_ADDSTRING, 0,
510                 (LPARAM)lpElfex->elfScript);
511         if( i != CB_ERR)
512             SendMessageW( hcmb5, CB_SETITEMDATA, i, lplf->lfCharSet);
513     }
514     return 1 ;
515 }
516
517 static INT CFn_FitFontSize( HWND hDlg, int points)
518 {
519     int i,n;
520     int ret = 0;
521     /* look for fitting font size in combobox3 */
522     n=SendDlgItemMessageW(hDlg, cmb3, CB_GETCOUNT, 0, 0);
523     for (i=0;i<n;i++)
524     {
525         if (points == (int)SendDlgItemMessageW
526                 (hDlg,cmb3, CB_GETITEMDATA,i,0))
527         {
528             SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,i,0);
529             SendMessageW(hDlg, WM_COMMAND,
530                     MAKEWPARAM(cmb3, CBN_SELCHANGE),
531                     (LPARAM)GetDlgItem(hDlg,cmb3));
532             ret = 1;
533             break;
534         }
535     }
536     return ret;
537 }
538
539 static INT CFn_FitFontStyle( HWND hDlg, LONG packedstyle )
540 {
541     LONG id;
542     int i, ret = 0;
543     /* look for fitting font style in combobox2 */
544     for (i=0;i<TEXT_EXTRAS;i++)
545     {
546         id = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
547         if (packedstyle == id)
548         {
549             SendDlgItemMessageW(hDlg, cmb2, CB_SETCURSEL, i, 0);
550             SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
551                     (LPARAM)GetDlgItem(hDlg,cmb2));
552             ret = 1;
553             break;
554         }
555     }
556     return ret;
557 }
558
559
560 static INT CFn_FitCharSet( HWND hDlg, int charset )
561 {
562     int i,n,cs;
563     /* look for fitting char set in combobox5 */
564     n=SendDlgItemMessageW(hDlg, cmb5, CB_GETCOUNT, 0, 0);
565     for (i=0;i<n;i++)
566     {
567         cs =SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
568         if (charset == cs)
569         {
570             SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, i, 0);
571             SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
572                     (LPARAM)GetDlgItem(hDlg,cmb2));
573             return 1;
574         }
575     }
576     /* no charset fits: select the first one in the list */
577     SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, 0, 0);
578     SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
579             (LPARAM)GetDlgItem(hDlg,cmb2));
580     return 0;
581 }
582
583 /***********************************************************************
584  *                 FontStyleEnumProc32                     [internal]
585  */
586 static INT WINAPI FontStyleEnumProc( const ENUMLOGFONTEXW *lpElfex,
587         const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam )
588 {
589     LPCFn_ENUMSTRUCT s=(LPCFn_ENUMSTRUCT)lParam;
590     HWND hcmb2=s->hWnd1;
591     HWND hcmb3=s->hWnd2;
592     HWND hDlg=GetParent(hcmb3);
593     return AddFontStyle( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
594                          dwFontType, s->lpcf32w, hcmb2, hcmb3, hDlg);
595 }
596
597 /***********************************************************************
598  *           CFn_WMInitDialog                            [internal]
599  */
600 static LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcf)
601 {
602     HDC hdc;
603     int i,j,init=0;
604     long pstyle;
605     CFn_ENUMSTRUCT s;
606     LPLOGFONTW lpxx;
607     HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
608     static const WCHAR strColorName[] = {'[','c','o','l','o','r',' ','n','a','m','e',']',0};
609
610     SetPropW(hDlg, strWineFontData, lpcf);
611     lpxx=lpcf->lpLogFont;
612     TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
613
614     if (lpcf->lStructSize != sizeof(CHOOSEFONTW))
615     {
616         ERR("structure size failure !!!\n");
617         EndDialog (hDlg, 0);
618         return FALSE;
619     }
620     if (!himlTT)
621         himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
622                 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
623
624     /* Set effect flags */
625     if((lpcf->Flags & CF_EFFECTS) && (lpcf->Flags & CF_INITTOLOGFONTSTRUCT))
626     {
627         if(lpxx->lfUnderline)
628             CheckDlgButton(hDlg, chx2, TRUE);
629         if(lpxx->lfStrikeOut)
630             CheckDlgButton(hDlg, chx1, TRUE);
631     }
632
633     if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow(lpcf->hwndOwner))
634         ShowWindow(GetDlgItem(hDlg,pshHelp),SW_HIDE);
635     if (!(lpcf->Flags & CF_APPLY))
636         ShowWindow(GetDlgItem(hDlg,psh3),SW_HIDE);
637     if (lpcf->Flags & CF_NOSCRIPTSEL)
638         EnableWindow(GetDlgItem(hDlg,cmb5),FALSE);
639     if (lpcf->Flags & CF_EFFECTS)
640     {
641         for (i=0;i<TEXT_COLORS;i++)
642         {
643             WCHAR name[30];
644
645             if( LoadStringW(COMDLG32_hInstance, IDS_COLOR_BLACK+i, name,
646                         sizeof(name)/sizeof(*name) )==0 )
647             {
648                 memcpy(name, strColorName, sizeof(strColorName));
649             }
650             j=SendDlgItemMessageW(hDlg, cmb4, CB_ADDSTRING, 0, (LPARAM)name);
651             SendDlgItemMessageW(hDlg, cmb4, CB_SETITEMDATA, j, textcolors[i]);
652             /* look for a fitting value in color combobox */
653             if (textcolors[i]==lpcf->rgbColors)
654                 SendDlgItemMessageW(hDlg,cmb4, CB_SETCURSEL,j,0);
655         }
656     }
657     else
658     {
659         ShowWindow(GetDlgItem(hDlg,cmb4),SW_HIDE);
660         ShowWindow(GetDlgItem(hDlg,chx1),SW_HIDE);
661         ShowWindow(GetDlgItem(hDlg,chx2),SW_HIDE);
662         ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
663         ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
664     }
665     if(!(hdc = CFn_GetDC(lpcf)))
666     {
667         EndDialog (hDlg, 0);
668         return FALSE;
669     }
670     s.hWnd1=GetDlgItem(hDlg,cmb1);
671     s.lpcf32w=lpcf;
672     do {
673         LOGFONTW elf;
674         s.added = 0;
675         elf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
676         elf.lfPitchAndFamily = 0;
677         elf.lfFaceName[0] = '\0'; /* enum all fonts */
678         if (!EnumFontFamiliesExW(hdc, &elf, (FONTENUMPROCW)FontFamilyEnumProc, (LPARAM)&s, 0))
679         {
680             TRACE("EnumFontFamiliesEx returns 0\n");
681             break;
682         }
683         if (s.added) break;
684         if (lpcf->Flags & CF_FIXEDPITCHONLY) {
685             FIXME("No font found with fixed pitch only, dropping flag.\n");
686             lpcf->Flags &= ~CF_FIXEDPITCHONLY;
687             continue;
688         }
689         if (lpcf->Flags & CF_TTONLY) {
690             FIXME("No font found with truetype only, dropping flag.\n");
691             lpcf->Flags &= ~CF_TTONLY;
692             continue;
693         }
694         break;
695     } while (1);
696
697
698     if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
699     {
700         /* look for fitting font name in combobox1 */
701         j=SendDlgItemMessageW(hDlg,cmb1,CB_FINDSTRING,-1,(LPARAM)lpxx->lfFaceName);
702         if (j!=CB_ERR)
703         {
704             INT height = lpxx->lfHeight < 0 ? -lpxx->lfHeight :
705                 lpxx->lfHeight;
706             INT points;
707             int charset = lpxx->lfCharSet;
708             points = MulDiv( height, 72, GetDeviceCaps(hdc, LOGPIXELSY));
709             pstyle = MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD:
710                     FW_NORMAL,lpxx->lfItalic !=0);
711             SendDlgItemMessageW(hDlg, cmb1, CB_SETCURSEL, j, 0);
712             SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
713                     (LPARAM)GetDlgItem(hDlg,cmb1));
714             init=1;
715             /* look for fitting font style in combobox2 */
716             CFn_FitFontStyle(hDlg, pstyle);
717             /* look for fitting font size in combobox3 */
718             CFn_FitFontSize(hDlg, points);
719             CFn_FitCharSet( hDlg, charset );
720         }
721     }
722     if (!init)
723     {
724         SendDlgItemMessageW(hDlg,cmb1,CB_SETCURSEL,0,0);
725         SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
726                 (LPARAM)GetDlgItem(hDlg,cmb1));
727         SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,0,0);
728         SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
729                 (LPARAM)GetDlgItem(hDlg,cmb1));
730         SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,0,0);
731         SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb3, CBN_SELCHANGE),
732                 (LPARAM)GetDlgItem(hDlg,cmb3));
733         SendDlgItemMessageW(hDlg,cmb5,CB_SETCURSEL,0,0);
734         SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
735                 (LPARAM)GetDlgItem(hDlg,cmb5));
736     }
737     if ((lpcf->Flags & CF_USESTYLE) && lpcf->lpszStyle)
738     {
739         j=SendDlgItemMessageW(hDlg,cmb2,CB_FINDSTRING,-1,(LPARAM)lpcf->lpszStyle);
740         if (j!=CB_ERR)
741         {
742             j=SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,j,0);
743             SendMessageW(hDlg,WM_COMMAND,cmb2,
744                     MAKELONG(HWND_16(GetDlgItem(hDlg,cmb2)),CBN_SELCHANGE));
745         }
746     }
747     CFn_ReleaseDC(lpcf, hdc);
748     SetCursor(hcursor);
749     return TRUE;
750 }
751
752
753 /***********************************************************************
754  *           CFn_WMMeasureItem                           [internal]
755  */
756 static LRESULT CFn_WMMeasureItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
757 {
758     HDC hdc;
759     HFONT hfontprev;
760     TEXTMETRICW tm;
761     LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam;
762     INT height = 0;
763
764     if (!himlTT)
765         himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
766                 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
767     ImageList_GetIconSize( himlTT, 0, &height);
768     lpmi->itemHeight = height + 2;
769     /* use MAX of bitmap height and tm.tmHeight .*/
770     hdc=GetDC(hDlg);
771     if(!hdc) return 0;
772     hfontprev = SelectObject( hdc, GetStockObject( SYSTEM_FONT));
773     GetTextMetricsW(hdc, &tm);
774     if( tm.tmHeight > lpmi->itemHeight) lpmi->itemHeight = tm.tmHeight;
775     SelectObject(hdc, hfontprev);
776     ReleaseDC(hDlg, hdc);
777     return 0;
778 }
779
780
781 /***********************************************************************
782  *           CFn_WMDrawItem                              [internal]
783  */
784 static LRESULT CFn_WMDrawItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
785 {
786     HBRUSH hBrush;
787     WCHAR buffer[40];
788     COLORREF cr, oldText=0, oldBk=0;
789     RECT rect;
790     int nFontType;
791     int idx;
792     LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam;
793
794     if (lpdi->itemID == (UINT)-1)  /* got no items */
795         DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
796     else
797     {
798         if (lpdi->CtlType == ODT_COMBOBOX)
799         {
800             if (lpdi->itemState & ODS_SELECTED)
801             {
802                 hBrush=GetSysColorBrush(COLOR_HIGHLIGHT);
803                 oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
804                 oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT));
805             }  else
806             {
807                 hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
808                 SelectObject(lpdi->hDC, hBrush);
809             }
810             FillRect(lpdi->hDC, &lpdi->rcItem, hBrush);
811         }
812         else
813             return TRUE;        /* this should never happen */
814
815         rect=lpdi->rcItem;
816         switch (lpdi->CtlID)
817         {
818         case cmb1:
819             /* TRACE(commdlg,"WM_Drawitem cmb1\n"); */
820             SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
821                          (LPARAM)buffer);
822             TextOutW(lpdi->hDC, lpdi->rcItem.left + TTBITMAP_XSIZE + 10,
823                      lpdi->rcItem.top, buffer, lstrlenW(buffer));
824             nFontType = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
825             idx = -1;
826             if (nFontType & TRUETYPE_FONTTYPE) {
827                 idx = 0;  /* picture: TT */
828                 if( nFontType & NTM_TT_OPENTYPE)
829                     idx = 2; /* picture: O */
830             } else if( nFontType & NTM_PS_OPENTYPE)
831                 idx = 3; /* picture: O+ps */
832             else if( nFontType & NTM_TYPE1)
833                 idx = 4; /* picture: a */
834             else if( nFontType & DEVICE_FONTTYPE)
835                 idx = 1; /* picture: printer */
836             if( idx >= 0)
837                 ImageList_Draw( himlTT, idx, lpdi->hDC, lpdi->rcItem.left,
838                         lpdi->rcItem.top, ILD_TRANSPARENT);
839             break;
840         case cmb2:
841         case cmb3:
842             /* TRACE(commdlg,"WM_DRAWITEN cmb2,cmb3\n"); */
843         case cmb5:
844             SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
845                          (LPARAM)buffer);
846             TextOutW(lpdi->hDC, lpdi->rcItem.left,
847                      lpdi->rcItem.top, buffer, lstrlenW(buffer));
848             break;
849
850         case cmb4:
851             /* TRACE(commdlg,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
852             SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
853                      (LPARAM)buffer);
854             TextOutW(lpdi->hDC, lpdi->rcItem.left +  25+5,
855                      lpdi->rcItem.top, buffer, lstrlenW(buffer));
856             cr = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
857             hBrush = CreateSolidBrush(cr);
858             if (hBrush)
859             {
860                 hBrush = SelectObject (lpdi->hDC, hBrush) ;
861                 rect.right=rect.left+25;
862                 rect.top++;
863                 rect.left+=5;
864                 rect.bottom--;
865                 Rectangle( lpdi->hDC, rect.left, rect.top,
866                            rect.right, rect.bottom );
867                 DeleteObject( SelectObject (lpdi->hDC, hBrush)) ;
868             }
869             rect=lpdi->rcItem;
870             rect.left+=25+5;
871             break;
872
873         default:
874             return TRUE;  /* this should never happen */
875         }
876         if (lpdi->itemState & ODS_SELECTED)
877         {
878             SetTextColor(lpdi->hDC, oldText);
879             SetBkColor(lpdi->hDC, oldBk);
880         }
881     }
882     return TRUE;
883 }
884
885 /***********************************************************************
886  *           CFn_WMCommand                               [internal]
887  */
888 static LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcf)
889 {
890     int i;
891     long l;
892     HDC hdc;
893     LPLOGFONTW lpxx=lpcf->lpLogFont;
894
895     TRACE("WM_COMMAND wParam=%08X lParam=%08lX\n", (LONG)wParam, lParam);
896     switch (LOWORD(wParam))
897     {
898     case cmb1:
899         if (HIWORD(wParam)==CBN_SELCHANGE)
900         {
901             INT pointsize; /* save current pointsize */
902             LONG pstyle;  /* save current style */
903             int charset;
904             int idx;
905             if(!(hdc = CFn_GetDC(lpcf)))
906             {
907                 EndDialog (hDlg, 0);
908                 return TRUE;
909             }
910             idx = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
911             pointsize = (int)SendDlgItemMessageW( hDlg, cmb3, CB_GETITEMDATA,
912                     idx, 0);
913             idx = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
914             pstyle = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, idx, 0);
915             idx = SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
916             charset = SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, idx, 0);
917
918             SendDlgItemMessageW(hDlg, cmb2, CB_RESETCONTENT, 0, 0);
919             SendDlgItemMessageW(hDlg, cmb3, CB_RESETCONTENT, 0, 0);
920             SendDlgItemMessageW(hDlg, cmb5, CB_RESETCONTENT, 0, 0);
921             i=SendDlgItemMessageW(hDlg, cmb1, CB_GETCURSEL, 0, 0);
922             if (i!=CB_ERR)
923             {
924                 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
925                 CFn_ENUMSTRUCT s;
926                 LOGFONTW enumlf;
927                 SendDlgItemMessageW(hDlg, cmb1, CB_GETLBTEXT, i,
928                                     (LPARAM)enumlf.lfFaceName);
929                 TRACE("WM_COMMAND/cmb1 =>%s\n", debugstr_w(enumlf.lfFaceName));
930                 s.hWnd1=GetDlgItem(hDlg, cmb2);
931                 s.hWnd2=GetDlgItem(hDlg, cmb3);
932                 s.lpcf32w=lpcf;
933                 enumlf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
934                 enumlf.lfPitchAndFamily = 0;
935                 EnumFontFamiliesExW(hdc, &enumlf,
936                         (FONTENUMPROCW)FontStyleEnumProc, (LPARAM)&s, 0);
937                 CFn_FitFontStyle(hDlg, pstyle);
938                 if( pointsize != CB_ERR) CFn_FitFontSize(hDlg, pointsize);
939                 if( charset != CB_ERR) CFn_FitCharSet( hDlg, charset );
940                 SetCursor(hcursor);
941             }
942             CFn_ReleaseDC(lpcf, hdc);
943         }
944     case chx1:
945     case chx2:
946     case cmb2:
947     case cmb3:
948     case cmb5:
949         if (HIWORD(wParam)==CBN_SELCHANGE || HIWORD(wParam)== BN_CLICKED )
950         {
951             WCHAR str[256];
952             WINDOWINFO wininfo;
953
954             TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
955             i=SendDlgItemMessageW(hDlg,cmb1,CB_GETCURSEL,0,0);
956             if (i==CB_ERR)
957                 i=GetDlgItemTextW( hDlg, cmb1, str, 256 );
958             else
959             {
960                 SendDlgItemMessageW(hDlg,cmb1,CB_GETLBTEXT,i,
961                                     (LPARAM)str);
962                 l=SendDlgItemMessageW(hDlg,cmb1,CB_GETITEMDATA,i,0);
963                 lpcf->nFontType = LOWORD(l);
964                 /* FIXME:   lpcf->nFontType |= ....  SIMULATED_FONTTYPE and so */
965                 /* same value reported to the EnumFonts
966                    call back with the extra FONTTYPE_...  bits added */
967                 lpxx->lfPitchAndFamily = HIWORD(l) >> 8;
968             }
969             lstrcpynW(lpxx->lfFaceName, str, sizeof(lpxx->lfFaceName)/sizeof(lpxx->lfFaceName[0]));
970             i=SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
971             if (i!=CB_ERR)
972             {
973                 l=SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
974                 if (0!=(lpxx->lfItalic=HIWORD(l)))
975                     lpcf->nFontType |= ITALIC_FONTTYPE;
976                 if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
977                     lpcf->nFontType |= BOLD_FONTTYPE;
978             }
979             i=SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
980             if( i != CB_ERR)
981                 lpcf->iPointSize = 10 * LOWORD(SendDlgItemMessageW(hDlg, cmb3,
982                             CB_GETITEMDATA , i, 0));
983             else
984                 lpcf->iPointSize = 100;
985             hdc = CFn_GetDC(lpcf);
986             if( hdc)
987             {
988                 lpxx->lfHeight = - MulDiv( lpcf->iPointSize ,
989                         GetDeviceCaps(hdc, LOGPIXELSY), 720);
990                 CFn_ReleaseDC(lpcf, hdc);
991             } else
992                 lpxx->lfHeight = -lpcf->iPointSize / 10;
993             i=SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
994             if (i!=CB_ERR)
995                 lpxx->lfCharSet=SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
996             else
997                 lpxx->lfCharSet = DEFAULT_CHARSET;
998             lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
999             lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
1000             lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
1001             lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
1002             lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
1003             lpxx->lfQuality=DEFAULT_QUALITY;
1004
1005             wininfo.cbSize=sizeof(wininfo);
1006
1007             if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1008             {
1009                 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1010                 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1011             }
1012         }
1013         break;
1014
1015     case cmb4:
1016         i=SendDlgItemMessageW(hDlg, cmb4, CB_GETCURSEL, 0, 0);
1017         if (i!=CB_ERR)
1018         {
1019             WINDOWINFO wininfo;
1020
1021             lpcf->rgbColors = SendDlgItemMessageW(hDlg, cmb4, CB_GETITEMDATA, i, 0);
1022             wininfo.cbSize=sizeof(wininfo);
1023
1024             if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1025             {
1026                 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1027                 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1028             }
1029         }
1030         break;
1031
1032     case psh15:
1033         i=RegisterWindowMessageW( HELPMSGSTRINGW );
1034         if (lpcf->hwndOwner)
1035             SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData));
1036         break;
1037
1038     case IDOK:
1039         if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
1040               ( (lpcf->Flags & CF_LIMITSIZE) &&
1041                 (lpcf->iPointSize >= 10 * lpcf->nSizeMin) &&
1042                 (lpcf->iPointSize <= 10 * lpcf->nSizeMax)))
1043             EndDialog(hDlg, TRUE);
1044         else
1045         {
1046             WCHAR buffer[80];
1047             WCHAR format[80];
1048             LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE, format, sizeof(format)/sizeof(WCHAR));
1049             wsprintfW(buffer, format, lpcf->nSizeMin,lpcf->nSizeMax);
1050             MessageBoxW(hDlg, buffer, NULL, MB_OK);
1051         }
1052         return(TRUE);
1053     case IDCANCEL:
1054         EndDialog(hDlg, FALSE);
1055         return(TRUE);
1056     }
1057     return(FALSE);
1058 }
1059
1060 static LRESULT CFn_WMDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcfw)
1061 {
1062     LPCHOOSEFONTA lpcfa;
1063     LPSTR lpszStyle;
1064     LPLOGFONTA lpLogFonta;
1065     int len;
1066
1067     lpcfa = GetPropW(hwnd, strWineFontData_a);
1068     lpLogFonta = lpcfa->lpLogFont;
1069     lpszStyle = lpcfa->lpszStyle;
1070     memcpy(lpcfa, lpcfw, sizeof(CHOOSEFONTA));
1071     lpcfa->lpLogFont = lpLogFonta;
1072     lpcfa->lpszStyle = lpszStyle;
1073     memcpy(lpcfa->lpLogFont, lpcfw->lpLogFont, sizeof(LOGFONTA));
1074     WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName,
1075                         LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0);
1076
1077     if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) {
1078         len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, 0, 0, 0);
1079         WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0);
1080         HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle);
1081     }
1082
1083     HeapFree(GetProcessHeap(), 0, lpcfw->lpLogFont);
1084     HeapFree(GetProcessHeap(), 0, lpcfw);
1085     SetPropW(hwnd, strWineFontData, 0);
1086
1087     return TRUE;
1088 }
1089
1090 static LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW *lpcf)
1091 {
1092     WINDOWINFO info;
1093
1094     info.cbSize=sizeof(info);
1095     if( GetWindowInfo( GetDlgItem( hDlg, stc5), &info ) )
1096     {
1097         PAINTSTRUCT ps;
1098         HDC hdc;
1099         HPEN hOrigPen;
1100         HFONT hOrigFont;
1101         LOGFONTW lf = *(lpcf->lpLogFont);
1102
1103         MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2);
1104         hdc = BeginPaint( hDlg, &ps );
1105
1106         TRACE("erase %d, rect=(%d,%d)-(%d,%d)\n", ps.fErase,
1107               ps.rcPaint.left, ps.rcPaint.top,
1108               ps.rcPaint.right, ps.rcPaint.bottom);
1109
1110         /* Paint frame */
1111         MoveToEx( hdc, info.rcWindow.left, info.rcWindow.bottom, NULL );
1112         hOrigPen=SelectObject( hdc, CreatePen( PS_SOLID, 2,
1113                                                GetSysColor( COLOR_3DSHADOW ) ));
1114         LineTo( hdc, info.rcWindow.left, info.rcWindow.top );
1115         LineTo( hdc, info.rcWindow.right, info.rcWindow.top );
1116         DeleteObject(SelectObject( hdc, CreatePen( PS_SOLID, 2,
1117                                                    GetSysColor( COLOR_3DLIGHT ) )));
1118         LineTo( hdc, info.rcWindow.right, info.rcWindow.bottom );
1119         LineTo( hdc, info.rcWindow.left, info.rcWindow.bottom );
1120         DeleteObject(SelectObject( hdc, hOrigPen ));
1121
1122         /* Draw the sample text itself */
1123         info.rcWindow.right--;
1124         info.rcWindow.bottom--;
1125         info.rcWindow.top++;
1126         info.rcWindow.left++;
1127         hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
1128         SetTextColor( hdc, lpcf->rgbColors );
1129
1130         DrawTextW( hdc,
1131                 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]],
1132                 -1, &info.rcWindow, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
1133
1134         DeleteObject(SelectObject( hdc, hOrigFont ));
1135         EndPaint( hDlg, &ps );
1136     }
1137     return FALSE;
1138 }
1139
1140 /***********************************************************************
1141  *           FormatCharDlgProcA   [internal]
1142  */
1143 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1144 {
1145     LPCHOOSEFONTW lpcfw;
1146     LPCHOOSEFONTA lpcfa;
1147     INT_PTR res = FALSE;
1148     int len;
1149
1150     if (uMsg!=WM_INITDIALOG) {
1151         lpcfw = GetPropW(hDlg, strWineFontData);
1152         if (!lpcfw)
1153             return FALSE;
1154         if (CFn_HookCallChk32(lpcfw))
1155             res=CallWindowProcA((WNDPROC)lpcfw->lpfnHook, hDlg, uMsg, wParam, lParam);
1156         if (res)
1157             return res;
1158     } else {
1159         lpcfa=(LPCHOOSEFONTA)lParam;
1160         SetPropW(hDlg, strWineFontData_a, (HANDLE)lParam);
1161
1162         lpcfw = HeapAlloc(GetProcessHeap(), 0, sizeof(CHOOSEFONTW));
1163         memcpy(lpcfw, lpcfa, sizeof(CHOOSEFONTA));
1164         lpcfw->lpLogFont = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGFONTW));
1165         memcpy(lpcfw->lpLogFont, lpcfa->lpLogFont, sizeof(LOGFONTA));
1166         MultiByteToWideChar(CP_ACP, 0, lpcfa->lpLogFont->lfFaceName,
1167                             LF_FACESIZE, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE);
1168
1169         if((lpcfa->Flags & CF_USESTYLE) && lpcfa->lpszStyle)  {
1170             len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, NULL, 0);
1171             lpcfw->lpszStyle = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
1172             MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len);
1173         }
1174
1175         if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcfw))
1176         {
1177             TRACE("CFn_WMInitDialog returned FALSE\n");
1178             return FALSE;
1179         }
1180         if (CFn_HookCallChk32(lpcfw))
1181             return CallWindowProcA((WNDPROC)lpcfa->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1182     }
1183     switch (uMsg)
1184     {
1185     case WM_MEASUREITEM:
1186         return CFn_WMMeasureItem(hDlg, wParam, lParam);
1187     case WM_DRAWITEM:
1188         return CFn_WMDrawItem(hDlg, wParam, lParam);
1189     case WM_COMMAND:
1190         return CFn_WMCommand(hDlg, wParam, lParam, lpcfw);
1191     case WM_DESTROY:
1192         return CFn_WMDestroy(hDlg, wParam, lParam, lpcfw);
1193     case WM_CHOOSEFONT_GETLOGFONT:
1194         TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1195         FIXME("current logfont back to caller\n");
1196         break;
1197     case WM_PAINT:
1198         return CFn_WMPaint(hDlg, wParam, lParam, lpcfw);
1199     }
1200     return res;
1201 }
1202
1203 /***********************************************************************
1204  *           FormatCharDlgProcW   [internal]
1205  */
1206 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1207 {
1208     LPCHOOSEFONTW lpcf;
1209     INT_PTR res = FALSE;
1210
1211     if (uMsg!=WM_INITDIALOG)
1212     {
1213         lpcf= GetPropW(hDlg, strWineFontData);
1214         if (!lpcf)
1215             return FALSE;
1216         if (CFn_HookCallChk32(lpcf))
1217             res=CallWindowProcW((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam);
1218         if (res)
1219             return res;
1220     }
1221     else
1222     {
1223         lpcf=(LPCHOOSEFONTW)lParam;
1224         if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcf))
1225         {
1226             TRACE("CFn_WMInitDialog returned FALSE\n");
1227             return FALSE;
1228         }
1229         if (CFn_HookCallChk32(lpcf))
1230             return CallWindowProcW((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1231     }
1232     switch (uMsg)
1233     {
1234     case WM_MEASUREITEM:
1235         return CFn_WMMeasureItem(hDlg, wParam, lParam);
1236     case WM_DRAWITEM:
1237         return CFn_WMDrawItem(hDlg, wParam, lParam);
1238     case WM_COMMAND:
1239         return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
1240     case WM_DESTROY:
1241         return TRUE;
1242     case WM_CHOOSEFONT_GETLOGFONT:
1243         TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1244         FIXME("current logfont back to caller\n");
1245         break;
1246     case WM_PAINT:
1247         return CFn_WMPaint(hDlg, wParam, lParam, lpcf);
1248     }
1249     return res;
1250 }