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