comdlg32: Uses SetDlgItemInt() to simplify the code.
[wine.git] / dlls / comdlg32 / fontdlg.c
blobc08b246e1294033b0028fc65c8b31432a408a124
1 /*
2 * COMMDLG - Font Dialog
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
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.
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.
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
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 "wine/unicode.h"
36 #include "cderr.h"
37 #include "cdlg.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
41 typedef struct
43 HWND hWnd1;
44 HWND hWnd2;
45 LPCHOOSEFONTW lpcf32w;
46 int added;
47 } CFn_ENUMSTRUCT, *LPCFn_ENUMSTRUCT;
50 static const WCHAR strWineFontData[] = {'_','_','W','I','N','E','_','F','O','N','T','D','L','G','D','A','T','A',0};
51 static const WCHAR strWineFontData_a[] =
52 {'_','_','W','I','N','E','_','F','O','N','T','D','L','G','D','A','T','A','_','A',0};
53 static const WCHAR chooseFontW[] = {'C','H','O','O','S','E','_','F','O','N','T',0};
54 static const WCHAR fontsizefmtW[] = {'%','d',0};
56 /* image list with TrueType bitmaps and more */
57 static HIMAGELIST himlTT = 0;
58 #define TTBITMAP_XSIZE 20 /* x-size of the bitmaps */
60 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
61 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
63 /* There is a table here of all charsets, and the sample text for each.
64 * There is a second table that translates a charset into an index into
65 * the first table.
68 #define CI(cs) ((IDS_CHARSET_##cs)-IDS_CHARSET_ANSI)
71 static const WCHAR stWestern[]={'A','a','B','b','Y','y','Z','z',0}; /* Western and default */
72 static const WCHAR stSymbol[]={'S','y','m','b','o','l',0}; /* Symbol */
73 static const WCHAR stShiftJis[]={'A','a',0x3042,0x3041,0x30a2,0x30a1,0x4e9c,0x5b87,0}; /* Shift JIS */
74 static const WCHAR stHangul[]={0xac00,0xb098,0xb2e4,'A','a','B','Y','y','Z','z',0}; /* Hangul */
75 static const WCHAR stGB2312[]={0x5fae,0x8f6f,0x4e2d,0x6587,0x8f6f,0x4ef6,0}; /* GB2312 */
76 static const WCHAR stBIG5[]={0x4e2d,0x6587,0x5b57,0x578b,0x7bc4,0x4f8b,0}; /* BIG5 */
77 static const WCHAR stGreek[]={'A','a','B','b',0x0391,0x03b1,0x0392,0x03b2,0}; /* Greek */
78 static const WCHAR stTurkish[]={'A','a','B','b',0x011e,0x011f,0x015e,0x015f,0}; /* Turkish */
79 static const WCHAR stHebrew[]={'A','a','B','b',0x05e0,0x05e1,0x05e9,0x05ea,0}; /* Hebrew */
80 static const WCHAR stArabic[]={'A','a','B','b',0x0627,0x0628,0x062c,0x062f,0x0647,0x0648,0x0632,0};/* Arabic */
81 static const WCHAR stBaltic[]={'A','a','B','b','Y','y','Z','z',0}; /* Baltic */
82 static const WCHAR stVietname[]={'A','a','B','b',0x01a0,0x01a1,0x01af,0x01b0,0}; /* Vietnamese */
83 static const WCHAR stCyrillic[]={'A','a','B','b',0x0411,0x0431,0x0424,0x0444,0}; /* Cyrillic */
84 static const WCHAR stEastEur[]={'A','a','B','b',0xc1,0xe1,0xd4,0xf4,0}; /* East European */
85 static const WCHAR stThai[]={'A','a','B','b',0x0e2d,0x0e31,0x0e01,0x0e29,0x0e23,0x0e44,0x0e17,0x0e22,0}; /* Thai */
86 static const WCHAR stJohab[]={0xac00,0xb098,0xb2e4,'A','a','B','Y','y','Z','z',0}; /* Johab */
87 static const WCHAR stMac[]={'A','a','B','b','Y','y','Z','z',0}; /* Mac */
88 static const WCHAR stOEM[]={'A','a','B','b',0xf8,0xf1,0xfd,0}; /* OEM */
89 /* the following character sets actually behave different (Win2K observation):
90 * the sample string is 'sticky': it uses the sample string of the previous
91 * selected character set. That behaviour looks like some default, which is
92 * not (yet) implemented. */
93 static const WCHAR stVISCII[]={'A','a','B','b',0}; /* VISCII */
94 static const WCHAR stTCVN[]={'A','a','B','b',0}; /* TCVN */
95 static const WCHAR stKOI8[]={'A','a','B','b',0}; /* KOI-8 */
96 static const WCHAR stIso88593[]={'A','a','B','b',0}; /* ISO-8859-3 */
97 static const WCHAR stIso88594[]={'A','a','B','b',0}; /* ISO-8859-4 */
98 static const WCHAR stIso885910[]={'A','a','B','b',0}; /* ISO-8859-10 */
99 static const WCHAR stCeltic[]={'A','a','B','b',0};/* Celtic */
101 static const WCHAR * const sample_lang_text[]={
102 stWestern,stSymbol,stShiftJis,stHangul,stGB2312,
103 stBIG5,stGreek,stTurkish,stHebrew,stArabic,
104 stBaltic,stVietname,stCyrillic,stEastEur,stThai,
105 stJohab,stMac,stOEM,stVISCII,stTCVN,
106 stKOI8,stIso88593,stIso88594,stIso885910,stCeltic};
109 static const BYTE CHARSET_ORDER[256]={
110 CI(ANSI), 0, CI(SYMBOL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(MAC), 0, 0,
115 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
118 CI(JIS), CI(HANGUL), CI(JOHAB), 0, 0, 0, CI(GB2312), 0, CI(BIG5), 0, 0, 0, 0, 0, 0, 0,
119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
120 0, CI(GREEK), CI(TURKISH), CI(VIETNAMESE), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
121 0, CI(HEBREW), CI(ARABIC), 0, 0, 0, 0, 0, 0, 0, CI(BALTIC), 0, 0, 0, 0, 0,
122 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(RUSSIAN), 0, 0, 0,
123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(THAI), 0,
124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(EE), 0,
125 CI(VISCII), CI(TCVN), CI(KOI8), CI(ISO3), CI(ISO4), CI(ISO10), CI(CELTIC), 0, 0, 0, 0, 0, 0, 0, 0, CI(OEM),
128 static const struct {
129 DWORD mask;
130 const char *name;
131 } cfflags[] = {
132 #define XX(x) { x, #x },
133 XX(CF_SCREENFONTS)
134 XX(CF_PRINTERFONTS)
135 XX(CF_SHOWHELP)
136 XX(CF_ENABLEHOOK)
137 XX(CF_ENABLETEMPLATE)
138 XX(CF_ENABLETEMPLATEHANDLE)
139 XX(CF_INITTOLOGFONTSTRUCT)
140 XX(CF_USESTYLE)
141 XX(CF_EFFECTS)
142 XX(CF_APPLY)
143 XX(CF_ANSIONLY)
144 XX(CF_NOVECTORFONTS)
145 XX(CF_NOSIMULATIONS)
146 XX(CF_LIMITSIZE)
147 XX(CF_FIXEDPITCHONLY)
148 XX(CF_WYSIWYG)
149 XX(CF_FORCEFONTEXIST)
150 XX(CF_SCALABLEONLY)
151 XX(CF_TTONLY)
152 XX(CF_NOFACESEL)
153 XX(CF_NOSTYLESEL)
154 XX(CF_NOSIZESEL)
155 XX(CF_SELECTSCRIPT)
156 XX(CF_NOSCRIPTSEL)
157 XX(CF_NOVERTFONTS)
158 #undef XX
161 static void _dump_cf_flags(DWORD cflags)
163 unsigned int i;
165 for (i = 0; i < sizeof(cfflags)/sizeof(cfflags[0]); i++)
166 if (cfflags[i].mask & cflags)
167 TRACE("%s|",cfflags[i].name);
168 TRACE("\n");
171 /***********************************************************************
172 * ChooseFontW (COMDLG32.@)
174 * Create a font dialog box.
176 * PARAMS
177 * lpChFont [I/O] in: information to initialize the dialog box.
178 * out: User's color selection
180 * RETURNS
181 * TRUE: Ok button clicked.
182 * FALSE: Cancel button clicked, or error.
184 BOOL WINAPI ChooseFontW(LPCHOOSEFONTW lpChFont)
186 LPCVOID template;
187 HRSRC hResInfo;
188 HINSTANCE hDlginst;
189 HGLOBAL hDlgTmpl;
191 TRACE("(%p)\n", lpChFont);
193 if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 )
195 template=lpChFont->hInstance;
196 } else
198 if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 )
200 hDlginst=lpChFont->hInstance;
201 if( !(hResInfo = FindResourceW(hDlginst, lpChFont->lpTemplateName,
202 (LPWSTR)RT_DIALOG)))
204 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
205 return FALSE;
207 } else
209 hDlginst=COMDLG32_hInstance;
210 if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG)))
212 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
213 return FALSE;
216 if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) ||
217 !(template = LockResource( hDlgTmpl )))
219 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
220 return FALSE;
223 if (TRACE_ON(commdlg))
224 _dump_cf_flags(lpChFont->Flags);
226 if (lpChFont->Flags & CF_SELECTSCRIPT)
227 FIXME(": unimplemented flag (ignored)\n");
229 return DialogBoxIndirectParamW(COMDLG32_hInstance, template,
230 lpChFont->hwndOwner, FormatCharDlgProcW, (LPARAM)lpChFont );
233 /***********************************************************************
234 * ChooseFontA (COMDLG32.@)
236 * See ChooseFontW.
238 BOOL WINAPI ChooseFontA(LPCHOOSEFONTA lpChFont)
240 LPCVOID template;
241 HRSRC hResInfo;
242 HINSTANCE hDlginst;
243 HGLOBAL hDlgTmpl;
245 TRACE("(%p)\n", lpChFont);
247 if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 )
249 template=lpChFont->hInstance;
250 } else
252 if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 )
254 hDlginst=lpChFont->hInstance;
255 if( !(hResInfo = FindResourceA(hDlginst, lpChFont->lpTemplateName,
256 (LPSTR)RT_DIALOG)))
258 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
259 return FALSE;
261 } else
263 hDlginst=COMDLG32_hInstance;
264 if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG)))
266 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
267 return FALSE;
270 if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) ||
271 !(template = LockResource( hDlgTmpl )))
273 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
274 return FALSE;
277 if (TRACE_ON(commdlg))
278 _dump_cf_flags(lpChFont->Flags);
279 if (lpChFont->Flags & CF_SELECTSCRIPT)
280 FIXME(": unimplemented flag (ignored)\n");
282 return DialogBoxIndirectParamA(COMDLG32_hInstance, template,
283 lpChFont->hwndOwner, FormatCharDlgProcA, (LPARAM)lpChFont );
286 #define TEXT_EXTRAS 4
287 #define TEXT_COLORS 16
289 static const COLORREF textcolors[TEXT_COLORS]=
291 0x00000000L,0x00000080L,0x00008000L,0x00008080L,
292 0x00800000L,0x00800080L,0x00808000L,0x00808080L,
293 0x00c0c0c0L,0x000000ffL,0x0000ff00L,0x0000ffffL,
294 0x00ff0000L,0x00ff00ffL,0x00ffff00L,0x00FFFFFFL
297 /***********************************************************************
298 * CFn_HookCallChk32 [internal]
300 static BOOL CFn_HookCallChk32(const CHOOSEFONTW *lpcf)
302 if (lpcf)
303 if(lpcf->Flags & CF_ENABLEHOOK)
304 if (lpcf->lpfnHook)
305 return TRUE;
306 return FALSE;
309 /*************************************************************************
310 * AddFontFamily [internal]
312 static INT AddFontFamily(const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM,
313 UINT nFontType, const CHOOSEFONTW *lpcf, HWND hwnd, LPCFn_ENUMSTRUCT e)
315 int i;
316 WORD w;
317 const LOGFONTW *lplf = &(lpElfex->elfLogFont);
319 TRACE("font=%s (nFontType=%d)\n", debugstr_w(lplf->lfFaceName), nFontType);
321 if (lpcf->Flags & CF_FIXEDPITCHONLY)
322 if (!(lplf->lfPitchAndFamily & FIXED_PITCH))
323 return 1;
324 if (lpcf->Flags & CF_ANSIONLY)
325 if (lplf->lfCharSet != ANSI_CHARSET)
326 return 1;
327 if (lpcf->Flags & CF_TTONLY)
328 if (!(nFontType & TRUETYPE_FONTTYPE))
329 return 1;
330 if (lpcf->Flags & CF_NOVERTFONTS)
331 if (lplf->lfFaceName[0] == '@')
332 return 1;
334 if (e) e->added++;
336 i=SendMessageW(hwnd, CB_FINDSTRINGEXACT, 0, (LPARAM)lplf->lfFaceName);
337 if (i == CB_ERR) {
338 i = SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)lplf->lfFaceName);
339 if( i != CB_ERR) {
340 /* store some important font information */
341 w = (lplf->lfPitchAndFamily) << 8 |
342 (HIWORD(lpNTM->ntmTm.ntmFlags) & 0xff);
343 SendMessageW(hwnd, CB_SETITEMDATA, i, MAKELONG(nFontType,w));
346 return 1;
349 /*************************************************************************
350 * FontFamilyEnumProc32 [internal]
352 static INT WINAPI FontFamilyEnumProc(const ENUMLOGFONTEXW *lpElfex,
353 const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam)
355 LPCFn_ENUMSTRUCT e;
356 e=(LPCFn_ENUMSTRUCT)lParam;
357 return AddFontFamily( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
358 dwFontType, e->lpcf32w, e->hWnd1, e);
361 /*************************************************************************
362 * SetFontStylesToCombo2 [internal]
364 * Fill font style information into combobox (without using font.c directly)
366 static BOOL SetFontStylesToCombo2(HWND hwnd, HDC hdc, const LOGFONTW *lplf)
368 #define FSTYLES 4
369 struct FONTSTYLE
371 int italic;
372 int weight;
373 UINT resId;
375 static const struct FONTSTYLE fontstyles[FSTYLES]={
376 { 0, FW_NORMAL, IDS_FONT_REGULAR },
377 { 1, FW_NORMAL, IDS_FONT_ITALIC },
378 { 0, FW_BOLD, IDS_FONT_BOLD },
379 { 1, FW_BOLD, IDS_FONT_BOLD_ITALIC }
381 HFONT hf;
382 TEXTMETRICW tm;
383 int i,j;
384 LOGFONTW lf;
386 lf = *lplf;
388 for (i=0;i<FSTYLES;i++)
390 lf.lfItalic=fontstyles[i].italic;
391 lf.lfWeight=fontstyles[i].weight;
392 hf=CreateFontIndirectW(&lf);
393 hf=SelectObject(hdc,hf);
394 GetTextMetricsW(hdc,&tm);
395 hf=SelectObject(hdc,hf);
396 DeleteObject(hf);
397 /* font successful created ? */
398 if (((fontstyles[i].weight == FW_NORMAL && tm.tmWeight <= FW_MEDIUM) ||
399 (fontstyles[i].weight == FW_BOLD && tm.tmWeight > FW_MEDIUM)) &&
400 ((tm.tmItalic != 0)==fontstyles[i].italic))
402 WCHAR name[64];
403 LoadStringW(COMDLG32_hInstance, fontstyles[i].resId, name, 64);
404 j=SendMessageW(hwnd,CB_ADDSTRING,0,(LPARAM)name );
405 if (j==CB_ERR) return TRUE;
406 j=SendMessageW(hwnd, CB_SETITEMDATA, j,
407 MAKELONG(tm.tmWeight,fontstyles[i].italic));
408 if (j==CB_ERR) return TRUE;
411 return FALSE;
414 /*************************************************************************
415 * AddFontSizeToCombo3 [internal]
417 static BOOL AddFontSizeToCombo3(HWND hwnd, UINT h, const CHOOSEFONTW *lpcf)
419 int j;
420 WCHAR buffer[20];
422 if ( (!(lpcf->Flags & CF_LIMITSIZE)) ||
423 ((lpcf->Flags & CF_LIMITSIZE) && (h >= lpcf->nSizeMin) && (h <= lpcf->nSizeMax)))
425 sprintfW(buffer, fontsizefmtW, h);
426 j=SendMessageW(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)buffer);
427 if (j==CB_ERR)
429 j=SendMessageW(hwnd, CB_INSERTSTRING, -1, (LPARAM)buffer);
430 if (j!=CB_ERR) j = SendMessageW(hwnd, CB_SETITEMDATA, j, h);
431 if (j==CB_ERR) return TRUE;
434 return FALSE;
437 /*************************************************************************
438 * SetFontSizesToCombo3 [internal]
440 static BOOL SetFontSizesToCombo3(HWND hwnd, const CHOOSEFONTW *lpcf)
442 static const BYTE sizes[]={6,7,8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
443 unsigned int i;
445 for (i = 0; i < sizeof(sizes)/sizeof(sizes[0]); i++)
446 if (AddFontSizeToCombo3(hwnd, sizes[i], lpcf)) return TRUE;
447 return FALSE;
450 /*************************************************************************
451 * CFn_GetDC [internal]
453 static inline HDC CFn_GetDC(const CHOOSEFONTW *lpcf)
455 HDC ret = ((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC) ?
456 lpcf->hDC :
457 GetDC(0);
458 if(!ret) ERR("HDC failure!!!\n");
459 return ret;
462 /*************************************************************************
463 * GetScreenDPI [internal]
465 static inline int GetScreenDPI(void)
467 HDC hdc;
468 int result;
470 hdc = GetDC(0);
471 result = GetDeviceCaps(hdc, LOGPIXELSY);
472 ReleaseDC(0, hdc);
474 return result;
477 /*************************************************************************
478 * CFn_ReleaseDC [internal]
480 static inline void CFn_ReleaseDC(const CHOOSEFONTW *lpcf, HDC hdc)
482 if(!((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC))
483 ReleaseDC(0, hdc);
486 /***********************************************************************
487 * AddFontStyle [internal]
489 static INT AddFontStyle( const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM,
490 UINT nFontType, const CHOOSEFONTW *lpcf, HWND hcmb2, HWND hcmb3, HWND hDlg)
492 int i;
493 const LOGFONTW *lplf = &(lpElfex->elfLogFont);
494 HWND hcmb5;
495 HDC hdc;
497 TRACE("(nFontType=%d)\n",nFontType);
498 TRACE(" %s h=%d w=%d e=%d o=%d wg=%d i=%d u=%d s=%d"
499 " ch=%d op=%d cp=%d q=%d pf=%xh\n",
500 debugstr_w(lplf->lfFaceName),lplf->lfHeight,lplf->lfWidth,
501 lplf->lfEscapement,lplf->lfOrientation,
502 lplf->lfWeight,lplf->lfItalic,lplf->lfUnderline,
503 lplf->lfStrikeOut,lplf->lfCharSet, lplf->lfOutPrecision,
504 lplf->lfClipPrecision,lplf->lfQuality, lplf->lfPitchAndFamily);
505 if (nFontType & RASTER_FONTTYPE)
507 INT points;
508 points = MulDiv( lpNTM->ntmTm.tmHeight - lpNTM->ntmTm.tmInternalLeading,
509 72, GetScreenDPI());
510 if (AddFontSizeToCombo3(hcmb3, points, lpcf))
511 return 0;
512 } else if (SetFontSizesToCombo3(hcmb3, lpcf)) return 0;
514 if (!SendMessageW(hcmb2, CB_GETCOUNT, 0, 0))
516 BOOL res;
517 if(!(hdc = CFn_GetDC(lpcf))) return 0;
518 res = SetFontStylesToCombo2(hcmb2,hdc,lplf);
519 CFn_ReleaseDC(lpcf, hdc);
520 if (res)
521 return 0;
523 if (!( hcmb5 = GetDlgItem(hDlg, cmb5))) return 1;
524 i = SendMessageW( hcmb5, CB_FINDSTRINGEXACT, 0,
525 (LPARAM)lpElfex->elfScript);
526 if( i == CB_ERR) {
527 i = SendMessageW( hcmb5, CB_ADDSTRING, 0,
528 (LPARAM)lpElfex->elfScript);
529 if( i != CB_ERR)
530 SendMessageW( hcmb5, CB_SETITEMDATA, i, lplf->lfCharSet);
532 return 1 ;
535 static void CFn_FitFontSize( HWND hDlg, int points)
537 int i,n;
539 /* look for fitting font size in combobox3 */
540 n=SendDlgItemMessageW(hDlg, cmb3, CB_GETCOUNT, 0, 0);
541 for (i=0;i<n;i++)
543 if (points == (int)SendDlgItemMessageW
544 (hDlg,cmb3, CB_GETITEMDATA,i,0))
546 SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,i,0);
547 SendMessageW(hDlg, WM_COMMAND,
548 MAKEWPARAM(cmb3, CBN_SELCHANGE),
549 (LPARAM)GetDlgItem(hDlg,cmb3));
550 return;
554 /* no default matching size, set text manually */
555 SetDlgItemInt(hDlg, cmb3, points, TRUE);
558 static BOOL CFn_FitFontStyle( HWND hDlg, LONG packedstyle )
560 LONG id;
561 int i;
562 BOOL ret = FALSE;
563 /* look for fitting font style in combobox2 */
564 for (i=0;i<TEXT_EXTRAS;i++)
566 id = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
567 if (packedstyle == id)
569 SendDlgItemMessageW(hDlg, cmb2, CB_SETCURSEL, i, 0);
570 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
571 (LPARAM)GetDlgItem(hDlg,cmb2));
572 ret = TRUE;
573 break;
576 return ret;
580 static BOOL CFn_FitCharSet( HWND hDlg, int charset )
582 int i,n,cs;
583 /* look for fitting char set in combobox5 */
584 n=SendDlgItemMessageW(hDlg, cmb5, CB_GETCOUNT, 0, 0);
585 for (i=0;i<n;i++)
587 cs =SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
588 if (charset == cs)
590 SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, i, 0);
591 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
592 (LPARAM)GetDlgItem(hDlg,cmb2));
593 return TRUE;
596 /* no charset fits: select the first one in the list */
597 SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, 0, 0);
598 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
599 (LPARAM)GetDlgItem(hDlg,cmb2));
600 return FALSE;
603 /***********************************************************************
604 * FontStyleEnumProc32 [internal]
606 static INT WINAPI FontStyleEnumProc( const ENUMLOGFONTEXW *lpElfex,
607 const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam )
609 LPCFn_ENUMSTRUCT s=(LPCFn_ENUMSTRUCT)lParam;
610 HWND hcmb2=s->hWnd1;
611 HWND hcmb3=s->hWnd2;
612 HWND hDlg=GetParent(hcmb3);
613 return AddFontStyle( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
614 dwFontType, s->lpcf32w, hcmb2, hcmb3, hDlg);
617 /***********************************************************************
618 * CFn_WMInitDialog [internal]
620 static LRESULT CFn_WMInitDialog(HWND hDlg, LPARAM lParam, LPCHOOSEFONTW lpcf)
622 HDC hdc;
623 int i,j;
624 BOOL init = FALSE;
625 long pstyle;
626 CFn_ENUMSTRUCT s;
627 LPLOGFONTW lpxx;
628 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
629 static const WCHAR strColorName[] = {'[','c','o','l','o','r',' ','n','a','m','e',']',0};
631 SetPropW(hDlg, strWineFontData, lpcf);
632 lpxx=lpcf->lpLogFont;
633 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
635 if (lpcf->lStructSize != sizeof(CHOOSEFONTW))
637 ERR("structure size failure!!!\n");
638 EndDialog (hDlg, 0);
639 return FALSE;
641 if (!himlTT)
642 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
643 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
645 /* Set effect flags */
646 if((lpcf->Flags & CF_EFFECTS) && (lpcf->Flags & CF_INITTOLOGFONTSTRUCT))
648 if(lpxx->lfUnderline)
649 CheckDlgButton(hDlg, chx2, TRUE);
650 if(lpxx->lfStrikeOut)
651 CheckDlgButton(hDlg, chx1, TRUE);
654 if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow(lpcf->hwndOwner))
655 ShowWindow(GetDlgItem(hDlg,pshHelp),SW_HIDE);
656 if (!(lpcf->Flags & CF_APPLY))
657 ShowWindow(GetDlgItem(hDlg,psh3),SW_HIDE);
658 if (lpcf->Flags & CF_NOSCRIPTSEL)
659 EnableWindow(GetDlgItem(hDlg,cmb5),FALSE);
660 if (lpcf->Flags & CF_EFFECTS)
662 for (i=0;i<TEXT_COLORS;i++)
664 WCHAR name[30];
666 if( LoadStringW(COMDLG32_hInstance, IDS_COLOR_BLACK+i, name,
667 sizeof(name)/sizeof(*name) )==0 )
669 memcpy(name, strColorName, sizeof(strColorName));
671 j=SendDlgItemMessageW(hDlg, cmb4, CB_ADDSTRING, 0, (LPARAM)name);
672 SendDlgItemMessageW(hDlg, cmb4, CB_SETITEMDATA, j, textcolors[i]);
673 /* look for a fitting value in color combobox */
674 if (textcolors[i]==lpcf->rgbColors)
675 SendDlgItemMessageW(hDlg,cmb4, CB_SETCURSEL,j,0);
678 else
680 ShowWindow(GetDlgItem(hDlg,cmb4),SW_HIDE);
681 ShowWindow(GetDlgItem(hDlg,chx1),SW_HIDE);
682 ShowWindow(GetDlgItem(hDlg,chx2),SW_HIDE);
683 ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
684 ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
686 if(!(hdc = CFn_GetDC(lpcf)))
688 EndDialog (hDlg, 0);
689 return FALSE;
691 s.hWnd1=GetDlgItem(hDlg,cmb1);
692 s.lpcf32w=lpcf;
693 do {
694 LOGFONTW elf;
695 s.added = 0;
696 elf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
697 elf.lfPitchAndFamily = 0;
698 elf.lfFaceName[0] = '\0'; /* enum all fonts */
699 if (!EnumFontFamiliesExW(hdc, &elf, (FONTENUMPROCW)FontFamilyEnumProc, (LPARAM)&s, 0))
701 TRACE("EnumFontFamiliesEx returns 0\n");
702 break;
704 if (s.added) break;
705 if (lpcf->Flags & CF_FIXEDPITCHONLY) {
706 FIXME("No font found with fixed pitch only, dropping flag.\n");
707 lpcf->Flags &= ~CF_FIXEDPITCHONLY;
708 continue;
710 if (lpcf->Flags & CF_TTONLY) {
711 FIXME("No font found with truetype only, dropping flag.\n");
712 lpcf->Flags &= ~CF_TTONLY;
713 continue;
715 break;
716 } while (1);
719 if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
721 /* look for fitting font name in combobox1 */
722 j=SendDlgItemMessageW(hDlg,cmb1,CB_FINDSTRING,-1,(LPARAM)lpxx->lfFaceName);
723 if (j!=CB_ERR)
725 INT height = lpxx->lfHeight < 0 ? -lpxx->lfHeight :
726 lpxx->lfHeight;
727 INT points;
728 int charset = lpxx->lfCharSet;
729 points = MulDiv( height, 72, GetScreenDPI());
730 pstyle = MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD:
731 FW_NORMAL,lpxx->lfItalic !=0);
732 SendDlgItemMessageW(hDlg, cmb1, CB_SETCURSEL, j, 0);
733 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
734 (LPARAM)GetDlgItem(hDlg,cmb1));
735 init = TRUE;
736 /* look for fitting font style in combobox2 */
737 CFn_FitFontStyle(hDlg, pstyle);
738 /* look for fitting font size in combobox3 */
739 CFn_FitFontSize(hDlg, points);
740 CFn_FitCharSet( hDlg, charset );
743 if (!init)
745 SendDlgItemMessageW(hDlg,cmb1,CB_SETCURSEL,0,0);
746 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
747 (LPARAM)GetDlgItem(hDlg,cmb1));
748 SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,0,0);
749 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
750 (LPARAM)GetDlgItem(hDlg,cmb1));
751 SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,0,0);
752 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb3, CBN_SELCHANGE),
753 (LPARAM)GetDlgItem(hDlg,cmb3));
754 SendDlgItemMessageW(hDlg,cmb5,CB_SETCURSEL,0,0);
755 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
756 (LPARAM)GetDlgItem(hDlg,cmb5));
758 /* limit text length user can type in as font size */
759 SendDlgItemMessageW(hDlg, cmb3, CB_LIMITTEXT, 5, 0);
761 if ((lpcf->Flags & CF_USESTYLE) && lpcf->lpszStyle)
763 j=SendDlgItemMessageW(hDlg,cmb2,CB_FINDSTRING,-1,(LPARAM)lpcf->lpszStyle);
764 if (j!=CB_ERR)
766 j=SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,j,0);
767 SendMessageW(hDlg,WM_COMMAND,cmb2,
768 MAKELONG(LOWORD(GetDlgItem(hDlg,cmb2)),CBN_SELCHANGE));
771 CFn_ReleaseDC(lpcf, hdc);
772 SetCursor(hcursor);
773 return TRUE;
777 /***********************************************************************
778 * CFn_WMMeasureItem [internal]
780 static LRESULT CFn_WMMeasureItem(HWND hDlg, LPARAM lParam)
782 HDC hdc;
783 HFONT hfontprev;
784 TEXTMETRICW tm;
785 LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam;
786 INT height = 0, cx;
788 if (!himlTT)
789 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
790 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
791 ImageList_GetIconSize( himlTT, &cx, &height);
792 lpmi->itemHeight = height + 2;
793 /* use MAX of bitmap height and tm.tmHeight .*/
794 hdc=GetDC(hDlg);
795 if(!hdc) return 0;
796 hfontprev = SelectObject( hdc, (HFONT)SendMessageW( hDlg, WM_GETFONT, 0, 0 ));
797 GetTextMetricsW(hdc, &tm);
798 if( tm.tmHeight > lpmi->itemHeight) lpmi->itemHeight = tm.tmHeight;
799 SelectObject(hdc, hfontprev);
800 ReleaseDC(hDlg, hdc);
801 return 0;
805 /***********************************************************************
806 * CFn_WMDrawItem [internal]
808 static LRESULT CFn_WMDrawItem(LPARAM lParam)
810 HBRUSH hBrush;
811 WCHAR buffer[40];
812 COLORREF cr, oldText=0, oldBk=0;
813 RECT rect;
814 int nFontType;
815 int cx, cy, idx;
816 LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam;
818 if (lpdi->itemID == (UINT)-1) /* got no items */
819 DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
820 else
822 if (lpdi->CtlType == ODT_COMBOBOX)
824 if (lpdi->itemState & ODS_SELECTED)
826 hBrush=GetSysColorBrush(COLOR_HIGHLIGHT);
827 oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
828 oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT));
829 } else
831 hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
832 SelectObject(lpdi->hDC, hBrush);
834 FillRect(lpdi->hDC, &lpdi->rcItem, hBrush);
836 else
837 return TRUE; /* this should never happen */
839 rect=lpdi->rcItem;
840 switch (lpdi->CtlID)
842 case cmb1:
843 /* TRACE(commdlg,"WM_Drawitem cmb1\n"); */
844 ImageList_GetIconSize( himlTT, &cx, &cy);
845 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
846 (LPARAM)buffer);
847 TextOutW(lpdi->hDC, lpdi->rcItem.left + cx + 4,
848 lpdi->rcItem.top, buffer, lstrlenW(buffer));
849 nFontType = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
850 idx = -1;
851 if (nFontType & TRUETYPE_FONTTYPE) {
852 idx = 0; /* picture: TT */
853 if( nFontType & NTM_TT_OPENTYPE)
854 idx = 2; /* picture: O */
855 } else if( nFontType & NTM_PS_OPENTYPE)
856 idx = 3; /* picture: O+ps */
857 else if( nFontType & NTM_TYPE1)
858 idx = 4; /* picture: a */
859 else if( nFontType & DEVICE_FONTTYPE)
860 idx = 1; /* picture: printer */
861 if( idx >= 0)
862 ImageList_Draw( himlTT, idx, lpdi->hDC, lpdi->rcItem.left,
863 (lpdi->rcItem.top + lpdi->rcItem.bottom - cy) / 2, ILD_TRANSPARENT);
864 break;
865 case cmb2:
866 case cmb3:
867 /* TRACE(commdlg,"WM_DRAWITEN cmb2,cmb3\n"); */
868 case cmb5:
869 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
870 (LPARAM)buffer);
871 TextOutW(lpdi->hDC, lpdi->rcItem.left,
872 lpdi->rcItem.top, buffer, lstrlenW(buffer));
873 break;
875 case cmb4:
876 /* TRACE(commdlg,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
877 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
878 (LPARAM)buffer);
879 TextOutW(lpdi->hDC, lpdi->rcItem.left + 25+5,
880 lpdi->rcItem.top, buffer, lstrlenW(buffer));
881 cr = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
882 hBrush = CreateSolidBrush(cr);
883 if (hBrush)
885 hBrush = SelectObject (lpdi->hDC, hBrush) ;
886 rect.right=rect.left+25;
887 rect.top++;
888 rect.left+=5;
889 rect.bottom--;
890 Rectangle( lpdi->hDC, rect.left, rect.top,
891 rect.right, rect.bottom );
892 DeleteObject( SelectObject (lpdi->hDC, hBrush)) ;
894 rect=lpdi->rcItem;
895 rect.left+=25+5;
896 break;
898 default:
899 return TRUE; /* this should never happen */
901 if (lpdi->itemState & ODS_SELECTED)
903 SetTextColor(lpdi->hDC, oldText);
904 SetBkColor(lpdi->hDC, oldBk);
907 return TRUE;
910 static INT get_dialog_font_point_size(HWND hDlg, CHOOSEFONTW *cf)
912 BOOL invalid_size = FALSE;
913 INT i, size;
915 i = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
916 if (i != CB_ERR)
917 size = LOWORD(SendDlgItemMessageW(hDlg, cmb3, CB_GETITEMDATA , i, 0));
918 else
920 WCHAR buffW[8], *endptrW;
922 GetDlgItemTextW(hDlg, cmb3, buffW, sizeof(buffW)/sizeof(*buffW));
923 size = strtolW(buffW, &endptrW, 10);
924 invalid_size = size == 0 && *endptrW;
926 if (size == 0)
927 size = 10;
930 cf->iPointSize = 10 * size;
931 cf->lpLogFont->lfHeight = -MulDiv(cf->iPointSize, GetScreenDPI(), 720);
932 return invalid_size ? -1 : size;
935 /***********************************************************************
936 * CFn_WMCommand [internal]
938 static LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcf)
940 int i;
941 long l;
942 HDC hdc;
944 if (!lpcf) return FALSE;
946 TRACE("WM_COMMAND wParam=%08X lParam=%08lX\n", (LONG)wParam, lParam);
947 switch (LOWORD(wParam))
949 case cmb1:
950 if (HIWORD(wParam)==CBN_SELCHANGE)
952 INT pointsize; /* save current pointsize */
953 LONG pstyle; /* save current style */
954 int charset;
955 int idx;
956 if(!(hdc = CFn_GetDC(lpcf)))
958 EndDialog (hDlg, 0);
959 return TRUE;
961 idx = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
962 pointsize = (int)SendDlgItemMessageW( hDlg, cmb3, CB_GETITEMDATA,
963 idx, 0);
964 idx = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
965 pstyle = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, idx, 0);
966 idx = SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
967 charset = SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, idx, 0);
969 SendDlgItemMessageW(hDlg, cmb2, CB_RESETCONTENT, 0, 0);
970 SendDlgItemMessageW(hDlg, cmb3, CB_RESETCONTENT, 0, 0);
971 SendDlgItemMessageW(hDlg, cmb5, CB_RESETCONTENT, 0, 0);
972 i=SendDlgItemMessageW(hDlg, cmb1, CB_GETCURSEL, 0, 0);
973 if (i!=CB_ERR)
975 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
976 CFn_ENUMSTRUCT s;
977 LOGFONTW enumlf;
978 SendDlgItemMessageW(hDlg, cmb1, CB_GETLBTEXT, i,
979 (LPARAM)enumlf.lfFaceName);
980 TRACE("WM_COMMAND/cmb1 =>%s\n", debugstr_w(enumlf.lfFaceName));
981 s.hWnd1=GetDlgItem(hDlg, cmb2);
982 s.hWnd2=GetDlgItem(hDlg, cmb3);
983 s.lpcf32w=lpcf;
984 enumlf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
985 enumlf.lfPitchAndFamily = 0;
986 EnumFontFamiliesExW(hdc, &enumlf,
987 (FONTENUMPROCW)FontStyleEnumProc, (LPARAM)&s, 0);
988 CFn_FitFontStyle(hDlg, pstyle);
989 if( pointsize != CB_ERR) CFn_FitFontSize(hDlg, pointsize);
990 if( charset != CB_ERR) CFn_FitCharSet( hDlg, charset );
991 SetCursor(hcursor);
993 CFn_ReleaseDC(lpcf, hdc);
995 break;
996 case chx1:
997 case chx2:
998 case cmb2:
999 case cmb3:
1000 case cmb5:
1001 if (HIWORD(wParam)==CBN_SELCHANGE || HIWORD(wParam)== BN_CLICKED )
1003 WCHAR str[256];
1004 WINDOWINFO wininfo;
1005 LPLOGFONTW lpxx=lpcf->lpLogFont;
1007 TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
1009 /* face name */
1010 i=SendDlgItemMessageW(hDlg,cmb1,CB_GETCURSEL,0,0);
1011 if (i==CB_ERR)
1012 GetDlgItemTextW( hDlg, cmb1, str, sizeof(str)/sizeof(str[0]) );
1013 else
1015 SendDlgItemMessageW(hDlg,cmb1,CB_GETLBTEXT,i,
1016 (LPARAM)str);
1017 l=SendDlgItemMessageW(hDlg,cmb1,CB_GETITEMDATA,i,0);
1018 lpcf->nFontType = LOWORD(l);
1019 /* FIXME: lpcf->nFontType |= .... SIMULATED_FONTTYPE and so */
1020 /* same value reported to the EnumFonts
1021 call back with the extra FONTTYPE_... bits added */
1022 lpxx->lfPitchAndFamily = HIWORD(l) >> 8;
1024 lstrcpynW(lpxx->lfFaceName, str, sizeof(lpxx->lfFaceName)/sizeof(lpxx->lfFaceName[0]));
1026 /* style */
1027 i=SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
1028 if (i!=CB_ERR)
1030 l=SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
1031 if (0!=(lpxx->lfItalic=HIWORD(l)))
1032 lpcf->nFontType |= ITALIC_FONTTYPE;
1033 if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
1034 lpcf->nFontType |= BOLD_FONTTYPE;
1037 /* size */
1038 get_dialog_font_point_size(hDlg, lpcf);
1040 /* charset */
1041 i=SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
1042 if (i!=CB_ERR)
1043 lpxx->lfCharSet=SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
1044 else
1045 lpxx->lfCharSet = DEFAULT_CHARSET;
1046 lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
1047 lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
1048 lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
1049 lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
1050 lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
1051 lpxx->lfQuality=DEFAULT_QUALITY;
1053 wininfo.cbSize=sizeof(wininfo);
1055 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1057 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1058 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1061 break;
1063 case cmb4:
1064 i=SendDlgItemMessageW(hDlg, cmb4, CB_GETCURSEL, 0, 0);
1065 if (i!=CB_ERR)
1067 WINDOWINFO wininfo;
1069 lpcf->rgbColors = SendDlgItemMessageW(hDlg, cmb4, CB_GETITEMDATA, i, 0);
1070 wininfo.cbSize=sizeof(wininfo);
1072 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1074 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1075 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1078 break;
1080 case psh15:
1081 i=RegisterWindowMessageW( HELPMSGSTRINGW );
1082 if (lpcf->hwndOwner)
1083 SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData));
1084 break;
1086 case IDOK:
1088 WCHAR msgW[80];
1089 INT pointsize;
1091 pointsize = get_dialog_font_point_size(hDlg, lpcf);
1092 if (pointsize == -1)
1094 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE_INPUT, msgW, sizeof(msgW)/sizeof(*msgW));
1095 MessageBoxW(hDlg, msgW, NULL, MB_OK | MB_ICONINFORMATION);
1096 return TRUE;
1099 if ( (!(lpcf->Flags & CF_LIMITSIZE)) ||
1100 ( (lpcf->Flags & CF_LIMITSIZE) &&
1101 (lpcf->iPointSize >= 10 * lpcf->nSizeMin) &&
1102 (lpcf->iPointSize <= 10 * lpcf->nSizeMax)))
1103 EndDialog(hDlg, TRUE);
1104 else
1106 WCHAR format[80];
1107 DWORD_PTR args[2];
1108 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE, format, sizeof(format)/sizeof(WCHAR));
1109 args[0] = lpcf->nSizeMin;
1110 args[1] = lpcf->nSizeMax;
1111 FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
1112 format, 0, 0, msgW, sizeof(msgW)/sizeof(*msgW),
1113 (__ms_va_list*)args);
1114 MessageBoxW(hDlg, msgW, NULL, MB_OK);
1116 return(TRUE);
1118 case IDCANCEL:
1119 EndDialog(hDlg, FALSE);
1120 return(TRUE);
1122 return(FALSE);
1125 static LRESULT CFn_WMDestroy(HWND hwnd, LPCHOOSEFONTW lpcfw)
1127 LPCHOOSEFONTA lpcfa;
1128 LPSTR lpszStyle;
1129 LPLOGFONTA lpLogFonta;
1130 int len;
1132 if (!lpcfw) return FALSE;
1134 lpcfa = GetPropW(hwnd, strWineFontData_a);
1135 lpLogFonta = lpcfa->lpLogFont;
1136 lpszStyle = lpcfa->lpszStyle;
1137 memcpy(lpcfa, lpcfw, sizeof(CHOOSEFONTA));
1138 lpcfa->lpLogFont = lpLogFonta;
1139 lpcfa->lpszStyle = lpszStyle;
1140 memcpy(lpcfa->lpLogFont, lpcfw->lpLogFont, sizeof(LOGFONTA));
1141 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName,
1142 LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0);
1144 if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) {
1145 len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, 0, 0, 0);
1146 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0);
1147 HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle);
1150 HeapFree(GetProcessHeap(), 0, lpcfw->lpLogFont);
1151 HeapFree(GetProcessHeap(), 0, lpcfw);
1152 SetPropW(hwnd, strWineFontData, 0);
1154 return TRUE;
1157 static LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW *lpcf)
1159 WINDOWINFO info;
1161 if (!lpcf) return FALSE;
1163 info.cbSize=sizeof(info);
1164 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &info ) )
1166 PAINTSTRUCT ps;
1167 HDC hdc;
1168 HFONT hOrigFont;
1169 LOGFONTW lf = *(lpcf->lpLogFont);
1171 MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2);
1172 hdc = BeginPaint( hDlg, &ps );
1174 TRACE("erase %d, rect=%s\n", ps.fErase, wine_dbgstr_rect(&ps.rcPaint));
1176 /* Paint frame */
1177 DrawEdge( hdc, &info.rcWindow, EDGE_SUNKEN, BF_RECT|BF_ADJUST );
1179 /* Draw the sample text itself */
1180 hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
1181 SetTextColor( hdc, lpcf->rgbColors );
1183 DrawTextW( hdc,
1184 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]],
1185 -1, &info.rcWindow, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
1187 DeleteObject(SelectObject( hdc, hOrigFont ));
1188 EndPaint( hDlg, &ps );
1190 return FALSE;
1193 /***********************************************************************
1194 * FormatCharDlgProcA [internal]
1196 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1198 LPCHOOSEFONTW lpcfw;
1199 LPCHOOSEFONTA lpcfa;
1200 INT_PTR res = FALSE;
1201 int len;
1203 if (uMsg!=WM_INITDIALOG) {
1204 lpcfw = GetPropW(hDlg, strWineFontData);
1205 if (lpcfw && CFn_HookCallChk32(lpcfw))
1206 res=CallWindowProcA((WNDPROC)lpcfw->lpfnHook, hDlg, uMsg, wParam, lParam);
1207 if (res)
1208 return res;
1209 } else {
1210 lpcfa=(LPCHOOSEFONTA)lParam;
1211 SetPropW(hDlg, strWineFontData_a, (HANDLE)lParam);
1213 lpcfw = HeapAlloc(GetProcessHeap(), 0, sizeof(CHOOSEFONTW));
1214 memcpy(lpcfw, lpcfa, sizeof(CHOOSEFONTA));
1215 lpcfw->lpLogFont = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGFONTW));
1216 memcpy(lpcfw->lpLogFont, lpcfa->lpLogFont, sizeof(LOGFONTA));
1217 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpLogFont->lfFaceName,
1218 LF_FACESIZE, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE);
1220 if((lpcfa->Flags & CF_USESTYLE) && lpcfa->lpszStyle) {
1221 len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, NULL, 0);
1222 lpcfw->lpszStyle = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
1223 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len);
1226 if (!CFn_WMInitDialog(hDlg, lParam, lpcfw))
1228 TRACE("CFn_WMInitDialog returned FALSE\n");
1229 return FALSE;
1231 if (CFn_HookCallChk32(lpcfw))
1232 return CallWindowProcA((WNDPROC)lpcfa->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1234 switch (uMsg)
1236 case WM_MEASUREITEM:
1237 return CFn_WMMeasureItem(hDlg,lParam);
1238 case WM_DRAWITEM:
1239 return CFn_WMDrawItem(lParam);
1240 case WM_COMMAND:
1241 return CFn_WMCommand(hDlg, wParam, lParam, lpcfw);
1242 case WM_DESTROY:
1243 return CFn_WMDestroy(hDlg, lpcfw);
1244 case WM_CHOOSEFONT_GETLOGFONT:
1246 LOGFONTA *logfont = (LOGFONTA *)lParam;
1247 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1248 memcpy( logfont, lpcfw->lpLogFont, FIELD_OFFSET( LOGFONTA, lfFaceName ));
1249 WideCharToMultiByte( CP_ACP, 0, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE,
1250 logfont->lfFaceName, LF_FACESIZE, NULL, NULL );
1251 break;
1253 case WM_PAINT:
1254 return CFn_WMPaint(hDlg, wParam, lParam, lpcfw);
1256 return res;
1259 /***********************************************************************
1260 * FormatCharDlgProcW [internal]
1262 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1264 LPCHOOSEFONTW lpcf;
1265 INT_PTR res = FALSE;
1267 if (uMsg!=WM_INITDIALOG)
1269 lpcf= GetPropW(hDlg, strWineFontData);
1270 if (lpcf && CFn_HookCallChk32(lpcf))
1271 res=CallWindowProcW((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam);
1272 if (res)
1273 return res;
1275 else
1277 lpcf=(LPCHOOSEFONTW)lParam;
1278 if (!CFn_WMInitDialog(hDlg, lParam, lpcf))
1280 TRACE("CFn_WMInitDialog returned FALSE\n");
1281 return FALSE;
1283 if (CFn_HookCallChk32(lpcf))
1284 return CallWindowProcW((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1286 switch (uMsg)
1288 case WM_MEASUREITEM:
1289 return CFn_WMMeasureItem(hDlg, lParam);
1290 case WM_DRAWITEM:
1291 return CFn_WMDrawItem(lParam);
1292 case WM_COMMAND:
1293 return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
1294 case WM_DESTROY:
1295 return TRUE;
1296 case WM_CHOOSEFONT_GETLOGFONT:
1297 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1298 memcpy( (LOGFONTW *)lParam, lpcf->lpLogFont, sizeof(LOGFONTW) );
1299 break;
1300 case WM_PAINT:
1301 return CFn_WMPaint(hDlg, wParam, lParam, lpcf);
1303 return res;