comdlg32/fontdlg: Allow font sizes outside of defaults set.
[wine/multimedia.git] / dlls / comdlg32 / fontdlg.c
blob245f15015f3a7f538b7598491166f07030bb2450
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};
55 /* image list with TrueType bitmaps and more */
56 static HIMAGELIST himlTT = 0;
57 #define TTBITMAP_XSIZE 20 /* x-size of the bitmaps */
59 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
60 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
62 /* There is a table here of all charsets, and the sample text for each.
63 * There is a second table that translates a charset into an index into
64 * the first table.
67 #define CI(cs) ((IDS_CHARSET_##cs)-IDS_CHARSET_ANSI)
70 static const WCHAR stWestern[]={'A','a','B','b','Y','y','Z','z',0}; /* Western and default */
71 static const WCHAR stSymbol[]={'S','y','m','b','o','l',0}; /* Symbol */
72 static const WCHAR stShiftJis[]={'A','a',0x3042,0x3041,0x30a2,0x30a1,0x4e9c,0x5b87,0}; /* Shift JIS */
73 static const WCHAR stHangul[]={0xac00,0xb098,0xb2e4,'A','a','B','Y','y','Z','z',0}; /* Hangul */
74 static const WCHAR stGB2312[]={0x5fae,0x8f6f,0x4e2d,0x6587,0x8f6f,0x4ef6,0}; /* GB2312 */
75 static const WCHAR stBIG5[]={0x4e2d,0x6587,0x5b57,0x578b,0x7bc4,0x4f8b,0}; /* BIG5 */
76 static const WCHAR stGreek[]={'A','a','B','b',0x0391,0x03b1,0x0392,0x03b2,0}; /* Greek */
77 static const WCHAR stTurkish[]={'A','a','B','b',0x011e,0x011f,0x015e,0x015f,0}; /* Turkish */
78 static const WCHAR stHebrew[]={'A','a','B','b',0x05e0,0x05e1,0x05e9,0x05ea,0}; /* Hebrew */
79 static const WCHAR stArabic[]={'A','a','B','b',0x0627,0x0628,0x062c,0x062f,0x0647,0x0648,0x0632,0};/* Arabic */
80 static const WCHAR stBaltic[]={'A','a','B','b','Y','y','Z','z',0}; /* Baltic */
81 static const WCHAR stVietname[]={'A','a','B','b',0x01a0,0x01a1,0x01af,0x01b0,0}; /* Vietnamese */
82 static const WCHAR stCyrillic[]={'A','a','B','b',0x0411,0x0431,0x0424,0x0444,0}; /* Cyrillic */
83 static const WCHAR stEastEur[]={'A','a','B','b',0xc1,0xe1,0xd4,0xf4,0}; /* East European */
84 static const WCHAR stThai[]={'A','a','B','b',0x0e2d,0x0e31,0x0e01,0x0e29,0x0e23,0x0e44,0x0e17,0x0e22,0}; /* Thai */
85 static const WCHAR stJohab[]={0xac00,0xb098,0xb2e4,'A','a','B','Y','y','Z','z',0}; /* Johab */
86 static const WCHAR stMac[]={'A','a','B','b','Y','y','Z','z',0}; /* Mac */
87 static const WCHAR stOEM[]={'A','a','B','b',0xf8,0xf1,0xfd,0}; /* OEM */
88 /* the following character sets actually behave different (Win2K observation):
89 * the sample string is 'sticky': it uses the sample string of the previous
90 * selected character set. That behaviour looks like some default, which is
91 * not (yet) implemented. */
92 static const WCHAR stVISCII[]={'A','a','B','b',0}; /* VISCII */
93 static const WCHAR stTCVN[]={'A','a','B','b',0}; /* TCVN */
94 static const WCHAR stKOI8[]={'A','a','B','b',0}; /* KOI-8 */
95 static const WCHAR stIso88593[]={'A','a','B','b',0}; /* ISO-8859-3 */
96 static const WCHAR stIso88594[]={'A','a','B','b',0}; /* ISO-8859-4 */
97 static const WCHAR stIso885910[]={'A','a','B','b',0}; /* ISO-8859-10 */
98 static const WCHAR stCeltic[]={'A','a','B','b',0};/* Celtic */
100 static const WCHAR * const sample_lang_text[]={
101 stWestern,stSymbol,stShiftJis,stHangul,stGB2312,
102 stBIG5,stGreek,stTurkish,stHebrew,stArabic,
103 stBaltic,stVietname,stCyrillic,stEastEur,stThai,
104 stJohab,stMac,stOEM,stVISCII,stTCVN,
105 stKOI8,stIso88593,stIso88594,stIso885910,stCeltic};
108 static const BYTE CHARSET_ORDER[256]={
109 CI(ANSI), 0, CI(SYMBOL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 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, CI(MAC), 0, 0,
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 CI(JIS), CI(HANGUL), CI(JOHAB), 0, 0, 0, CI(GB2312), 0, CI(BIG5), 0, 0, 0, 0, 0, 0, 0,
118 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
119 0, CI(GREEK), CI(TURKISH), CI(VIETNAMESE), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
120 0, CI(HEBREW), CI(ARABIC), 0, 0, 0, 0, 0, 0, 0, CI(BALTIC), 0, 0, 0, 0, 0,
121 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(RUSSIAN), 0, 0, 0,
122 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(THAI), 0,
123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(EE), 0,
124 CI(VISCII), CI(TCVN), CI(KOI8), CI(ISO3), CI(ISO4), CI(ISO10), CI(CELTIC), 0, 0, 0, 0, 0, 0, 0, 0, CI(OEM),
127 static const struct {
128 DWORD mask;
129 const char *name;
130 } cfflags[] = {
131 #define XX(x) { x, #x },
132 XX(CF_SCREENFONTS)
133 XX(CF_PRINTERFONTS)
134 XX(CF_SHOWHELP)
135 XX(CF_ENABLEHOOK)
136 XX(CF_ENABLETEMPLATE)
137 XX(CF_ENABLETEMPLATEHANDLE)
138 XX(CF_INITTOLOGFONTSTRUCT)
139 XX(CF_USESTYLE)
140 XX(CF_EFFECTS)
141 XX(CF_APPLY)
142 XX(CF_ANSIONLY)
143 XX(CF_NOVECTORFONTS)
144 XX(CF_NOSIMULATIONS)
145 XX(CF_LIMITSIZE)
146 XX(CF_FIXEDPITCHONLY)
147 XX(CF_WYSIWYG)
148 XX(CF_FORCEFONTEXIST)
149 XX(CF_SCALABLEONLY)
150 XX(CF_TTONLY)
151 XX(CF_NOFACESEL)
152 XX(CF_NOSTYLESEL)
153 XX(CF_NOSIZESEL)
154 XX(CF_SELECTSCRIPT)
155 XX(CF_NOSCRIPTSEL)
156 XX(CF_NOVERTFONTS)
157 #undef XX
160 static void _dump_cf_flags(DWORD cflags)
162 unsigned int i;
164 for (i = 0; i < sizeof(cfflags)/sizeof(cfflags[0]); i++)
165 if (cfflags[i].mask & cflags)
166 TRACE("%s|",cfflags[i].name);
167 TRACE("\n");
170 /***********************************************************************
171 * ChooseFontW (COMDLG32.@)
173 * Create a font dialog box.
175 * PARAMS
176 * lpChFont [I/O] in: information to initialize the dialog box.
177 * out: User's color selection
179 * RETURNS
180 * TRUE: Ok button clicked.
181 * FALSE: Cancel button clicked, or error.
183 BOOL WINAPI ChooseFontW(LPCHOOSEFONTW lpChFont)
185 LPCVOID template;
186 HRSRC hResInfo;
187 HINSTANCE hDlginst;
188 HGLOBAL hDlgTmpl;
190 TRACE("(%p)\n", lpChFont);
192 if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 )
194 template=lpChFont->hInstance;
195 } else
197 if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 )
199 hDlginst=lpChFont->hInstance;
200 if( !(hResInfo = FindResourceW(hDlginst, lpChFont->lpTemplateName,
201 (LPWSTR)RT_DIALOG)))
203 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
204 return FALSE;
206 } else
208 hDlginst=COMDLG32_hInstance;
209 if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG)))
211 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
212 return FALSE;
215 if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) ||
216 !(template = LockResource( hDlgTmpl )))
218 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
219 return FALSE;
222 if (TRACE_ON(commdlg))
223 _dump_cf_flags(lpChFont->Flags);
225 if (lpChFont->Flags & CF_SELECTSCRIPT)
226 FIXME(": unimplemented flag (ignored)\n");
228 return DialogBoxIndirectParamW(COMDLG32_hInstance, template,
229 lpChFont->hwndOwner, FormatCharDlgProcW, (LPARAM)lpChFont );
232 /***********************************************************************
233 * ChooseFontA (COMDLG32.@)
235 * See ChooseFontW.
237 BOOL WINAPI ChooseFontA(LPCHOOSEFONTA lpChFont)
239 LPCVOID template;
240 HRSRC hResInfo;
241 HINSTANCE hDlginst;
242 HGLOBAL hDlgTmpl;
244 TRACE("(%p)\n", lpChFont);
246 if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 )
248 template=lpChFont->hInstance;
249 } else
251 if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 )
253 hDlginst=lpChFont->hInstance;
254 if( !(hResInfo = FindResourceA(hDlginst, lpChFont->lpTemplateName,
255 (LPSTR)RT_DIALOG)))
257 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
258 return FALSE;
260 } else
262 hDlginst=COMDLG32_hInstance;
263 if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG)))
265 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
266 return FALSE;
269 if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) ||
270 !(template = LockResource( hDlgTmpl )))
272 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
273 return FALSE;
276 if (TRACE_ON(commdlg))
277 _dump_cf_flags(lpChFont->Flags);
278 if (lpChFont->Flags & CF_SELECTSCRIPT)
279 FIXME(": unimplemented flag (ignored)\n");
281 return DialogBoxIndirectParamA(COMDLG32_hInstance, template,
282 lpChFont->hwndOwner, FormatCharDlgProcA, (LPARAM)lpChFont );
285 #define TEXT_EXTRAS 4
286 #define TEXT_COLORS 16
288 static const COLORREF textcolors[TEXT_COLORS]=
290 0x00000000L,0x00000080L,0x00008000L,0x00008080L,
291 0x00800000L,0x00800080L,0x00808000L,0x00808080L,
292 0x00c0c0c0L,0x000000ffL,0x0000ff00L,0x0000ffffL,
293 0x00ff0000L,0x00ff00ffL,0x00ffff00L,0x00FFFFFFL
296 /***********************************************************************
297 * CFn_HookCallChk32 [internal]
299 static BOOL CFn_HookCallChk32(const CHOOSEFONTW *lpcf)
301 if (lpcf)
302 if(lpcf->Flags & CF_ENABLEHOOK)
303 if (lpcf->lpfnHook)
304 return TRUE;
305 return FALSE;
308 /*************************************************************************
309 * AddFontFamily [internal]
311 static INT AddFontFamily(const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM,
312 UINT nFontType, const CHOOSEFONTW *lpcf, HWND hwnd, LPCFn_ENUMSTRUCT e)
314 int i;
315 WORD w;
316 const LOGFONTW *lplf = &(lpElfex->elfLogFont);
318 TRACE("font=%s (nFontType=%d)\n", debugstr_w(lplf->lfFaceName), nFontType);
320 if (lpcf->Flags & CF_FIXEDPITCHONLY)
321 if (!(lplf->lfPitchAndFamily & FIXED_PITCH))
322 return 1;
323 if (lpcf->Flags & CF_ANSIONLY)
324 if (lplf->lfCharSet != ANSI_CHARSET)
325 return 1;
326 if (lpcf->Flags & CF_TTONLY)
327 if (!(nFontType & TRUETYPE_FONTTYPE))
328 return 1;
329 if (lpcf->Flags & CF_NOVERTFONTS)
330 if (lplf->lfFaceName[0] == '@')
331 return 1;
333 if (e) e->added++;
335 i=SendMessageW(hwnd, CB_FINDSTRINGEXACT, 0, (LPARAM)lplf->lfFaceName);
336 if (i == CB_ERR) {
337 i = SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)lplf->lfFaceName);
338 if( i != CB_ERR) {
339 /* store some important font information */
340 w = (lplf->lfPitchAndFamily) << 8 |
341 (HIWORD(lpNTM->ntmTm.ntmFlags) & 0xff);
342 SendMessageW(hwnd, CB_SETITEMDATA, i, MAKELONG(nFontType,w));
345 return 1;
348 /*************************************************************************
349 * FontFamilyEnumProc32 [internal]
351 static INT WINAPI FontFamilyEnumProc(const ENUMLOGFONTEXW *lpElfex,
352 const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam)
354 LPCFn_ENUMSTRUCT e;
355 e=(LPCFn_ENUMSTRUCT)lParam;
356 return AddFontFamily( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
357 dwFontType, e->lpcf32w, e->hWnd1, e);
360 /*************************************************************************
361 * SetFontStylesToCombo2 [internal]
363 * Fill font style information into combobox (without using font.c directly)
365 static BOOL SetFontStylesToCombo2(HWND hwnd, HDC hdc, const LOGFONTW *lplf)
367 #define FSTYLES 4
368 struct FONTSTYLE
370 int italic;
371 int weight;
372 UINT resId;
374 static const struct FONTSTYLE fontstyles[FSTYLES]={
375 { 0, FW_NORMAL, IDS_FONT_REGULAR },
376 { 1, FW_NORMAL, IDS_FONT_ITALIC },
377 { 0, FW_BOLD, IDS_FONT_BOLD },
378 { 1, FW_BOLD, IDS_FONT_BOLD_ITALIC }
380 HFONT hf;
381 TEXTMETRICW tm;
382 int i,j;
383 LOGFONTW lf;
385 lf = *lplf;
387 for (i=0;i<FSTYLES;i++)
389 lf.lfItalic=fontstyles[i].italic;
390 lf.lfWeight=fontstyles[i].weight;
391 hf=CreateFontIndirectW(&lf);
392 hf=SelectObject(hdc,hf);
393 GetTextMetricsW(hdc,&tm);
394 hf=SelectObject(hdc,hf);
395 DeleteObject(hf);
396 /* font successful created ? */
397 if (((fontstyles[i].weight == FW_NORMAL && tm.tmWeight <= FW_MEDIUM) ||
398 (fontstyles[i].weight == FW_BOLD && tm.tmWeight > FW_MEDIUM)) &&
399 ((tm.tmItalic != 0)==fontstyles[i].italic))
401 WCHAR name[64];
402 LoadStringW(COMDLG32_hInstance, fontstyles[i].resId, name, 64);
403 j=SendMessageW(hwnd,CB_ADDSTRING,0,(LPARAM)name );
404 if (j==CB_ERR) return TRUE;
405 j=SendMessageW(hwnd, CB_SETITEMDATA, j,
406 MAKELONG(tm.tmWeight,fontstyles[i].italic));
407 if (j==CB_ERR) return TRUE;
410 return FALSE;
413 /*************************************************************************
414 * AddFontSizeToCombo3 [internal]
416 static BOOL AddFontSizeToCombo3(HWND hwnd, UINT h, const CHOOSEFONTW *lpcf)
418 int j;
419 WCHAR buffer[20];
420 static const WCHAR strFormat[] = {'%','2','d',0};
422 if ( (!(lpcf->Flags & CF_LIMITSIZE)) ||
423 ((lpcf->Flags & CF_LIMITSIZE) && (h >= lpcf->nSizeMin) && (h <= lpcf->nSizeMax)))
425 wsprintfW(buffer, strFormat, h);
426 j=SendMessageW(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)buffer);
427 if (j==CB_ERR)
429 j=SendMessageW(hwnd, CB_ADDSTRING, 0, (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 static const WCHAR fmtW[] = {'%','d',0};
538 WCHAR buffW[16];
539 int i,n;
541 /* look for fitting font size in combobox3 */
542 n=SendDlgItemMessageW(hDlg, cmb3, CB_GETCOUNT, 0, 0);
543 for (i=0;i<n;i++)
545 if (points == (int)SendDlgItemMessageW
546 (hDlg,cmb3, CB_GETITEMDATA,i,0))
548 SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,i,0);
549 SendMessageW(hDlg, WM_COMMAND,
550 MAKEWPARAM(cmb3, CBN_SELCHANGE),
551 (LPARAM)GetDlgItem(hDlg,cmb3));
552 return;
556 /* no default matching size, set text manually */
557 sprintfW(buffW, fmtW, points);
558 SetDlgItemTextW(hDlg, cmb3, buffW);
561 static BOOL CFn_FitFontStyle( HWND hDlg, LONG packedstyle )
563 LONG id;
564 int i;
565 BOOL ret = FALSE;
566 /* look for fitting font style in combobox2 */
567 for (i=0;i<TEXT_EXTRAS;i++)
569 id = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
570 if (packedstyle == id)
572 SendDlgItemMessageW(hDlg, cmb2, CB_SETCURSEL, i, 0);
573 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
574 (LPARAM)GetDlgItem(hDlg,cmb2));
575 ret = TRUE;
576 break;
579 return ret;
583 static BOOL CFn_FitCharSet( HWND hDlg, int charset )
585 int i,n,cs;
586 /* look for fitting char set in combobox5 */
587 n=SendDlgItemMessageW(hDlg, cmb5, CB_GETCOUNT, 0, 0);
588 for (i=0;i<n;i++)
590 cs =SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
591 if (charset == cs)
593 SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, i, 0);
594 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
595 (LPARAM)GetDlgItem(hDlg,cmb2));
596 return TRUE;
599 /* no charset fits: select the first one in the list */
600 SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, 0, 0);
601 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
602 (LPARAM)GetDlgItem(hDlg,cmb2));
603 return FALSE;
606 /***********************************************************************
607 * FontStyleEnumProc32 [internal]
609 static INT WINAPI FontStyleEnumProc( const ENUMLOGFONTEXW *lpElfex,
610 const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam )
612 LPCFn_ENUMSTRUCT s=(LPCFn_ENUMSTRUCT)lParam;
613 HWND hcmb2=s->hWnd1;
614 HWND hcmb3=s->hWnd2;
615 HWND hDlg=GetParent(hcmb3);
616 return AddFontStyle( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
617 dwFontType, s->lpcf32w, hcmb2, hcmb3, hDlg);
620 /***********************************************************************
621 * CFn_WMInitDialog [internal]
623 static LRESULT CFn_WMInitDialog(HWND hDlg, LPARAM lParam, LPCHOOSEFONTW lpcf)
625 HDC hdc;
626 int i,j;
627 BOOL init = FALSE;
628 long pstyle;
629 CFn_ENUMSTRUCT s;
630 LPLOGFONTW lpxx;
631 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
632 static const WCHAR strColorName[] = {'[','c','o','l','o','r',' ','n','a','m','e',']',0};
634 SetPropW(hDlg, strWineFontData, lpcf);
635 lpxx=lpcf->lpLogFont;
636 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
638 if (lpcf->lStructSize != sizeof(CHOOSEFONTW))
640 ERR("structure size failure!!!\n");
641 EndDialog (hDlg, 0);
642 return FALSE;
644 if (!himlTT)
645 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
646 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
648 /* Set effect flags */
649 if((lpcf->Flags & CF_EFFECTS) && (lpcf->Flags & CF_INITTOLOGFONTSTRUCT))
651 if(lpxx->lfUnderline)
652 CheckDlgButton(hDlg, chx2, TRUE);
653 if(lpxx->lfStrikeOut)
654 CheckDlgButton(hDlg, chx1, TRUE);
657 if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow(lpcf->hwndOwner))
658 ShowWindow(GetDlgItem(hDlg,pshHelp),SW_HIDE);
659 if (!(lpcf->Flags & CF_APPLY))
660 ShowWindow(GetDlgItem(hDlg,psh3),SW_HIDE);
661 if (lpcf->Flags & CF_NOSCRIPTSEL)
662 EnableWindow(GetDlgItem(hDlg,cmb5),FALSE);
663 if (lpcf->Flags & CF_EFFECTS)
665 for (i=0;i<TEXT_COLORS;i++)
667 WCHAR name[30];
669 if( LoadStringW(COMDLG32_hInstance, IDS_COLOR_BLACK+i, name,
670 sizeof(name)/sizeof(*name) )==0 )
672 memcpy(name, strColorName, sizeof(strColorName));
674 j=SendDlgItemMessageW(hDlg, cmb4, CB_ADDSTRING, 0, (LPARAM)name);
675 SendDlgItemMessageW(hDlg, cmb4, CB_SETITEMDATA, j, textcolors[i]);
676 /* look for a fitting value in color combobox */
677 if (textcolors[i]==lpcf->rgbColors)
678 SendDlgItemMessageW(hDlg,cmb4, CB_SETCURSEL,j,0);
681 else
683 ShowWindow(GetDlgItem(hDlg,cmb4),SW_HIDE);
684 ShowWindow(GetDlgItem(hDlg,chx1),SW_HIDE);
685 ShowWindow(GetDlgItem(hDlg,chx2),SW_HIDE);
686 ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
687 ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
689 if(!(hdc = CFn_GetDC(lpcf)))
691 EndDialog (hDlg, 0);
692 return FALSE;
694 s.hWnd1=GetDlgItem(hDlg,cmb1);
695 s.lpcf32w=lpcf;
696 do {
697 LOGFONTW elf;
698 s.added = 0;
699 elf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
700 elf.lfPitchAndFamily = 0;
701 elf.lfFaceName[0] = '\0'; /* enum all fonts */
702 if (!EnumFontFamiliesExW(hdc, &elf, (FONTENUMPROCW)FontFamilyEnumProc, (LPARAM)&s, 0))
704 TRACE("EnumFontFamiliesEx returns 0\n");
705 break;
707 if (s.added) break;
708 if (lpcf->Flags & CF_FIXEDPITCHONLY) {
709 FIXME("No font found with fixed pitch only, dropping flag.\n");
710 lpcf->Flags &= ~CF_FIXEDPITCHONLY;
711 continue;
713 if (lpcf->Flags & CF_TTONLY) {
714 FIXME("No font found with truetype only, dropping flag.\n");
715 lpcf->Flags &= ~CF_TTONLY;
716 continue;
718 break;
719 } while (1);
722 if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
724 /* look for fitting font name in combobox1 */
725 j=SendDlgItemMessageW(hDlg,cmb1,CB_FINDSTRING,-1,(LPARAM)lpxx->lfFaceName);
726 if (j!=CB_ERR)
728 INT height = lpxx->lfHeight < 0 ? -lpxx->lfHeight :
729 lpxx->lfHeight;
730 INT points;
731 int charset = lpxx->lfCharSet;
732 points = MulDiv( height, 72, GetScreenDPI());
733 pstyle = MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD:
734 FW_NORMAL,lpxx->lfItalic !=0);
735 SendDlgItemMessageW(hDlg, cmb1, CB_SETCURSEL, j, 0);
736 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
737 (LPARAM)GetDlgItem(hDlg,cmb1));
738 init = TRUE;
739 /* look for fitting font style in combobox2 */
740 CFn_FitFontStyle(hDlg, pstyle);
741 /* look for fitting font size in combobox3 */
742 CFn_FitFontSize(hDlg, points);
743 CFn_FitCharSet( hDlg, charset );
746 if (!init)
748 SendDlgItemMessageW(hDlg,cmb1,CB_SETCURSEL,0,0);
749 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
750 (LPARAM)GetDlgItem(hDlg,cmb1));
751 SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,0,0);
752 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
753 (LPARAM)GetDlgItem(hDlg,cmb1));
754 SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,0,0);
755 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb3, CBN_SELCHANGE),
756 (LPARAM)GetDlgItem(hDlg,cmb3));
757 SendDlgItemMessageW(hDlg,cmb5,CB_SETCURSEL,0,0);
758 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
759 (LPARAM)GetDlgItem(hDlg,cmb5));
761 /* limit text length user can type in as font size */
762 SendDlgItemMessageW(hDlg, cmb3, CB_LIMITTEXT, 5, 0);
764 if ((lpcf->Flags & CF_USESTYLE) && lpcf->lpszStyle)
766 j=SendDlgItemMessageW(hDlg,cmb2,CB_FINDSTRING,-1,(LPARAM)lpcf->lpszStyle);
767 if (j!=CB_ERR)
769 j=SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,j,0);
770 SendMessageW(hDlg,WM_COMMAND,cmb2,
771 MAKELONG(LOWORD(GetDlgItem(hDlg,cmb2)),CBN_SELCHANGE));
774 CFn_ReleaseDC(lpcf, hdc);
775 SetCursor(hcursor);
776 return TRUE;
780 /***********************************************************************
781 * CFn_WMMeasureItem [internal]
783 static LRESULT CFn_WMMeasureItem(HWND hDlg, LPARAM lParam)
785 HDC hdc;
786 HFONT hfontprev;
787 TEXTMETRICW tm;
788 LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam;
789 INT height = 0, cx;
791 if (!himlTT)
792 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
793 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
794 ImageList_GetIconSize( himlTT, &cx, &height);
795 lpmi->itemHeight = height + 2;
796 /* use MAX of bitmap height and tm.tmHeight .*/
797 hdc=GetDC(hDlg);
798 if(!hdc) return 0;
799 hfontprev = SelectObject( hdc, (HFONT)SendMessageW( hDlg, WM_GETFONT, 0, 0 ));
800 GetTextMetricsW(hdc, &tm);
801 if( tm.tmHeight > lpmi->itemHeight) lpmi->itemHeight = tm.tmHeight;
802 SelectObject(hdc, hfontprev);
803 ReleaseDC(hDlg, hdc);
804 return 0;
808 /***********************************************************************
809 * CFn_WMDrawItem [internal]
811 static LRESULT CFn_WMDrawItem(LPARAM lParam)
813 HBRUSH hBrush;
814 WCHAR buffer[40];
815 COLORREF cr, oldText=0, oldBk=0;
816 RECT rect;
817 int nFontType;
818 int cx, cy, idx;
819 LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam;
821 if (lpdi->itemID == (UINT)-1) /* got no items */
822 DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
823 else
825 if (lpdi->CtlType == ODT_COMBOBOX)
827 if (lpdi->itemState & ODS_SELECTED)
829 hBrush=GetSysColorBrush(COLOR_HIGHLIGHT);
830 oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
831 oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT));
832 } else
834 hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
835 SelectObject(lpdi->hDC, hBrush);
837 FillRect(lpdi->hDC, &lpdi->rcItem, hBrush);
839 else
840 return TRUE; /* this should never happen */
842 rect=lpdi->rcItem;
843 switch (lpdi->CtlID)
845 case cmb1:
846 /* TRACE(commdlg,"WM_Drawitem cmb1\n"); */
847 ImageList_GetIconSize( himlTT, &cx, &cy);
848 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
849 (LPARAM)buffer);
850 TextOutW(lpdi->hDC, lpdi->rcItem.left + cx + 4,
851 lpdi->rcItem.top, buffer, lstrlenW(buffer));
852 nFontType = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
853 idx = -1;
854 if (nFontType & TRUETYPE_FONTTYPE) {
855 idx = 0; /* picture: TT */
856 if( nFontType & NTM_TT_OPENTYPE)
857 idx = 2; /* picture: O */
858 } else if( nFontType & NTM_PS_OPENTYPE)
859 idx = 3; /* picture: O+ps */
860 else if( nFontType & NTM_TYPE1)
861 idx = 4; /* picture: a */
862 else if( nFontType & DEVICE_FONTTYPE)
863 idx = 1; /* picture: printer */
864 if( idx >= 0)
865 ImageList_Draw( himlTT, idx, lpdi->hDC, lpdi->rcItem.left,
866 (lpdi->rcItem.top + lpdi->rcItem.bottom - cy) / 2, ILD_TRANSPARENT);
867 break;
868 case cmb2:
869 case cmb3:
870 /* TRACE(commdlg,"WM_DRAWITEN cmb2,cmb3\n"); */
871 case cmb5:
872 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
873 (LPARAM)buffer);
874 TextOutW(lpdi->hDC, lpdi->rcItem.left,
875 lpdi->rcItem.top, buffer, lstrlenW(buffer));
876 break;
878 case cmb4:
879 /* TRACE(commdlg,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
880 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
881 (LPARAM)buffer);
882 TextOutW(lpdi->hDC, lpdi->rcItem.left + 25+5,
883 lpdi->rcItem.top, buffer, lstrlenW(buffer));
884 cr = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
885 hBrush = CreateSolidBrush(cr);
886 if (hBrush)
888 hBrush = SelectObject (lpdi->hDC, hBrush) ;
889 rect.right=rect.left+25;
890 rect.top++;
891 rect.left+=5;
892 rect.bottom--;
893 Rectangle( lpdi->hDC, rect.left, rect.top,
894 rect.right, rect.bottom );
895 DeleteObject( SelectObject (lpdi->hDC, hBrush)) ;
897 rect=lpdi->rcItem;
898 rect.left+=25+5;
899 break;
901 default:
902 return TRUE; /* this should never happen */
904 if (lpdi->itemState & ODS_SELECTED)
906 SetTextColor(lpdi->hDC, oldText);
907 SetBkColor(lpdi->hDC, oldBk);
910 return TRUE;
913 static INT get_dialog_font_point_size(HWND hDlg, CHOOSEFONTW *cf)
915 BOOL invalid_size = FALSE;
916 INT i, size;
918 i = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
919 if (i != CB_ERR)
920 size = LOWORD(SendDlgItemMessageW(hDlg, cmb3, CB_GETITEMDATA , i, 0));
921 else
923 WCHAR buffW[8], *endptrW;
925 GetDlgItemTextW(hDlg, cmb3, buffW, sizeof(buffW)/sizeof(*buffW));
926 size = strtolW(buffW, &endptrW, 10);
927 invalid_size = size == 0 && *endptrW;
929 if (size == 0)
930 size = 10;
933 cf->iPointSize = 10 * size;
934 cf->lpLogFont->lfHeight = -MulDiv(cf->iPointSize, GetScreenDPI(), 720);
935 return invalid_size ? -1 : size;
938 /***********************************************************************
939 * CFn_WMCommand [internal]
941 static LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcf)
943 int i;
944 long l;
945 HDC hdc;
947 if (!lpcf) return FALSE;
949 TRACE("WM_COMMAND wParam=%08X lParam=%08lX\n", (LONG)wParam, lParam);
950 switch (LOWORD(wParam))
952 case cmb1:
953 if (HIWORD(wParam)==CBN_SELCHANGE)
955 INT pointsize; /* save current pointsize */
956 LONG pstyle; /* save current style */
957 int charset;
958 int idx;
959 if(!(hdc = CFn_GetDC(lpcf)))
961 EndDialog (hDlg, 0);
962 return TRUE;
964 idx = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
965 pointsize = (int)SendDlgItemMessageW( hDlg, cmb3, CB_GETITEMDATA,
966 idx, 0);
967 idx = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
968 pstyle = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, idx, 0);
969 idx = SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
970 charset = SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, idx, 0);
972 SendDlgItemMessageW(hDlg, cmb2, CB_RESETCONTENT, 0, 0);
973 SendDlgItemMessageW(hDlg, cmb3, CB_RESETCONTENT, 0, 0);
974 SendDlgItemMessageW(hDlg, cmb5, CB_RESETCONTENT, 0, 0);
975 i=SendDlgItemMessageW(hDlg, cmb1, CB_GETCURSEL, 0, 0);
976 if (i!=CB_ERR)
978 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
979 CFn_ENUMSTRUCT s;
980 LOGFONTW enumlf;
981 SendDlgItemMessageW(hDlg, cmb1, CB_GETLBTEXT, i,
982 (LPARAM)enumlf.lfFaceName);
983 TRACE("WM_COMMAND/cmb1 =>%s\n", debugstr_w(enumlf.lfFaceName));
984 s.hWnd1=GetDlgItem(hDlg, cmb2);
985 s.hWnd2=GetDlgItem(hDlg, cmb3);
986 s.lpcf32w=lpcf;
987 enumlf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
988 enumlf.lfPitchAndFamily = 0;
989 EnumFontFamiliesExW(hdc, &enumlf,
990 (FONTENUMPROCW)FontStyleEnumProc, (LPARAM)&s, 0);
991 CFn_FitFontStyle(hDlg, pstyle);
992 if( pointsize != CB_ERR) CFn_FitFontSize(hDlg, pointsize);
993 if( charset != CB_ERR) CFn_FitCharSet( hDlg, charset );
994 SetCursor(hcursor);
996 CFn_ReleaseDC(lpcf, hdc);
998 break;
999 case chx1:
1000 case chx2:
1001 case cmb2:
1002 case cmb3:
1003 case cmb5:
1004 if (HIWORD(wParam)==CBN_SELCHANGE || HIWORD(wParam)== BN_CLICKED )
1006 WCHAR str[256];
1007 WINDOWINFO wininfo;
1008 LPLOGFONTW lpxx=lpcf->lpLogFont;
1010 TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
1012 /* face name */
1013 i=SendDlgItemMessageW(hDlg,cmb1,CB_GETCURSEL,0,0);
1014 if (i==CB_ERR)
1015 i=GetDlgItemTextW( hDlg, cmb1, str, 256 );
1016 else
1018 SendDlgItemMessageW(hDlg,cmb1,CB_GETLBTEXT,i,
1019 (LPARAM)str);
1020 l=SendDlgItemMessageW(hDlg,cmb1,CB_GETITEMDATA,i,0);
1021 lpcf->nFontType = LOWORD(l);
1022 /* FIXME: lpcf->nFontType |= .... SIMULATED_FONTTYPE and so */
1023 /* same value reported to the EnumFonts
1024 call back with the extra FONTTYPE_... bits added */
1025 lpxx->lfPitchAndFamily = HIWORD(l) >> 8;
1027 lstrcpynW(lpxx->lfFaceName, str, sizeof(lpxx->lfFaceName)/sizeof(lpxx->lfFaceName[0]));
1029 /* style */
1030 i=SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
1031 if (i!=CB_ERR)
1033 l=SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
1034 if (0!=(lpxx->lfItalic=HIWORD(l)))
1035 lpcf->nFontType |= ITALIC_FONTTYPE;
1036 if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
1037 lpcf->nFontType |= BOLD_FONTTYPE;
1040 /* size */
1041 get_dialog_font_point_size(hDlg, lpcf);
1043 /* charset */
1044 i=SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
1045 if (i!=CB_ERR)
1046 lpxx->lfCharSet=SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
1047 else
1048 lpxx->lfCharSet = DEFAULT_CHARSET;
1049 lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
1050 lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
1051 lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
1052 lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
1053 lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
1054 lpxx->lfQuality=DEFAULT_QUALITY;
1056 wininfo.cbSize=sizeof(wininfo);
1058 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1060 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1061 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1064 break;
1066 case cmb4:
1067 i=SendDlgItemMessageW(hDlg, cmb4, CB_GETCURSEL, 0, 0);
1068 if (i!=CB_ERR)
1070 WINDOWINFO wininfo;
1072 lpcf->rgbColors = SendDlgItemMessageW(hDlg, cmb4, CB_GETITEMDATA, i, 0);
1073 wininfo.cbSize=sizeof(wininfo);
1075 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1077 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1078 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1081 break;
1083 case psh15:
1084 i=RegisterWindowMessageW( HELPMSGSTRINGW );
1085 if (lpcf->hwndOwner)
1086 SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData));
1087 break;
1089 case IDOK:
1091 WCHAR msgW[80];
1092 INT pointsize;
1094 pointsize = get_dialog_font_point_size(hDlg, lpcf);
1095 if (pointsize == -1)
1097 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE_INPUT, msgW, sizeof(msgW)/sizeof(*msgW));
1098 MessageBoxW(hDlg, msgW, NULL, MB_OK | MB_ICONINFORMATION);
1099 return TRUE;
1102 if ( (!(lpcf->Flags & CF_LIMITSIZE)) ||
1103 ( (lpcf->Flags & CF_LIMITSIZE) &&
1104 (lpcf->iPointSize >= 10 * lpcf->nSizeMin) &&
1105 (lpcf->iPointSize <= 10 * lpcf->nSizeMax)))
1106 EndDialog(hDlg, TRUE);
1107 else
1109 WCHAR format[80];
1110 DWORD_PTR args[2];
1111 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE, format, sizeof(format)/sizeof(WCHAR));
1112 args[0] = lpcf->nSizeMin;
1113 args[1] = lpcf->nSizeMax;
1114 FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
1115 format, 0, 0, msgW, sizeof(msgW)/sizeof(*msgW),
1116 (__ms_va_list*)args);
1117 MessageBoxW(hDlg, msgW, NULL, MB_OK);
1119 return(TRUE);
1121 case IDCANCEL:
1122 EndDialog(hDlg, FALSE);
1123 return(TRUE);
1125 return(FALSE);
1128 static LRESULT CFn_WMDestroy(HWND hwnd, LPCHOOSEFONTW lpcfw)
1130 LPCHOOSEFONTA lpcfa;
1131 LPSTR lpszStyle;
1132 LPLOGFONTA lpLogFonta;
1133 int len;
1135 if (!lpcfw) return FALSE;
1137 lpcfa = GetPropW(hwnd, strWineFontData_a);
1138 lpLogFonta = lpcfa->lpLogFont;
1139 lpszStyle = lpcfa->lpszStyle;
1140 memcpy(lpcfa, lpcfw, sizeof(CHOOSEFONTA));
1141 lpcfa->lpLogFont = lpLogFonta;
1142 lpcfa->lpszStyle = lpszStyle;
1143 memcpy(lpcfa->lpLogFont, lpcfw->lpLogFont, sizeof(LOGFONTA));
1144 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName,
1145 LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0);
1147 if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) {
1148 len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, 0, 0, 0);
1149 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0);
1150 HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle);
1153 HeapFree(GetProcessHeap(), 0, lpcfw->lpLogFont);
1154 HeapFree(GetProcessHeap(), 0, lpcfw);
1155 SetPropW(hwnd, strWineFontData, 0);
1157 return TRUE;
1160 static LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW *lpcf)
1162 WINDOWINFO info;
1164 if (!lpcf) return FALSE;
1166 info.cbSize=sizeof(info);
1167 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &info ) )
1169 PAINTSTRUCT ps;
1170 HDC hdc;
1171 HFONT hOrigFont;
1172 LOGFONTW lf = *(lpcf->lpLogFont);
1174 MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2);
1175 hdc = BeginPaint( hDlg, &ps );
1177 TRACE("erase %d, rect=(%d,%d)-(%d,%d)\n", ps.fErase,
1178 ps.rcPaint.left, ps.rcPaint.top,
1179 ps.rcPaint.right, ps.rcPaint.bottom);
1181 /* Paint frame */
1182 DrawEdge( hdc, &info.rcWindow, EDGE_SUNKEN, BF_RECT|BF_ADJUST );
1184 /* Draw the sample text itself */
1185 hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
1186 SetTextColor( hdc, lpcf->rgbColors );
1188 DrawTextW( hdc,
1189 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]],
1190 -1, &info.rcWindow, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
1192 DeleteObject(SelectObject( hdc, hOrigFont ));
1193 EndPaint( hDlg, &ps );
1195 return FALSE;
1198 /***********************************************************************
1199 * FormatCharDlgProcA [internal]
1201 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1203 LPCHOOSEFONTW lpcfw;
1204 LPCHOOSEFONTA lpcfa;
1205 INT_PTR res = FALSE;
1206 int len;
1208 if (uMsg!=WM_INITDIALOG) {
1209 lpcfw = GetPropW(hDlg, strWineFontData);
1210 if (lpcfw && CFn_HookCallChk32(lpcfw))
1211 res=CallWindowProcA((WNDPROC)lpcfw->lpfnHook, hDlg, uMsg, wParam, lParam);
1212 if (res)
1213 return res;
1214 } else {
1215 lpcfa=(LPCHOOSEFONTA)lParam;
1216 SetPropW(hDlg, strWineFontData_a, (HANDLE)lParam);
1218 lpcfw = HeapAlloc(GetProcessHeap(), 0, sizeof(CHOOSEFONTW));
1219 memcpy(lpcfw, lpcfa, sizeof(CHOOSEFONTA));
1220 lpcfw->lpLogFont = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGFONTW));
1221 memcpy(lpcfw->lpLogFont, lpcfa->lpLogFont, sizeof(LOGFONTA));
1222 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpLogFont->lfFaceName,
1223 LF_FACESIZE, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE);
1225 if((lpcfa->Flags & CF_USESTYLE) && lpcfa->lpszStyle) {
1226 len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, NULL, 0);
1227 lpcfw->lpszStyle = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
1228 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len);
1231 if (!CFn_WMInitDialog(hDlg, lParam, lpcfw))
1233 TRACE("CFn_WMInitDialog returned FALSE\n");
1234 return FALSE;
1236 if (CFn_HookCallChk32(lpcfw))
1237 return CallWindowProcA((WNDPROC)lpcfa->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1239 switch (uMsg)
1241 case WM_MEASUREITEM:
1242 return CFn_WMMeasureItem(hDlg,lParam);
1243 case WM_DRAWITEM:
1244 return CFn_WMDrawItem(lParam);
1245 case WM_COMMAND:
1246 return CFn_WMCommand(hDlg, wParam, lParam, lpcfw);
1247 case WM_DESTROY:
1248 return CFn_WMDestroy(hDlg, lpcfw);
1249 case WM_CHOOSEFONT_GETLOGFONT:
1251 LOGFONTA *logfont = (LOGFONTA *)lParam;
1252 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1253 memcpy( logfont, lpcfw->lpLogFont, FIELD_OFFSET( LOGFONTA, lfFaceName ));
1254 WideCharToMultiByte( CP_ACP, 0, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE,
1255 logfont->lfFaceName, LF_FACESIZE, NULL, NULL );
1256 break;
1258 case WM_PAINT:
1259 return CFn_WMPaint(hDlg, wParam, lParam, lpcfw);
1261 return res;
1264 /***********************************************************************
1265 * FormatCharDlgProcW [internal]
1267 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1269 LPCHOOSEFONTW lpcf;
1270 INT_PTR res = FALSE;
1272 if (uMsg!=WM_INITDIALOG)
1274 lpcf= GetPropW(hDlg, strWineFontData);
1275 if (lpcf && CFn_HookCallChk32(lpcf))
1276 res=CallWindowProcW((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam);
1277 if (res)
1278 return res;
1280 else
1282 lpcf=(LPCHOOSEFONTW)lParam;
1283 if (!CFn_WMInitDialog(hDlg, lParam, lpcf))
1285 TRACE("CFn_WMInitDialog returned FALSE\n");
1286 return FALSE;
1288 if (CFn_HookCallChk32(lpcf))
1289 return CallWindowProcW((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1291 switch (uMsg)
1293 case WM_MEASUREITEM:
1294 return CFn_WMMeasureItem(hDlg, lParam);
1295 case WM_DRAWITEM:
1296 return CFn_WMDrawItem(lParam);
1297 case WM_COMMAND:
1298 return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
1299 case WM_DESTROY:
1300 return TRUE;
1301 case WM_CHOOSEFONT_GETLOGFONT:
1302 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1303 memcpy( (LOGFONTW *)lParam, lpcf->lpLogFont, sizeof(LOGFONTW) );
1304 break;
1305 case WM_PAINT:
1306 return CFn_WMPaint(hDlg, wParam, lParam, lpcf);
1308 return res;