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