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