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