msvcrt: Remove bogus code.
[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  * 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, (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 (tm.tmWeight==fontstyles[i].weight &&
390             ((tm.tmItalic != 0)==fontstyles[i].italic))
391         {
392             j=SendMessageW(hwnd,CB_ADDSTRING,0,(LPARAM)fontstyles[i].stname );
393             if (j==CB_ERR) return 1;
394             j=SendMessageW(hwnd, CB_SETITEMDATA, j,
395                            MAKELONG(fontstyles[i].weight,fontstyles[i].italic));
396             if (j==CB_ERR) return 1;
397         }
398     }
399     return 0;
400 }
401
402 /*************************************************************************
403  *              AddFontSizeToCombo3                           [internal]
404  */
405 static int AddFontSizeToCombo3(HWND hwnd, UINT h, LPCHOOSEFONTW lpcf)
406 {
407     int j;
408     WCHAR buffer[20];
409     static const WCHAR strFormat[] = {'%','2','d',0};
410
411     if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
412             ((lpcf->Flags & CF_LIMITSIZE) && (h >= lpcf->nSizeMin) && (h <= lpcf->nSizeMax)))
413     {
414         wsprintfW(buffer, strFormat, h);
415         j=SendMessageW(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)buffer);
416         if (j==CB_ERR)
417         {
418             j=SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)buffer);
419             if (j!=CB_ERR) j = SendMessageW(hwnd, CB_SETITEMDATA, j, h);
420             if (j==CB_ERR) return 1;
421         }
422     }
423     return 0;
424 }
425
426 /*************************************************************************
427  *              SetFontSizesToCombo3                           [internal]
428  */
429 static int SetFontSizesToCombo3(HWND hwnd, LPCHOOSEFONTW lpcf)
430 {
431     static const BYTE sizes[]={6,7,8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
432     int i;
433
434     for (i = 0; i < sizeof(sizes)/sizeof(sizes[0]); i++)
435         if (AddFontSizeToCombo3(hwnd, sizes[i], lpcf)) return 1;
436     return 0;
437 }
438
439 /*************************************************************************
440  *              CFn_GetDC                           [internal]
441  */
442 static inline HDC CFn_GetDC(LPCHOOSEFONTW lpcf)
443 {
444     HDC ret = ((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC) ?
445         lpcf->hDC :
446         GetDC(0);
447     if(!ret) ERR("HDC failure!!!\n");
448     return ret;
449 }
450
451 /*************************************************************************
452  *              CFn_ReleaseDC                           [internal]
453  */
454 static inline void CFn_ReleaseDC(LPCHOOSEFONTW lpcf, HDC hdc)
455 {
456         if(!((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC))
457             ReleaseDC(0, hdc);
458 }
459
460 /***********************************************************************
461  *                 AddFontStyle                          [internal]
462  */
463 INT AddFontStyle( const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM,
464                 UINT nFontType, LPCHOOSEFONTW lpcf, HWND hcmb2, HWND hcmb3,
465                 HWND hDlg, BOOL iswin16)
466 {
467     int i;
468     const LOGFONTW *lplf = &(lpElfex->elfLogFont);
469     HWND hcmb5;
470     HDC hdc;
471
472     TRACE("(nFontType=%d)\n",nFontType);
473     TRACE("  %s h=%ld w=%ld e=%ld o=%ld wg=%ld i=%d u=%d s=%d"
474             " ch=%d op=%d cp=%d q=%d pf=%xh\n",
475             debugstr_w(lplf->lfFaceName),lplf->lfHeight,lplf->lfWidth,
476             lplf->lfEscapement,lplf->lfOrientation,
477             lplf->lfWeight,lplf->lfItalic,lplf->lfUnderline,
478             lplf->lfStrikeOut,lplf->lfCharSet, lplf->lfOutPrecision,
479             lplf->lfClipPrecision,lplf->lfQuality, lplf->lfPitchAndFamily);
480     if (nFontType & RASTER_FONTTYPE)
481     {
482         INT points;
483         if(!(hdc = CFn_GetDC(lpcf))) return 0;
484         points = MulDiv( lpNTM->ntmTm.tmHeight - lpNTM->ntmTm.tmInternalLeading,
485                 72, GetDeviceCaps(hdc, LOGPIXELSY));
486         CFn_ReleaseDC(lpcf, hdc);
487         i = AddFontSizeToCombo3(hcmb3, points, lpcf);
488         if(i) return 0;
489     } else if (SetFontSizesToCombo3(hcmb3, lpcf)) return 0;
490
491     if (!SendMessageW(hcmb2, CB_GETCOUNT, 0, 0))
492     {
493         if(!(hdc = CFn_GetDC(lpcf))) return 0;
494         i=SetFontStylesToCombo2(hcmb2,hdc,lplf);
495         CFn_ReleaseDC(lpcf, hdc);
496         if (i)
497             return 0;
498     }
499     if( iswin16 || !( hcmb5 = GetDlgItem(hDlg, cmb5))) return 1;
500     i = SendMessageW( hcmb5, CB_FINDSTRINGEXACT, 0,
501                 (LPARAM)lpElfex->elfScript);
502     if( i == CB_ERR) {
503         i = SendMessageW( hcmb5, CB_ADDSTRING, 0,
504                 (LPARAM)lpElfex->elfScript);
505         if( i != CB_ERR)
506             SendMessageW( hcmb5, CB_SETITEMDATA, i, lplf->lfCharSet);
507     }
508     return 1 ;
509 }
510
511 static INT CFn_FitFontSize( HWND hDlg, int points)
512 {
513     int i,n;
514     int ret = 0;
515     /* look for fitting font size in combobox3 */
516     n=SendDlgItemMessageW(hDlg, cmb3, CB_GETCOUNT, 0, 0);
517     for (i=0;i<n;i++)
518     {
519         if (points == (int)SendDlgItemMessageW
520                 (hDlg,cmb3, CB_GETITEMDATA,i,0))
521         {
522             SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,i,0);
523             SendMessageW(hDlg, WM_COMMAND,
524                     MAKEWPARAM(cmb3, CBN_SELCHANGE),
525                     (LPARAM)GetDlgItem(hDlg,cmb3));
526             ret = 1;
527             break;
528         }
529     }
530     return ret;
531 }
532
533 static INT CFn_FitFontStyle( HWND hDlg, LONG packedstyle )
534 {
535     LONG id;
536     int i, ret = 0;
537     /* look for fitting font style in combobox2 */
538     for (i=0;i<TEXT_EXTRAS;i++)
539     {
540         id = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
541         if (packedstyle == id)
542         {
543             SendDlgItemMessageW(hDlg, cmb2, CB_SETCURSEL, i, 0);
544             SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
545                     (LPARAM)GetDlgItem(hDlg,cmb2));
546             ret = 1;
547             break;
548         }
549     }
550     return ret;
551 }
552
553
554 static INT CFn_FitCharSet( HWND hDlg, int charset )
555 {
556     int i,n,cs;
557     /* look for fitting char set in combobox5 */
558     n=SendDlgItemMessageW(hDlg, cmb5, CB_GETCOUNT, 0, 0);
559     for (i=0;i<n;i++)
560     {
561         cs =SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
562         if (charset == cs)
563         {
564             SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, i, 0);
565             SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
566                     (LPARAM)GetDlgItem(hDlg,cmb2));
567             return 1;
568         }
569     }
570     /* no charset fits: select the first one in the list */
571     SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, 0, 0);
572     SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
573             (LPARAM)GetDlgItem(hDlg,cmb2));
574     return 0;
575 }
576
577 /***********************************************************************
578  *                 FontStyleEnumProc32                     [internal]
579  */
580 static INT WINAPI FontStyleEnumProc( const ENUMLOGFONTEXW *lpElfex,
581         const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam )
582 {
583     LPCFn_ENUMSTRUCT s=(LPCFn_ENUMSTRUCT)lParam;
584     HWND hcmb2=s->hWnd1;
585     HWND hcmb3=s->hWnd2;
586     HWND hDlg=GetParent(hcmb3);
587     return AddFontStyle( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
588             dwFontType, s->lpcf32w, hcmb2, hcmb3, hDlg, FALSE);
589 }
590
591 /***********************************************************************
592  *           CFn_WMInitDialog                            [internal]
593  */
594 LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam,
595                          LPCHOOSEFONTW lpcf)
596 {
597     HDC hdc;
598     int i,j,init=0;
599     long pstyle;
600     CFn_ENUMSTRUCT s;
601     LPLOGFONTW lpxx;
602     HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
603     static const WCHAR strColorName[] = {'[','c','o','l','o','r',' ','n','a','m','e',']',0};
604
605     SetPropW(hDlg, strWineFontData, (HANDLE)lpcf);
606     lpxx=lpcf->lpLogFont;
607     TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
608
609     if (lpcf->lStructSize != sizeof(CHOOSEFONTW))
610     {
611         ERR("structure size failure !!!\n");
612         EndDialog (hDlg, 0);
613         return FALSE;
614     }
615     if (!himlTT)
616         himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
617                 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
618
619     if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow(lpcf->hwndOwner))
620         ShowWindow(GetDlgItem(hDlg,pshHelp),SW_HIDE);
621     if (!(lpcf->Flags & CF_APPLY))
622         ShowWindow(GetDlgItem(hDlg,psh3),SW_HIDE);
623     if (lpcf->Flags & CF_EFFECTS)
624     {
625         for (i=0;i<TEXT_COLORS;i++)
626         {
627             WCHAR name[30];
628
629             if( LoadStringW(COMDLG32_hInstance, IDS_COLOR_BLACK+i, name,
630                         sizeof(name)/sizeof(*name) )==0 )
631             {
632                 memcpy(name, strColorName, sizeof(strColorName));
633             }
634             j=SendDlgItemMessageW(hDlg, cmb4, CB_ADDSTRING, 0, (LPARAM)name);
635             SendDlgItemMessageW(hDlg, cmb4, CB_SETITEMDATA, j, textcolors[j]);
636             /* look for a fitting value in color combobox */
637             if (textcolors[j]==lpcf->rgbColors)
638                 SendDlgItemMessageW(hDlg,cmb4, CB_SETCURSEL,j,0);
639         }
640     }
641     else
642     {
643         ShowWindow(GetDlgItem(hDlg,cmb4),SW_HIDE);
644         ShowWindow(GetDlgItem(hDlg,chx1),SW_HIDE);
645         ShowWindow(GetDlgItem(hDlg,chx2),SW_HIDE);
646         ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
647         ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
648     }
649     if(!(hdc = CFn_GetDC(lpcf)))
650     {
651         EndDialog (hDlg, 0);
652         return FALSE;
653     }
654     s.hWnd1=GetDlgItem(hDlg,cmb1);
655     s.lpcf32w=lpcf;
656     do {
657         LOGFONTW elf;
658         s.added = 0;
659         elf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
660         elf.lfPitchAndFamily = 0;
661         elf.lfFaceName[0] = '\0'; /* enum all fonts */
662         if (!EnumFontFamiliesExW(hdc, &elf, (FONTENUMPROCW)FontFamilyEnumProc, (LPARAM)&s, 0))
663         {
664             TRACE("EnumFontFamiliesEx returns 0\n");
665             break;
666         }
667         if (s.added) break;
668         if (lpcf->Flags & CF_FIXEDPITCHONLY) {
669             FIXME("No font found with fixed pitch only, dropping flag.\n");
670             lpcf->Flags &= ~CF_FIXEDPITCHONLY;
671             continue;
672         }
673         if (lpcf->Flags & CF_TTONLY) {
674             FIXME("No font found with truetype only, dropping flag.\n");
675             lpcf->Flags &= ~CF_TTONLY;
676             continue;
677         }
678         break;
679     } while (1);
680
681
682     if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
683     {
684         /* look for fitting font name in combobox1 */
685         j=SendDlgItemMessageW(hDlg,cmb1,CB_FINDSTRING,-1,(LPARAM)lpxx->lfFaceName);
686         if (j!=CB_ERR)
687         {
688             INT height = lpxx->lfHeight < 0 ? -lpxx->lfHeight :
689                 lpxx->lfHeight;
690             INT points;
691             int charset = lpxx->lfCharSet;
692             points = MulDiv( height, 72, GetDeviceCaps(hdc, LOGPIXELSY));
693             pstyle = MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD:
694                     FW_NORMAL,lpxx->lfItalic !=0);
695             SendDlgItemMessageW(hDlg, cmb1, CB_SETCURSEL, j, 0);
696             SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
697                     (LPARAM)GetDlgItem(hDlg,cmb1));
698             init=1;
699             /* look for fitting font style in combobox2 */
700             CFn_FitFontStyle(hDlg, pstyle);
701             /* look for fitting font size in combobox3 */
702             CFn_FitFontSize(hDlg, points);
703             CFn_FitCharSet( hDlg, charset );
704         }
705     }
706     if (!init)
707     {
708         SendDlgItemMessageW(hDlg,cmb1,CB_SETCURSEL,0,0);
709         SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
710                 (LPARAM)GetDlgItem(hDlg,cmb1));
711     }
712     if ((lpcf->Flags & CF_USESTYLE) && lpcf->lpszStyle)
713     {
714         j=SendDlgItemMessageW(hDlg,cmb2,CB_FINDSTRING,-1,(LPARAM)lpcf->lpszStyle);
715         if (j!=CB_ERR)
716         {
717             j=SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,j,0);
718             SendMessageW(hDlg,WM_COMMAND,cmb2,
719                     MAKELONG(HWND_16(GetDlgItem(hDlg,cmb2)),CBN_SELCHANGE));
720         }
721     }
722     CFn_ReleaseDC(lpcf, hdc);
723     SetCursor(hcursor);
724     return TRUE;
725 }
726
727
728 /***********************************************************************
729  *           CFn_WMMeasureItem                           [internal]
730  */
731 LRESULT CFn_WMMeasureItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
732 {
733     HDC hdc;
734     HFONT hfontprev;
735     TEXTMETRICW tm;
736     LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam;
737     INT height = 0;
738
739     if (!himlTT)
740         himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
741                 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
742     ImageList_GetIconSize( himlTT, 0, &height);
743     lpmi->itemHeight = height + 2;
744     /* use MAX of bitmap height and tm.tmHeight .*/
745     hdc=GetDC(hDlg);
746     if(!hdc) return 0;
747     hfontprev = SelectObject( hdc, GetStockObject( SYSTEM_FONT));
748     GetTextMetricsW(hdc, &tm);
749     if( tm.tmHeight > lpmi->itemHeight) lpmi->itemHeight = tm.tmHeight;
750     SelectObject(hdc, hfontprev);
751     ReleaseDC(hDlg, hdc);
752     return 0;
753 }
754
755
756 /***********************************************************************
757  *           CFn_WMDrawItem                              [internal]
758  */
759 LRESULT CFn_WMDrawItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
760 {
761     HBRUSH hBrush;
762     WCHAR buffer[40];
763     COLORREF cr, oldText=0, oldBk=0;
764     RECT rect;
765     int nFontType;
766     int idx;
767     LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam;
768
769     if (lpdi->itemID == (UINT)-1)  /* got no items */
770         DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
771     else
772     {
773         if (lpdi->CtlType == ODT_COMBOBOX)
774         {
775             if (lpdi->itemState & ODS_SELECTED)
776             {
777                 hBrush=GetSysColorBrush(COLOR_HIGHLIGHT);
778                 oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
779                 oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT));
780             }  else
781             {
782                 hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
783                 SelectObject(lpdi->hDC, hBrush);
784             }
785             FillRect(lpdi->hDC, &lpdi->rcItem, hBrush);
786         }
787         else
788             return TRUE;        /* this should never happen */
789
790         rect=lpdi->rcItem;
791         switch (lpdi->CtlID)
792         {
793         case cmb1:
794             /* TRACE(commdlg,"WM_Drawitem cmb1\n"); */
795             SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
796                          (LPARAM)buffer);
797             TextOutW(lpdi->hDC, lpdi->rcItem.left + TTBITMAP_XSIZE + 10,
798                      lpdi->rcItem.top, buffer, lstrlenW(buffer));
799             nFontType = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
800             idx = -1;
801             if (nFontType & TRUETYPE_FONTTYPE) {
802                 idx = 0;  /* picture: TT */
803                 if( nFontType & NTM_TT_OPENTYPE)
804                     idx = 2; /* picture: O */
805             } else if( nFontType & NTM_PS_OPENTYPE)
806                 idx = 3; /* picture: O+ps */
807             else if( nFontType & NTM_TYPE1)
808                 idx = 4; /* picture: a */
809             else if( nFontType & DEVICE_FONTTYPE)
810                 idx = 1; /* picture: printer */
811             if( idx >= 0)
812                 ImageList_Draw( himlTT, idx, lpdi->hDC, lpdi->rcItem.left,
813                         lpdi->rcItem.top, ILD_TRANSPARENT);
814             break;
815         case cmb2:
816         case cmb3:
817             /* TRACE(commdlg,"WM_DRAWITEN cmb2,cmb3\n"); */
818         case cmb5:
819             SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
820                          (LPARAM)buffer);
821             TextOutW(lpdi->hDC, lpdi->rcItem.left,
822                      lpdi->rcItem.top, buffer, lstrlenW(buffer));
823             break;
824
825         case cmb4:
826             /* TRACE(commdlg,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
827             SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
828                      (LPARAM)buffer);
829             TextOutW(lpdi->hDC, lpdi->rcItem.left +  25+5,
830                      lpdi->rcItem.top, buffer, lstrlenW(buffer));
831             cr = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
832             hBrush = CreateSolidBrush(cr);
833             if (hBrush)
834             {
835                 hBrush = SelectObject (lpdi->hDC, hBrush) ;
836                 rect.right=rect.left+25;
837                 rect.top++;
838                 rect.left+=5;
839                 rect.bottom--;
840                 Rectangle( lpdi->hDC, rect.left, rect.top,
841                            rect.right, rect.bottom );
842                 DeleteObject( SelectObject (lpdi->hDC, hBrush)) ;
843             }
844             rect=lpdi->rcItem;
845             rect.left+=25+5;
846             break;
847
848         default:
849             return TRUE;  /* this should never happen */
850         }
851         if (lpdi->itemState & ODS_SELECTED)
852         {
853             SetTextColor(lpdi->hDC, oldText);
854             SetBkColor(lpdi->hDC, oldBk);
855         }
856     }
857     return TRUE;
858 }
859
860 /***********************************************************************
861  *           CFn_WMCommand                               [internal]
862  */
863 LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam,
864         LPCHOOSEFONTW lpcf)
865 {
866     int i;
867     long l;
868     HDC hdc;
869     LPLOGFONTW lpxx=lpcf->lpLogFont;
870
871     TRACE("WM_COMMAND wParam=%08lX lParam=%08lX\n", (LONG)wParam, lParam);
872     switch (LOWORD(wParam))
873     {
874     case cmb1:
875         if (HIWORD(wParam)==CBN_SELCHANGE)
876         {
877             INT pointsize; /* save current pointsize */
878             LONG pstyle;  /* save current style */
879             int charset;
880             int idx;
881             if(!(hdc = CFn_GetDC(lpcf)))
882             {
883                 EndDialog (hDlg, 0);
884                 return TRUE;
885             }
886             idx = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
887             pointsize = (int)SendDlgItemMessageW( hDlg, cmb3, CB_GETITEMDATA,
888                     idx, 0);
889             idx = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
890             pstyle = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, idx, 0);
891             idx = SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
892             charset = SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, idx, 0);
893
894             SendDlgItemMessageW(hDlg, cmb2, CB_RESETCONTENT, 0, 0);
895             SendDlgItemMessageW(hDlg, cmb3, CB_RESETCONTENT, 0, 0);
896             SendDlgItemMessageW(hDlg, cmb5, CB_RESETCONTENT, 0, 0);
897             i=SendDlgItemMessageW(hDlg, cmb1, CB_GETCURSEL, 0, 0);
898             if (i!=CB_ERR)
899             {
900                 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
901                 CFn_ENUMSTRUCT s;
902                 LOGFONTW enumlf;
903                 SendDlgItemMessageW(hDlg, cmb1, CB_GETLBTEXT, i,
904                                     (LPARAM)enumlf.lfFaceName);
905                 TRACE("WM_COMMAND/cmb1 =>%s\n", debugstr_w(enumlf.lfFaceName));
906                 s.hWnd1=GetDlgItem(hDlg, cmb2);
907                 s.hWnd2=GetDlgItem(hDlg, cmb3);
908                 s.lpcf32w=lpcf;
909                 enumlf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
910                 enumlf.lfPitchAndFamily = 0;
911                 EnumFontFamiliesExW(hdc, &enumlf,
912                         (FONTENUMPROCW)FontStyleEnumProc, (LPARAM)&s, 0);
913                 CFn_FitFontStyle(hDlg, pstyle);
914                 if( pointsize != CB_ERR) CFn_FitFontSize(hDlg, pointsize);
915                 if( charset != CB_ERR) CFn_FitCharSet( hDlg, charset );
916                 SetCursor(hcursor);
917             }
918             CFn_ReleaseDC(lpcf, hdc);
919         }
920     case chx1:
921     case chx2:
922     case cmb2:
923     case cmb3:
924     case cmb5:
925         if (HIWORD(wParam)==CBN_SELCHANGE || HIWORD(wParam)== BN_CLICKED )
926         {
927             WCHAR str[256];
928             WINDOWINFO wininfo;
929
930             TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
931             i=SendDlgItemMessageW(hDlg,cmb1,CB_GETCURSEL,0,0);
932             if (i==CB_ERR)
933                 i=GetDlgItemTextW( hDlg, cmb1, str, 256 );
934             else
935             {
936                 SendDlgItemMessageW(hDlg,cmb1,CB_GETLBTEXT,i,
937                                     (LPARAM)str);
938                 l=SendDlgItemMessageW(hDlg,cmb1,CB_GETITEMDATA,i,0);
939                 lpcf->nFontType = LOWORD(l);
940                 /* FIXME:   lpcf->nFontType |= ....  SIMULATED_FONTTYPE and so */
941                 /* same value reported to the EnumFonts
942                    call back with the extra FONTTYPE_...  bits added */
943                 lpxx->lfPitchAndFamily = HIWORD(l) >> 8;
944             }
945             lstrcpyW(lpxx->lfFaceName,str);
946             i=SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
947             if (i!=CB_ERR)
948             {
949                 l=SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
950                 if (0!=(lpxx->lfItalic=HIWORD(l)))
951                     lpcf->nFontType |= ITALIC_FONTTYPE;
952                 if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
953                     lpcf->nFontType |= BOLD_FONTTYPE;
954             }
955             i=SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
956             if( i != CB_ERR)
957                 lpcf->iPointSize = 10 * LOWORD(SendDlgItemMessageW(hDlg, cmb3,
958                             CB_GETITEMDATA , i, 0));
959             else
960                 lpcf->iPointSize = 100;
961             hdc = CFn_GetDC(lpcf);
962             if( hdc)
963             {
964                 lpxx->lfHeight = - MulDiv( lpcf->iPointSize ,
965                         GetDeviceCaps(hdc, LOGPIXELSY), 720);
966                 CFn_ReleaseDC(lpcf, hdc);
967             } else
968                 lpxx->lfHeight = -lpcf->iPointSize / 10;
969             i=SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
970             if (i!=CB_ERR)
971                 lpxx->lfCharSet=SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
972             else
973                 lpxx->lfCharSet = DEFAULT_CHARSET;
974             lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
975             lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
976             lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
977             lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
978             lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
979             lpxx->lfQuality=DEFAULT_QUALITY;
980
981             wininfo.cbSize=sizeof(wininfo);
982
983             if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
984             {
985                 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
986                 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
987             }
988         }
989         break;
990
991     case cmb4:
992         i=SendDlgItemMessageW(hDlg, cmb4, CB_GETCURSEL, 0, 0);
993         if (i!=CB_ERR)
994         {
995             WINDOWINFO wininfo;
996
997             lpcf->rgbColors=textcolors[i];
998             wininfo.cbSize=sizeof(wininfo);
999
1000             if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1001             {
1002                 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1003                 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1004             }
1005         }
1006         break;
1007
1008     case psh15:
1009         i=RegisterWindowMessageW( HELPMSGSTRINGW );
1010         if (lpcf->hwndOwner)
1011             SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData));
1012         /* if (CFn_HookCallChk(lpcf))
1013            CallWindowProc16(lpcf->lpfnHook,hDlg,WM_COMMAND,psh15,(LPARAM)lpcf);*/
1014         break;
1015
1016     case IDOK:
1017         if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
1018               ( (lpcf->Flags & CF_LIMITSIZE) &&
1019                 (lpcf->iPointSize >= 10 * lpcf->nSizeMin) &&
1020                 (lpcf->iPointSize <= 10 * lpcf->nSizeMax)))
1021             EndDialog(hDlg, TRUE);
1022         else
1023         {
1024             WCHAR buffer[80];
1025             WCHAR format[80];
1026             LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE, format, sizeof(format)/sizeof(WCHAR));
1027             wsprintfW(buffer, format, lpcf->nSizeMin,lpcf->nSizeMax);
1028             MessageBoxW(hDlg, buffer, NULL, MB_OK);
1029         }
1030         return(TRUE);
1031     case IDCANCEL:
1032         EndDialog(hDlg, FALSE);
1033         return(TRUE);
1034     }
1035     return(FALSE);
1036 }
1037
1038 static LRESULT CFn_WMDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcfw)
1039 {
1040     LPCHOOSEFONTA lpcfa;
1041     LPSTR lpszStyle;
1042     LPLOGFONTA lpLogFonta;
1043     int len;
1044
1045     lpcfa = GetPropW(hwnd, strWineFontData_a);
1046     lpLogFonta = lpcfa->lpLogFont;
1047     lpszStyle = lpcfa->lpszStyle;
1048     memcpy(lpcfa, lpcfw, sizeof(CHOOSEFONTA));
1049     lpcfa->lpLogFont = lpLogFonta;
1050     lpcfa->lpszStyle = lpszStyle;
1051     memcpy(lpcfa->lpLogFont, lpcfw->lpLogFont, sizeof(LOGFONTA));
1052     WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName,
1053                         LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0);
1054
1055     if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) {
1056         len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, -1, 0, 0);
1057         WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0);
1058         HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle);
1059     }
1060
1061     HeapFree(GetProcessHeap(), 0, lpcfw->lpLogFont);
1062     HeapFree(GetProcessHeap(), 0, lpcfw);
1063     SetPropW(hwnd, strWineFontData, 0);
1064
1065     return TRUE;
1066 }
1067
1068 LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcf)
1069 {
1070     WINDOWINFO info;
1071
1072     info.cbSize=sizeof(info);
1073     if( GetWindowInfo( GetDlgItem( hDlg, stc5), &info ) )
1074     {
1075         PAINTSTRUCT ps;
1076         HDC hdc;
1077         HPEN hOrigPen;
1078         HFONT hOrigFont;
1079         LOGFONTW lf = *(lpcf->lpLogFont);
1080
1081         MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2);
1082         hdc = BeginPaint( hDlg, &ps );
1083
1084         TRACE("erase %d, rect=(%ld,%ld)-(%ld,%ld)\n", ps.fErase,
1085               ps.rcPaint.left, ps.rcPaint.top,
1086               ps.rcPaint.right, ps.rcPaint.bottom);
1087
1088         /* Paint frame */
1089         MoveToEx( hdc, info.rcWindow.left, info.rcWindow.bottom, NULL );
1090         hOrigPen=SelectObject( hdc, CreatePen( PS_SOLID, 2,
1091                                                GetSysColor( COLOR_3DSHADOW ) ));
1092         LineTo( hdc, info.rcWindow.left, info.rcWindow.top );
1093         LineTo( hdc, info.rcWindow.right, info.rcWindow.top );
1094         DeleteObject(SelectObject( hdc, CreatePen( PS_SOLID, 2,
1095                                                    GetSysColor( COLOR_3DLIGHT ) )));
1096         LineTo( hdc, info.rcWindow.right, info.rcWindow.bottom );
1097         LineTo( hdc, info.rcWindow.left, info.rcWindow.bottom );
1098         DeleteObject(SelectObject( hdc, hOrigPen ));
1099
1100         /* Draw the sample text itself */
1101         info.rcWindow.right--;
1102         info.rcWindow.bottom--;
1103         info.rcWindow.top++;
1104         info.rcWindow.left++;
1105         hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
1106         SetTextColor( hdc, lpcf->rgbColors );
1107
1108         DrawTextW( hdc,
1109                 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]],
1110                 -1, &info.rcWindow, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
1111
1112         DeleteObject(SelectObject( hdc, hOrigFont ));
1113         EndPaint( hDlg, &ps );
1114     }
1115     return FALSE;
1116 }
1117
1118 /***********************************************************************
1119  *           FormatCharDlgProcA   [internal]
1120  */
1121 INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
1122         LPARAM lParam)
1123 {
1124     LPCHOOSEFONTW lpcfw;
1125     LPCHOOSEFONTA lpcfa;
1126     INT_PTR res = FALSE;
1127     int len;
1128
1129     if (uMsg!=WM_INITDIALOG) {
1130         lpcfw = (LPCHOOSEFONTW)GetPropW(hDlg, strWineFontData);
1131         if (!lpcfw)
1132             return FALSE;
1133         if (CFn_HookCallChk32(lpcfw))
1134             res=CallWindowProcA((WNDPROC)lpcfw->lpfnHook, hDlg, uMsg, wParam, lParam);
1135         if (res)
1136             return res;
1137     } else {
1138         lpcfa=(LPCHOOSEFONTA)lParam;
1139         SetPropW(hDlg, strWineFontData_a, (HANDLE)lParam);
1140
1141         lpcfw = HeapAlloc(GetProcessHeap(), 0, sizeof(CHOOSEFONTW));
1142         memcpy(lpcfw, lpcfa, sizeof(CHOOSEFONTA));
1143         lpcfw->lpLogFont = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGFONTW));
1144         memcpy(lpcfw->lpLogFont, lpcfa->lpLogFont, sizeof(LOGFONTA));
1145         MultiByteToWideChar(CP_ACP, 0, lpcfa->lpLogFont->lfFaceName,
1146                             LF_FACESIZE, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE);
1147
1148         if((lpcfa->Flags & CF_USESTYLE) && lpcfa->lpszStyle)  {
1149             len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, NULL, 0);
1150             lpcfw->lpszStyle = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
1151             MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len);
1152         }
1153
1154         if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcfw))
1155         {
1156             TRACE("CFn_WMInitDialog returned FALSE\n");
1157             return FALSE;
1158         }
1159         if (CFn_HookCallChk32(lpcfw))
1160             return CallWindowProcA((WNDPROC)lpcfa->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1161     }
1162     switch (uMsg)
1163     {
1164     case WM_MEASUREITEM:
1165         return CFn_WMMeasureItem(hDlg, wParam, lParam);
1166     case WM_DRAWITEM:
1167         return CFn_WMDrawItem(hDlg, wParam, lParam);
1168     case WM_COMMAND:
1169         return CFn_WMCommand(hDlg, wParam, lParam, lpcfw);
1170     case WM_DESTROY:
1171         return CFn_WMDestroy(hDlg, wParam, lParam, lpcfw);
1172     case WM_CHOOSEFONT_GETLOGFONT:
1173         TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1174         FIXME("current logfont back to caller\n");
1175         break;
1176     case WM_PAINT:
1177         return CFn_WMPaint(hDlg, wParam, lParam, lpcfw);
1178     }
1179     return res;
1180 }
1181
1182 /***********************************************************************
1183  *           FormatCharDlgProcW   [internal]
1184  */
1185 INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam,
1186         LPARAM lParam)
1187 {
1188     LPCHOOSEFONTW lpcf;
1189     INT_PTR res = FALSE;
1190
1191     if (uMsg!=WM_INITDIALOG)
1192     {
1193         lpcf=(LPCHOOSEFONTW)GetPropW(hDlg, strWineFontData);
1194         if (!lpcf)
1195             return FALSE;
1196         if (CFn_HookCallChk32(lpcf))
1197             res=CallWindowProcW((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam);
1198         if (res)
1199             return res;
1200     }
1201     else
1202     {
1203         lpcf=(LPCHOOSEFONTW)lParam;
1204         if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcf))
1205         {
1206             TRACE("CFn_WMInitDialog returned FALSE\n");
1207             return FALSE;
1208         }
1209         if (CFn_HookCallChk32(lpcf))
1210             return CallWindowProcW((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1211     }
1212     switch (uMsg)
1213     {
1214     case WM_MEASUREITEM:
1215         return CFn_WMMeasureItem(hDlg, wParam, lParam);
1216     case WM_DRAWITEM:
1217         return CFn_WMDrawItem(hDlg, wParam, lParam);
1218     case WM_COMMAND:
1219         return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
1220     case WM_DESTROY:
1221         return TRUE;
1222     case WM_CHOOSEFONT_GETLOGFONT:
1223         TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1224         FIXME("current logfont back to caller\n");
1225         break;
1226     case WM_PAINT:
1227         return CFn_WMPaint(hDlg, wParam, lParam, lpcf);
1228     }
1229     return res;
1230 }