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