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