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