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