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