user32: UpdateWindow doesn't accept a NULL hwnd.
[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(HWND_16(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     case chx1:
959     case chx2:
960     case cmb2:
961     case cmb3:
962     case cmb5:
963         if (HIWORD(wParam)==CBN_SELCHANGE || HIWORD(wParam)== BN_CLICKED )
964         {
965             WCHAR str[256];
966             WINDOWINFO wininfo;
967             LPLOGFONTW lpxx=lpcf->lpLogFont;
968
969             TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
970             i=SendDlgItemMessageW(hDlg,cmb1,CB_GETCURSEL,0,0);
971             if (i==CB_ERR)
972                 i=GetDlgItemTextW( hDlg, cmb1, str, 256 );
973             else
974             {
975                 SendDlgItemMessageW(hDlg,cmb1,CB_GETLBTEXT,i,
976                                     (LPARAM)str);
977                 l=SendDlgItemMessageW(hDlg,cmb1,CB_GETITEMDATA,i,0);
978                 lpcf->nFontType = LOWORD(l);
979                 /* FIXME:   lpcf->nFontType |= ....  SIMULATED_FONTTYPE and so */
980                 /* same value reported to the EnumFonts
981                    call back with the extra FONTTYPE_...  bits added */
982                 lpxx->lfPitchAndFamily = HIWORD(l) >> 8;
983             }
984             lstrcpynW(lpxx->lfFaceName, str, sizeof(lpxx->lfFaceName)/sizeof(lpxx->lfFaceName[0]));
985             i=SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
986             if (i!=CB_ERR)
987             {
988                 l=SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
989                 if (0!=(lpxx->lfItalic=HIWORD(l)))
990                     lpcf->nFontType |= ITALIC_FONTTYPE;
991                 if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
992                     lpcf->nFontType |= BOLD_FONTTYPE;
993             }
994             i=SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
995             if( i != CB_ERR)
996                 lpcf->iPointSize = 10 * LOWORD(SendDlgItemMessageW(hDlg, cmb3,
997                             CB_GETITEMDATA , i, 0));
998             else
999                 lpcf->iPointSize = 100;
1000             lpxx->lfHeight = - MulDiv( lpcf->iPointSize ,
1001                     GetScreenDPI(), 720);
1002             i=SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
1003             if (i!=CB_ERR)
1004                 lpxx->lfCharSet=SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
1005             else
1006                 lpxx->lfCharSet = DEFAULT_CHARSET;
1007             lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
1008             lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
1009             lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
1010             lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
1011             lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
1012             lpxx->lfQuality=DEFAULT_QUALITY;
1013
1014             wininfo.cbSize=sizeof(wininfo);
1015
1016             if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1017             {
1018                 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1019                 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1020             }
1021         }
1022         break;
1023
1024     case cmb4:
1025         i=SendDlgItemMessageW(hDlg, cmb4, CB_GETCURSEL, 0, 0);
1026         if (i!=CB_ERR)
1027         {
1028             WINDOWINFO wininfo;
1029
1030             lpcf->rgbColors = SendDlgItemMessageW(hDlg, cmb4, CB_GETITEMDATA, i, 0);
1031             wininfo.cbSize=sizeof(wininfo);
1032
1033             if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1034             {
1035                 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1036                 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1037             }
1038         }
1039         break;
1040
1041     case psh15:
1042         i=RegisterWindowMessageW( HELPMSGSTRINGW );
1043         if (lpcf->hwndOwner)
1044             SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData));
1045         break;
1046
1047     case IDOK:
1048         if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
1049               ( (lpcf->Flags & CF_LIMITSIZE) &&
1050                 (lpcf->iPointSize >= 10 * lpcf->nSizeMin) &&
1051                 (lpcf->iPointSize <= 10 * lpcf->nSizeMax)))
1052             EndDialog(hDlg, TRUE);
1053         else
1054         {
1055             WCHAR buffer[80];
1056             WCHAR format[80];
1057             LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE, format, sizeof(format)/sizeof(WCHAR));
1058             wsprintfW(buffer, format, lpcf->nSizeMin,lpcf->nSizeMax);
1059             MessageBoxW(hDlg, buffer, NULL, MB_OK);
1060         }
1061         return(TRUE);
1062     case IDCANCEL:
1063         EndDialog(hDlg, FALSE);
1064         return(TRUE);
1065     }
1066     return(FALSE);
1067 }
1068
1069 static LRESULT CFn_WMDestroy(HWND hwnd, LPCHOOSEFONTW lpcfw)
1070 {
1071     LPCHOOSEFONTA lpcfa;
1072     LPSTR lpszStyle;
1073     LPLOGFONTA lpLogFonta;
1074     int len;
1075
1076     if (!lpcfw) return FALSE;
1077
1078     lpcfa = GetPropW(hwnd, strWineFontData_a);
1079     lpLogFonta = lpcfa->lpLogFont;
1080     lpszStyle = lpcfa->lpszStyle;
1081     memcpy(lpcfa, lpcfw, sizeof(CHOOSEFONTA));
1082     lpcfa->lpLogFont = lpLogFonta;
1083     lpcfa->lpszStyle = lpszStyle;
1084     memcpy(lpcfa->lpLogFont, lpcfw->lpLogFont, sizeof(LOGFONTA));
1085     WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName,
1086                         LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0);
1087
1088     if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) {
1089         len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, 0, 0, 0);
1090         WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0);
1091         HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle);
1092     }
1093
1094     HeapFree(GetProcessHeap(), 0, lpcfw->lpLogFont);
1095     HeapFree(GetProcessHeap(), 0, lpcfw);
1096     SetPropW(hwnd, strWineFontData, 0);
1097
1098     return TRUE;
1099 }
1100
1101 static LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW *lpcf)
1102 {
1103     WINDOWINFO info;
1104
1105     if (!lpcf) return FALSE;
1106
1107     info.cbSize=sizeof(info);
1108     if( GetWindowInfo( GetDlgItem( hDlg, stc5), &info ) )
1109     {
1110         PAINTSTRUCT ps;
1111         HDC hdc;
1112         HPEN hOrigPen;
1113         HFONT hOrigFont;
1114         LOGFONTW lf = *(lpcf->lpLogFont);
1115
1116         MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2);
1117         hdc = BeginPaint( hDlg, &ps );
1118
1119         TRACE("erase %d, rect=(%d,%d)-(%d,%d)\n", ps.fErase,
1120               ps.rcPaint.left, ps.rcPaint.top,
1121               ps.rcPaint.right, ps.rcPaint.bottom);
1122
1123         /* Paint frame */
1124         MoveToEx( hdc, info.rcWindow.left, info.rcWindow.bottom, NULL );
1125         hOrigPen=SelectObject( hdc, CreatePen( PS_SOLID, 2,
1126                                                GetSysColor( COLOR_3DSHADOW ) ));
1127         LineTo( hdc, info.rcWindow.left, info.rcWindow.top );
1128         LineTo( hdc, info.rcWindow.right, info.rcWindow.top );
1129         DeleteObject(SelectObject( hdc, CreatePen( PS_SOLID, 2,
1130                                                    GetSysColor( COLOR_3DLIGHT ) )));
1131         LineTo( hdc, info.rcWindow.right, info.rcWindow.bottom );
1132         LineTo( hdc, info.rcWindow.left, info.rcWindow.bottom );
1133         DeleteObject(SelectObject( hdc, hOrigPen ));
1134
1135         /* Draw the sample text itself */
1136         info.rcWindow.right--;
1137         info.rcWindow.bottom--;
1138         info.rcWindow.top++;
1139         info.rcWindow.left++;
1140         hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
1141         SetTextColor( hdc, lpcf->rgbColors );
1142
1143         DrawTextW( hdc,
1144                 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]],
1145                 -1, &info.rcWindow, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
1146
1147         DeleteObject(SelectObject( hdc, hOrigFont ));
1148         EndPaint( hDlg, &ps );
1149     }
1150     return FALSE;
1151 }
1152
1153 /***********************************************************************
1154  *           FormatCharDlgProcA   [internal]
1155  */
1156 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1157 {
1158     LPCHOOSEFONTW lpcfw;
1159     LPCHOOSEFONTA lpcfa;
1160     INT_PTR res = FALSE;
1161     int len;
1162
1163     if (uMsg!=WM_INITDIALOG) {
1164         lpcfw = GetPropW(hDlg, strWineFontData);
1165         if (lpcfw && CFn_HookCallChk32(lpcfw))
1166             res=CallWindowProcA((WNDPROC)lpcfw->lpfnHook, hDlg, uMsg, wParam, lParam);
1167         if (res)
1168             return res;
1169     } else {
1170         lpcfa=(LPCHOOSEFONTA)lParam;
1171         SetPropW(hDlg, strWineFontData_a, (HANDLE)lParam);
1172
1173         lpcfw = HeapAlloc(GetProcessHeap(), 0, sizeof(CHOOSEFONTW));
1174         memcpy(lpcfw, lpcfa, sizeof(CHOOSEFONTA));
1175         lpcfw->lpLogFont = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGFONTW));
1176         memcpy(lpcfw->lpLogFont, lpcfa->lpLogFont, sizeof(LOGFONTA));
1177         MultiByteToWideChar(CP_ACP, 0, lpcfa->lpLogFont->lfFaceName,
1178                             LF_FACESIZE, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE);
1179
1180         if((lpcfa->Flags & CF_USESTYLE) && lpcfa->lpszStyle)  {
1181             len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, NULL, 0);
1182             lpcfw->lpszStyle = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
1183             MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len);
1184         }
1185
1186         if (!CFn_WMInitDialog(hDlg, lParam, lpcfw))
1187         {
1188             TRACE("CFn_WMInitDialog returned FALSE\n");
1189             return FALSE;
1190         }
1191         if (CFn_HookCallChk32(lpcfw))
1192             return CallWindowProcA((WNDPROC)lpcfa->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1193     }
1194     switch (uMsg)
1195     {
1196     case WM_MEASUREITEM:
1197         return CFn_WMMeasureItem(hDlg,lParam);
1198     case WM_DRAWITEM:
1199         return CFn_WMDrawItem(lParam);
1200     case WM_COMMAND:
1201         return CFn_WMCommand(hDlg, wParam, lParam, lpcfw);
1202     case WM_DESTROY:
1203         return CFn_WMDestroy(hDlg, lpcfw);
1204     case WM_CHOOSEFONT_GETLOGFONT:
1205         TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1206         FIXME("current logfont back to caller\n");
1207         break;
1208     case WM_PAINT:
1209         return CFn_WMPaint(hDlg, wParam, lParam, lpcfw);
1210     }
1211     return res;
1212 }
1213
1214 /***********************************************************************
1215  *           FormatCharDlgProcW   [internal]
1216  */
1217 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1218 {
1219     LPCHOOSEFONTW lpcf;
1220     INT_PTR res = FALSE;
1221
1222     if (uMsg!=WM_INITDIALOG)
1223     {
1224         lpcf= GetPropW(hDlg, strWineFontData);
1225         if (lpcf && CFn_HookCallChk32(lpcf))
1226             res=CallWindowProcW((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam);
1227         if (res)
1228             return res;
1229     }
1230     else
1231     {
1232         lpcf=(LPCHOOSEFONTW)lParam;
1233         if (!CFn_WMInitDialog(hDlg, lParam, lpcf))
1234         {
1235             TRACE("CFn_WMInitDialog returned FALSE\n");
1236             return FALSE;
1237         }
1238         if (CFn_HookCallChk32(lpcf))
1239             return CallWindowProcW((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1240     }
1241     switch (uMsg)
1242     {
1243     case WM_MEASUREITEM:
1244         return CFn_WMMeasureItem(hDlg, lParam);
1245     case WM_DRAWITEM:
1246         return CFn_WMDrawItem(lParam);
1247     case WM_COMMAND:
1248         return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
1249     case WM_DESTROY:
1250         return TRUE;
1251     case WM_CHOOSEFONT_GETLOGFONT:
1252         TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1253         FIXME("current logfont back to caller\n");
1254         break;
1255     case WM_PAINT:
1256         return CFn_WMPaint(hDlg, wParam, lParam, lpcf);
1257     }
1258     return res;
1259 }