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