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