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