ddraw: Use real handles for state blocks.
[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 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  * 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(LPCHOOSEFONTW 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, LPCHOOSEFONTW 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, LPCHOOSEFONTW 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, LPCHOOSEFONTW 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(LPCHOOSEFONTW 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(LPCHOOSEFONTW 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, LPCHOOSEFONTW 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     if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow(lpcf->hwndOwner))
621         ShowWindow(GetDlgItem(hDlg,pshHelp),SW_HIDE);
622     if (!(lpcf->Flags & CF_APPLY))
623         ShowWindow(GetDlgItem(hDlg,psh3),SW_HIDE);
624     if (lpcf->Flags & CF_EFFECTS)
625     {
626         for (i=0;i<TEXT_COLORS;i++)
627         {
628             WCHAR name[30];
629
630             if( LoadStringW(COMDLG32_hInstance, IDS_COLOR_BLACK+i, name,
631                         sizeof(name)/sizeof(*name) )==0 )
632             {
633                 memcpy(name, strColorName, sizeof(strColorName));
634             }
635             j=SendDlgItemMessageW(hDlg, cmb4, CB_ADDSTRING, 0, (LPARAM)name);
636             SendDlgItemMessageW(hDlg, cmb4, CB_SETITEMDATA, j, textcolors[i]);
637             /* look for a fitting value in color combobox */
638             if (textcolors[i]==lpcf->rgbColors)
639                 SendDlgItemMessageW(hDlg,cmb4, CB_SETCURSEL,j,0);
640         }
641     }
642     else
643     {
644         ShowWindow(GetDlgItem(hDlg,cmb4),SW_HIDE);
645         ShowWindow(GetDlgItem(hDlg,chx1),SW_HIDE);
646         ShowWindow(GetDlgItem(hDlg,chx2),SW_HIDE);
647         ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
648         ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
649     }
650     if(!(hdc = CFn_GetDC(lpcf)))
651     {
652         EndDialog (hDlg, 0);
653         return FALSE;
654     }
655     s.hWnd1=GetDlgItem(hDlg,cmb1);
656     s.lpcf32w=lpcf;
657     do {
658         LOGFONTW elf;
659         s.added = 0;
660         elf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
661         elf.lfPitchAndFamily = 0;
662         elf.lfFaceName[0] = '\0'; /* enum all fonts */
663         if (!EnumFontFamiliesExW(hdc, &elf, (FONTENUMPROCW)FontFamilyEnumProc, (LPARAM)&s, 0))
664         {
665             TRACE("EnumFontFamiliesEx returns 0\n");
666             break;
667         }
668         if (s.added) break;
669         if (lpcf->Flags & CF_FIXEDPITCHONLY) {
670             FIXME("No font found with fixed pitch only, dropping flag.\n");
671             lpcf->Flags &= ~CF_FIXEDPITCHONLY;
672             continue;
673         }
674         if (lpcf->Flags & CF_TTONLY) {
675             FIXME("No font found with truetype only, dropping flag.\n");
676             lpcf->Flags &= ~CF_TTONLY;
677             continue;
678         }
679         break;
680     } while (1);
681
682
683     if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
684     {
685         /* look for fitting font name in combobox1 */
686         j=SendDlgItemMessageW(hDlg,cmb1,CB_FINDSTRING,-1,(LPARAM)lpxx->lfFaceName);
687         if (j!=CB_ERR)
688         {
689             INT height = lpxx->lfHeight < 0 ? -lpxx->lfHeight :
690                 lpxx->lfHeight;
691             INT points;
692             int charset = lpxx->lfCharSet;
693             points = MulDiv( height, 72, GetDeviceCaps(hdc, LOGPIXELSY));
694             pstyle = MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD:
695                     FW_NORMAL,lpxx->lfItalic !=0);
696             SendDlgItemMessageW(hDlg, cmb1, CB_SETCURSEL, j, 0);
697             SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
698                     (LPARAM)GetDlgItem(hDlg,cmb1));
699             init=1;
700             /* look for fitting font style in combobox2 */
701             CFn_FitFontStyle(hDlg, pstyle);
702             /* look for fitting font size in combobox3 */
703             CFn_FitFontSize(hDlg, points);
704             CFn_FitCharSet( hDlg, charset );
705         }
706     }
707     if (!init)
708     {
709         SendDlgItemMessageW(hDlg,cmb1,CB_SETCURSEL,0,0);
710         SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
711                 (LPARAM)GetDlgItem(hDlg,cmb1));
712     }
713     if ((lpcf->Flags & CF_USESTYLE) && lpcf->lpszStyle)
714     {
715         j=SendDlgItemMessageW(hDlg,cmb2,CB_FINDSTRING,-1,(LPARAM)lpcf->lpszStyle);
716         if (j!=CB_ERR)
717         {
718             j=SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,j,0);
719             SendMessageW(hDlg,WM_COMMAND,cmb2,
720                     MAKELONG(HWND_16(GetDlgItem(hDlg,cmb2)),CBN_SELCHANGE));
721         }
722     }
723     CFn_ReleaseDC(lpcf, hdc);
724     SetCursor(hcursor);
725     return TRUE;
726 }
727
728
729 /***********************************************************************
730  *           CFn_WMMeasureItem                           [internal]
731  */
732 LRESULT CFn_WMMeasureItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
733 {
734     HDC hdc;
735     HFONT hfontprev;
736     TEXTMETRICW tm;
737     LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam;
738     INT height = 0;
739
740     if (!himlTT)
741         himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
742                 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
743     ImageList_GetIconSize( himlTT, 0, &height);
744     lpmi->itemHeight = height + 2;
745     /* use MAX of bitmap height and tm.tmHeight .*/
746     hdc=GetDC(hDlg);
747     if(!hdc) return 0;
748     hfontprev = SelectObject( hdc, GetStockObject( SYSTEM_FONT));
749     GetTextMetricsW(hdc, &tm);
750     if( tm.tmHeight > lpmi->itemHeight) lpmi->itemHeight = tm.tmHeight;
751     SelectObject(hdc, hfontprev);
752     ReleaseDC(hDlg, hdc);
753     return 0;
754 }
755
756
757 /***********************************************************************
758  *           CFn_WMDrawItem                              [internal]
759  */
760 LRESULT CFn_WMDrawItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
761 {
762     HBRUSH hBrush;
763     WCHAR buffer[40];
764     COLORREF cr, oldText=0, oldBk=0;
765     RECT rect;
766     int nFontType;
767     int idx;
768     LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam;
769
770     if (lpdi->itemID == (UINT)-1)  /* got no items */
771         DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
772     else
773     {
774         if (lpdi->CtlType == ODT_COMBOBOX)
775         {
776             if (lpdi->itemState & ODS_SELECTED)
777             {
778                 hBrush=GetSysColorBrush(COLOR_HIGHLIGHT);
779                 oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
780                 oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT));
781             }  else
782             {
783                 hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
784                 SelectObject(lpdi->hDC, hBrush);
785             }
786             FillRect(lpdi->hDC, &lpdi->rcItem, hBrush);
787         }
788         else
789             return TRUE;        /* this should never happen */
790
791         rect=lpdi->rcItem;
792         switch (lpdi->CtlID)
793         {
794         case cmb1:
795             /* TRACE(commdlg,"WM_Drawitem cmb1\n"); */
796             SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
797                          (LPARAM)buffer);
798             TextOutW(lpdi->hDC, lpdi->rcItem.left + TTBITMAP_XSIZE + 10,
799                      lpdi->rcItem.top, buffer, lstrlenW(buffer));
800             nFontType = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
801             idx = -1;
802             if (nFontType & TRUETYPE_FONTTYPE) {
803                 idx = 0;  /* picture: TT */
804                 if( nFontType & NTM_TT_OPENTYPE)
805                     idx = 2; /* picture: O */
806             } else if( nFontType & NTM_PS_OPENTYPE)
807                 idx = 3; /* picture: O+ps */
808             else if( nFontType & NTM_TYPE1)
809                 idx = 4; /* picture: a */
810             else if( nFontType & DEVICE_FONTTYPE)
811                 idx = 1; /* picture: printer */
812             if( idx >= 0)
813                 ImageList_Draw( himlTT, idx, lpdi->hDC, lpdi->rcItem.left,
814                         lpdi->rcItem.top, ILD_TRANSPARENT);
815             break;
816         case cmb2:
817         case cmb3:
818             /* TRACE(commdlg,"WM_DRAWITEN cmb2,cmb3\n"); */
819         case cmb5:
820             SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
821                          (LPARAM)buffer);
822             TextOutW(lpdi->hDC, lpdi->rcItem.left,
823                      lpdi->rcItem.top, buffer, lstrlenW(buffer));
824             break;
825
826         case cmb4:
827             /* TRACE(commdlg,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
828             SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
829                      (LPARAM)buffer);
830             TextOutW(lpdi->hDC, lpdi->rcItem.left +  25+5,
831                      lpdi->rcItem.top, buffer, lstrlenW(buffer));
832             cr = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
833             hBrush = CreateSolidBrush(cr);
834             if (hBrush)
835             {
836                 hBrush = SelectObject (lpdi->hDC, hBrush) ;
837                 rect.right=rect.left+25;
838                 rect.top++;
839                 rect.left+=5;
840                 rect.bottom--;
841                 Rectangle( lpdi->hDC, rect.left, rect.top,
842                            rect.right, rect.bottom );
843                 DeleteObject( SelectObject (lpdi->hDC, hBrush)) ;
844             }
845             rect=lpdi->rcItem;
846             rect.left+=25+5;
847             break;
848
849         default:
850             return TRUE;  /* this should never happen */
851         }
852         if (lpdi->itemState & ODS_SELECTED)
853         {
854             SetTextColor(lpdi->hDC, oldText);
855             SetBkColor(lpdi->hDC, oldBk);
856         }
857     }
858     return TRUE;
859 }
860
861 /***********************************************************************
862  *           CFn_WMCommand                               [internal]
863  */
864 LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam,
865         LPCHOOSEFONTW lpcf)
866 {
867     int i;
868     long l;
869     HDC hdc;
870     LPLOGFONTW lpxx=lpcf->lpLogFont;
871
872     TRACE("WM_COMMAND wParam=%08X lParam=%08lX\n", (LONG)wParam, lParam);
873     switch (LOWORD(wParam))
874     {
875     case cmb1:
876         if (HIWORD(wParam)==CBN_SELCHANGE)
877         {
878             INT pointsize; /* save current pointsize */
879             LONG pstyle;  /* save current style */
880             int charset;
881             int idx;
882             if(!(hdc = CFn_GetDC(lpcf)))
883             {
884                 EndDialog (hDlg, 0);
885                 return TRUE;
886             }
887             idx = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
888             pointsize = (int)SendDlgItemMessageW( hDlg, cmb3, CB_GETITEMDATA,
889                     idx, 0);
890             idx = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
891             pstyle = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, idx, 0);
892             idx = SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
893             charset = SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, idx, 0);
894
895             SendDlgItemMessageW(hDlg, cmb2, CB_RESETCONTENT, 0, 0);
896             SendDlgItemMessageW(hDlg, cmb3, CB_RESETCONTENT, 0, 0);
897             SendDlgItemMessageW(hDlg, cmb5, CB_RESETCONTENT, 0, 0);
898             i=SendDlgItemMessageW(hDlg, cmb1, CB_GETCURSEL, 0, 0);
899             if (i!=CB_ERR)
900             {
901                 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
902                 CFn_ENUMSTRUCT s;
903                 LOGFONTW enumlf;
904                 SendDlgItemMessageW(hDlg, cmb1, CB_GETLBTEXT, i,
905                                     (LPARAM)enumlf.lfFaceName);
906                 TRACE("WM_COMMAND/cmb1 =>%s\n", debugstr_w(enumlf.lfFaceName));
907                 s.hWnd1=GetDlgItem(hDlg, cmb2);
908                 s.hWnd2=GetDlgItem(hDlg, cmb3);
909                 s.lpcf32w=lpcf;
910                 enumlf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
911                 enumlf.lfPitchAndFamily = 0;
912                 EnumFontFamiliesExW(hdc, &enumlf,
913                         (FONTENUMPROCW)FontStyleEnumProc, (LPARAM)&s, 0);
914                 CFn_FitFontStyle(hDlg, pstyle);
915                 if( pointsize != CB_ERR) CFn_FitFontSize(hDlg, pointsize);
916                 if( charset != CB_ERR) CFn_FitCharSet( hDlg, charset );
917                 SetCursor(hcursor);
918             }
919             CFn_ReleaseDC(lpcf, hdc);
920         }
921     case chx1:
922     case chx2:
923     case cmb2:
924     case cmb3:
925     case cmb5:
926         if (HIWORD(wParam)==CBN_SELCHANGE || HIWORD(wParam)== BN_CLICKED )
927         {
928             WCHAR str[256];
929             WINDOWINFO wininfo;
930
931             TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
932             i=SendDlgItemMessageW(hDlg,cmb1,CB_GETCURSEL,0,0);
933             if (i==CB_ERR)
934                 i=GetDlgItemTextW( hDlg, cmb1, str, 256 );
935             else
936             {
937                 SendDlgItemMessageW(hDlg,cmb1,CB_GETLBTEXT,i,
938                                     (LPARAM)str);
939                 l=SendDlgItemMessageW(hDlg,cmb1,CB_GETITEMDATA,i,0);
940                 lpcf->nFontType = LOWORD(l);
941                 /* FIXME:   lpcf->nFontType |= ....  SIMULATED_FONTTYPE and so */
942                 /* same value reported to the EnumFonts
943                    call back with the extra FONTTYPE_...  bits added */
944                 lpxx->lfPitchAndFamily = HIWORD(l) >> 8;
945             }
946             lstrcpyW(lpxx->lfFaceName,str);
947             i=SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
948             if (i!=CB_ERR)
949             {
950                 l=SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
951                 if (0!=(lpxx->lfItalic=HIWORD(l)))
952                     lpcf->nFontType |= ITALIC_FONTTYPE;
953                 if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
954                     lpcf->nFontType |= BOLD_FONTTYPE;
955             }
956             i=SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
957             if( i != CB_ERR)
958                 lpcf->iPointSize = 10 * LOWORD(SendDlgItemMessageW(hDlg, cmb3,
959                             CB_GETITEMDATA , i, 0));
960             else
961                 lpcf->iPointSize = 100;
962             hdc = CFn_GetDC(lpcf);
963             if( hdc)
964             {
965                 lpxx->lfHeight = - MulDiv( lpcf->iPointSize ,
966                         GetDeviceCaps(hdc, LOGPIXELSY), 720);
967                 CFn_ReleaseDC(lpcf, hdc);
968             } else
969                 lpxx->lfHeight = -lpcf->iPointSize / 10;
970             i=SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
971             if (i!=CB_ERR)
972                 lpxx->lfCharSet=SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
973             else
974                 lpxx->lfCharSet = DEFAULT_CHARSET;
975             lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
976             lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
977             lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
978             lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
979             lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
980             lpxx->lfQuality=DEFAULT_QUALITY;
981
982             wininfo.cbSize=sizeof(wininfo);
983
984             if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
985             {
986                 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
987                 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
988             }
989         }
990         break;
991
992     case cmb4:
993         i=SendDlgItemMessageW(hDlg, cmb4, CB_GETCURSEL, 0, 0);
994         if (i!=CB_ERR)
995         {
996             WINDOWINFO wininfo;
997
998             lpcf->rgbColors = SendDlgItemMessageW(hDlg, cmb4, CB_GETITEMDATA, i, 0);
999             wininfo.cbSize=sizeof(wininfo);
1000
1001             if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1002             {
1003                 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1004                 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1005             }
1006         }
1007         break;
1008
1009     case psh15:
1010         i=RegisterWindowMessageW( HELPMSGSTRINGW );
1011         if (lpcf->hwndOwner)
1012             SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData));
1013         /* if (CFn_HookCallChk(lpcf))
1014            CallWindowProc16(lpcf->lpfnHook,hDlg,WM_COMMAND,psh15,(LPARAM)lpcf);*/
1015         break;
1016
1017     case IDOK:
1018         if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
1019               ( (lpcf->Flags & CF_LIMITSIZE) &&
1020                 (lpcf->iPointSize >= 10 * lpcf->nSizeMin) &&
1021                 (lpcf->iPointSize <= 10 * lpcf->nSizeMax)))
1022             EndDialog(hDlg, TRUE);
1023         else
1024         {
1025             WCHAR buffer[80];
1026             WCHAR format[80];
1027             LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE, format, sizeof(format)/sizeof(WCHAR));
1028             wsprintfW(buffer, format, lpcf->nSizeMin,lpcf->nSizeMax);
1029             MessageBoxW(hDlg, buffer, NULL, MB_OK);
1030         }
1031         return(TRUE);
1032     case IDCANCEL:
1033         EndDialog(hDlg, FALSE);
1034         return(TRUE);
1035     }
1036     return(FALSE);
1037 }
1038
1039 static LRESULT CFn_WMDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcfw)
1040 {
1041     LPCHOOSEFONTA lpcfa;
1042     LPSTR lpszStyle;
1043     LPLOGFONTA lpLogFonta;
1044     int len;
1045
1046     lpcfa = GetPropW(hwnd, strWineFontData_a);
1047     lpLogFonta = lpcfa->lpLogFont;
1048     lpszStyle = lpcfa->lpszStyle;
1049     memcpy(lpcfa, lpcfw, sizeof(CHOOSEFONTA));
1050     lpcfa->lpLogFont = lpLogFonta;
1051     lpcfa->lpszStyle = lpszStyle;
1052     memcpy(lpcfa->lpLogFont, lpcfw->lpLogFont, sizeof(LOGFONTA));
1053     WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName,
1054                         LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0);
1055
1056     if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) {
1057         len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, -1, 0, 0);
1058         WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0);
1059         HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle);
1060     }
1061
1062     HeapFree(GetProcessHeap(), 0, lpcfw->lpLogFont);
1063     HeapFree(GetProcessHeap(), 0, lpcfw);
1064     SetPropW(hwnd, strWineFontData, 0);
1065
1066     return TRUE;
1067 }
1068
1069 LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcf)
1070 {
1071     WINDOWINFO info;
1072
1073     info.cbSize=sizeof(info);
1074     if( GetWindowInfo( GetDlgItem( hDlg, stc5), &info ) )
1075     {
1076         PAINTSTRUCT ps;
1077         HDC hdc;
1078         HPEN hOrigPen;
1079         HFONT hOrigFont;
1080         LOGFONTW lf = *(lpcf->lpLogFont);
1081
1082         MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2);
1083         hdc = BeginPaint( hDlg, &ps );
1084
1085         TRACE("erase %d, rect=(%d,%d)-(%d,%d)\n", ps.fErase,
1086               ps.rcPaint.left, ps.rcPaint.top,
1087               ps.rcPaint.right, ps.rcPaint.bottom);
1088
1089         /* Paint frame */
1090         MoveToEx( hdc, info.rcWindow.left, info.rcWindow.bottom, NULL );
1091         hOrigPen=SelectObject( hdc, CreatePen( PS_SOLID, 2,
1092                                                GetSysColor( COLOR_3DSHADOW ) ));
1093         LineTo( hdc, info.rcWindow.left, info.rcWindow.top );
1094         LineTo( hdc, info.rcWindow.right, info.rcWindow.top );
1095         DeleteObject(SelectObject( hdc, CreatePen( PS_SOLID, 2,
1096                                                    GetSysColor( COLOR_3DLIGHT ) )));
1097         LineTo( hdc, info.rcWindow.right, info.rcWindow.bottom );
1098         LineTo( hdc, info.rcWindow.left, info.rcWindow.bottom );
1099         DeleteObject(SelectObject( hdc, hOrigPen ));
1100
1101         /* Draw the sample text itself */
1102         info.rcWindow.right--;
1103         info.rcWindow.bottom--;
1104         info.rcWindow.top++;
1105         info.rcWindow.left++;
1106         hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
1107         SetTextColor( hdc, lpcf->rgbColors );
1108
1109         DrawTextW( hdc,
1110                 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]],
1111                 -1, &info.rcWindow, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
1112
1113         DeleteObject(SelectObject( hdc, hOrigFont ));
1114         EndPaint( hDlg, &ps );
1115     }
1116     return FALSE;
1117 }
1118
1119 /***********************************************************************
1120  *           FormatCharDlgProcA   [internal]
1121  */
1122 INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
1123         LPARAM lParam)
1124 {
1125     LPCHOOSEFONTW lpcfw;
1126     LPCHOOSEFONTA lpcfa;
1127     INT_PTR res = FALSE;
1128     int len;
1129
1130     if (uMsg!=WM_INITDIALOG) {
1131         lpcfw = (LPCHOOSEFONTW)GetPropW(hDlg, strWineFontData);
1132         if (!lpcfw)
1133             return FALSE;
1134         if (CFn_HookCallChk32(lpcfw))
1135             res=CallWindowProcA((WNDPROC)lpcfw->lpfnHook, hDlg, uMsg, wParam, lParam);
1136         if (res)
1137             return res;
1138     } else {
1139         lpcfa=(LPCHOOSEFONTA)lParam;
1140         SetPropW(hDlg, strWineFontData_a, (HANDLE)lParam);
1141
1142         lpcfw = HeapAlloc(GetProcessHeap(), 0, sizeof(CHOOSEFONTW));
1143         memcpy(lpcfw, lpcfa, sizeof(CHOOSEFONTA));
1144         lpcfw->lpLogFont = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGFONTW));
1145         memcpy(lpcfw->lpLogFont, lpcfa->lpLogFont, sizeof(LOGFONTA));
1146         MultiByteToWideChar(CP_ACP, 0, lpcfa->lpLogFont->lfFaceName,
1147                             LF_FACESIZE, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE);
1148
1149         if((lpcfa->Flags & CF_USESTYLE) && lpcfa->lpszStyle)  {
1150             len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, NULL, 0);
1151             lpcfw->lpszStyle = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
1152             MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len);
1153         }
1154
1155         if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcfw))
1156         {
1157             TRACE("CFn_WMInitDialog returned FALSE\n");
1158             return FALSE;
1159         }
1160         if (CFn_HookCallChk32(lpcfw))
1161             return CallWindowProcA((WNDPROC)lpcfa->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1162     }
1163     switch (uMsg)
1164     {
1165     case WM_MEASUREITEM:
1166         return CFn_WMMeasureItem(hDlg, wParam, lParam);
1167     case WM_DRAWITEM:
1168         return CFn_WMDrawItem(hDlg, wParam, lParam);
1169     case WM_COMMAND:
1170         return CFn_WMCommand(hDlg, wParam, lParam, lpcfw);
1171     case WM_DESTROY:
1172         return CFn_WMDestroy(hDlg, wParam, lParam, lpcfw);
1173     case WM_CHOOSEFONT_GETLOGFONT:
1174         TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1175         FIXME("current logfont back to caller\n");
1176         break;
1177     case WM_PAINT:
1178         return CFn_WMPaint(hDlg, wParam, lParam, lpcfw);
1179     }
1180     return res;
1181 }
1182
1183 /***********************************************************************
1184  *           FormatCharDlgProcW   [internal]
1185  */
1186 INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam,
1187         LPARAM lParam)
1188 {
1189     LPCHOOSEFONTW lpcf;
1190     INT_PTR res = FALSE;
1191
1192     if (uMsg!=WM_INITDIALOG)
1193     {
1194         lpcf=(LPCHOOSEFONTW)GetPropW(hDlg, strWineFontData);
1195         if (!lpcf)
1196             return FALSE;
1197         if (CFn_HookCallChk32(lpcf))
1198             res=CallWindowProcW((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam);
1199         if (res)
1200             return res;
1201     }
1202     else
1203     {
1204         lpcf=(LPCHOOSEFONTW)lParam;
1205         if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcf))
1206         {
1207             TRACE("CFn_WMInitDialog returned FALSE\n");
1208             return FALSE;
1209         }
1210         if (CFn_HookCallChk32(lpcf))
1211             return CallWindowProcW((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1212     }
1213     switch (uMsg)
1214     {
1215     case WM_MEASUREITEM:
1216         return CFn_WMMeasureItem(hDlg, wParam, lParam);
1217     case WM_DRAWITEM:
1218         return CFn_WMDrawItem(hDlg, wParam, lParam);
1219     case WM_COMMAND:
1220         return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
1221     case WM_DESTROY:
1222         return TRUE;
1223     case WM_CHOOSEFONT_GETLOGFONT:
1224         TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1225         FIXME("current logfont back to caller\n");
1226         break;
1227     case WM_PAINT:
1228         return CFn_WMPaint(hDlg, wParam, lParam, lpcf);
1229     }
1230     return res;
1231 }