comdlg32/fontdlg: Allow setting value by typing it into the edit fields.
[wine.git] / dlls / comdlg32 / fontdlg.c
blob82992cb5a4591c84d92439863a4c18ff7d3aa0cc
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;
943 BOOL cmb_selected_by_edit = FALSE;
945 if (!lpcf) return FALSE;
947 if(HIWORD(wParam) == CBN_EDITCHANGE)
949 int idx;
950 WCHAR str_edit[256], str_cmb[256];
951 int cmb = LOWORD(wParam);
953 GetDlgItemTextW(hDlg, cmb, str_edit, sizeof(str_edit) / sizeof(str_edit[0]));
954 idx = SendDlgItemMessageW(hDlg, cmb, CB_FINDSTRING, -1, (LPARAM)str_edit);
955 if(idx != -1)
957 SendDlgItemMessageW(hDlg, cmb, CB_GETLBTEXT, idx, (LPARAM)str_cmb);
959 /* Select listbox entry only if we have an exact match */
960 if(lstrcmpiW(str_edit, str_cmb) == 0)
962 SendDlgItemMessageW(hDlg, cmb, CB_SETCURSEL, idx, 0);
963 SendDlgItemMessageW(hDlg, cmb, CB_SETEDITSEL, 0, -1); /* Remove edit field selection */
964 cmb_selected_by_edit = TRUE;
969 TRACE("WM_COMMAND wParam=%08X lParam=%08lX\n", (LONG)wParam, lParam);
970 switch (LOWORD(wParam))
972 case cmb1:
973 if (HIWORD(wParam) == CBN_SELCHANGE || cmb_selected_by_edit)
975 INT pointsize; /* save current pointsize */
976 LONG pstyle; /* save current style */
977 int charset;
978 int idx;
979 if(!(hdc = CFn_GetDC(lpcf)))
981 EndDialog (hDlg, 0);
982 return TRUE;
984 idx = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
985 pointsize = (int)SendDlgItemMessageW( hDlg, cmb3, CB_GETITEMDATA,
986 idx, 0);
987 idx = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
988 pstyle = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, idx, 0);
989 idx = SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
990 charset = SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, idx, 0);
992 SendDlgItemMessageW(hDlg, cmb2, CB_RESETCONTENT, 0, 0);
993 SendDlgItemMessageW(hDlg, cmb3, CB_RESETCONTENT, 0, 0);
994 SendDlgItemMessageW(hDlg, cmb5, CB_RESETCONTENT, 0, 0);
995 i=SendDlgItemMessageW(hDlg, cmb1, CB_GETCURSEL, 0, 0);
996 if (i!=CB_ERR)
998 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
999 CFn_ENUMSTRUCT s;
1000 LOGFONTW enumlf;
1001 SendDlgItemMessageW(hDlg, cmb1, CB_GETLBTEXT, i,
1002 (LPARAM)enumlf.lfFaceName);
1003 TRACE("WM_COMMAND/cmb1 =>%s\n", debugstr_w(enumlf.lfFaceName));
1004 s.hWnd1=GetDlgItem(hDlg, cmb2);
1005 s.hWnd2=GetDlgItem(hDlg, cmb3);
1006 s.lpcf32w=lpcf;
1007 enumlf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
1008 enumlf.lfPitchAndFamily = 0;
1009 EnumFontFamiliesExW(hdc, &enumlf,
1010 (FONTENUMPROCW)FontStyleEnumProc, (LPARAM)&s, 0);
1011 CFn_FitFontStyle(hDlg, pstyle);
1012 if( pointsize != CB_ERR) CFn_FitFontSize(hDlg, pointsize);
1013 if( charset != CB_ERR) CFn_FitCharSet( hDlg, charset );
1014 SetCursor(hcursor);
1016 CFn_ReleaseDC(lpcf, hdc);
1018 break;
1019 case chx1:
1020 case chx2:
1021 case cmb2:
1022 case cmb3:
1023 case cmb5:
1024 if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == BN_CLICKED || cmb_selected_by_edit)
1026 WCHAR str[256];
1027 WINDOWINFO wininfo;
1028 LPLOGFONTW lpxx=lpcf->lpLogFont;
1030 TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
1032 /* face name */
1033 i=SendDlgItemMessageW(hDlg,cmb1,CB_GETCURSEL,0,0);
1034 if (i==CB_ERR)
1035 GetDlgItemTextW( hDlg, cmb1, str, sizeof(str)/sizeof(str[0]) );
1036 else
1038 SendDlgItemMessageW(hDlg,cmb1,CB_GETLBTEXT,i,
1039 (LPARAM)str);
1040 l=SendDlgItemMessageW(hDlg,cmb1,CB_GETITEMDATA,i,0);
1041 lpcf->nFontType = LOWORD(l);
1042 /* FIXME: lpcf->nFontType |= .... SIMULATED_FONTTYPE and so */
1043 /* same value reported to the EnumFonts
1044 call back with the extra FONTTYPE_... bits added */
1045 lpxx->lfPitchAndFamily = HIWORD(l) >> 8;
1047 lstrcpynW(lpxx->lfFaceName, str, sizeof(lpxx->lfFaceName)/sizeof(lpxx->lfFaceName[0]));
1049 /* style */
1050 i=SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
1051 if (i!=CB_ERR)
1053 l=SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
1054 if (0!=(lpxx->lfItalic=HIWORD(l)))
1055 lpcf->nFontType |= ITALIC_FONTTYPE;
1056 if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
1057 lpcf->nFontType |= BOLD_FONTTYPE;
1060 /* size */
1061 get_dialog_font_point_size(hDlg, lpcf);
1063 /* charset */
1064 i=SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
1065 if (i!=CB_ERR)
1066 lpxx->lfCharSet=SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
1067 else
1068 lpxx->lfCharSet = DEFAULT_CHARSET;
1069 lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
1070 lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
1071 lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
1072 lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
1073 lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
1074 lpxx->lfQuality=DEFAULT_QUALITY;
1076 wininfo.cbSize=sizeof(wininfo);
1078 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1080 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1081 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1084 break;
1086 case cmb4:
1087 i=SendDlgItemMessageW(hDlg, cmb4, CB_GETCURSEL, 0, 0);
1088 if (i!=CB_ERR)
1090 WINDOWINFO wininfo;
1092 lpcf->rgbColors = SendDlgItemMessageW(hDlg, cmb4, CB_GETITEMDATA, i, 0);
1093 wininfo.cbSize=sizeof(wininfo);
1095 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1097 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1098 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1101 break;
1103 case psh15:
1104 i=RegisterWindowMessageW( HELPMSGSTRINGW );
1105 if (lpcf->hwndOwner)
1106 SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData));
1107 break;
1109 case IDOK:
1111 WCHAR msgW[80];
1112 INT pointsize;
1114 pointsize = get_dialog_font_point_size(hDlg, lpcf);
1115 if (pointsize == -1)
1117 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE_INPUT, msgW, sizeof(msgW)/sizeof(*msgW));
1118 MessageBoxW(hDlg, msgW, NULL, MB_OK | MB_ICONINFORMATION);
1119 return TRUE;
1122 if ( (!(lpcf->Flags & CF_LIMITSIZE)) ||
1123 ( (lpcf->Flags & CF_LIMITSIZE) &&
1124 (lpcf->iPointSize >= 10 * lpcf->nSizeMin) &&
1125 (lpcf->iPointSize <= 10 * lpcf->nSizeMax)))
1126 EndDialog(hDlg, TRUE);
1127 else
1129 WCHAR format[80];
1130 DWORD_PTR args[2];
1131 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE, format, sizeof(format)/sizeof(WCHAR));
1132 args[0] = lpcf->nSizeMin;
1133 args[1] = lpcf->nSizeMax;
1134 FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
1135 format, 0, 0, msgW, sizeof(msgW)/sizeof(*msgW),
1136 (__ms_va_list*)args);
1137 MessageBoxW(hDlg, msgW, NULL, MB_OK);
1139 return(TRUE);
1141 case IDCANCEL:
1142 EndDialog(hDlg, FALSE);
1143 return(TRUE);
1145 return(FALSE);
1148 static LRESULT CFn_WMDestroy(HWND hwnd, LPCHOOSEFONTW lpcfw)
1150 LPCHOOSEFONTA lpcfa;
1151 LPSTR lpszStyle;
1152 LPLOGFONTA lpLogFonta;
1153 int len;
1155 if (!lpcfw) return FALSE;
1157 lpcfa = GetPropW(hwnd, strWineFontData_a);
1158 lpLogFonta = lpcfa->lpLogFont;
1159 lpszStyle = lpcfa->lpszStyle;
1160 memcpy(lpcfa, lpcfw, sizeof(CHOOSEFONTA));
1161 lpcfa->lpLogFont = lpLogFonta;
1162 lpcfa->lpszStyle = lpszStyle;
1163 memcpy(lpcfa->lpLogFont, lpcfw->lpLogFont, sizeof(LOGFONTA));
1164 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName,
1165 LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0);
1167 if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) {
1168 len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, 0, 0, 0);
1169 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0);
1170 HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle);
1173 HeapFree(GetProcessHeap(), 0, lpcfw->lpLogFont);
1174 HeapFree(GetProcessHeap(), 0, lpcfw);
1175 SetPropW(hwnd, strWineFontData, 0);
1177 return TRUE;
1180 static LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW *lpcf)
1182 WINDOWINFO info;
1184 if (!lpcf) return FALSE;
1186 info.cbSize=sizeof(info);
1187 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &info ) )
1189 PAINTSTRUCT ps;
1190 HDC hdc;
1191 HFONT hOrigFont;
1192 LOGFONTW lf = *(lpcf->lpLogFont);
1194 MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2);
1195 hdc = BeginPaint( hDlg, &ps );
1197 TRACE("erase %d, rect=%s\n", ps.fErase, wine_dbgstr_rect(&ps.rcPaint));
1199 /* Paint frame */
1200 DrawEdge( hdc, &info.rcWindow, EDGE_SUNKEN, BF_RECT|BF_ADJUST );
1202 /* Draw the sample text itself */
1203 hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
1204 SetTextColor( hdc, lpcf->rgbColors );
1206 DrawTextW( hdc,
1207 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]],
1208 -1, &info.rcWindow, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
1210 DeleteObject(SelectObject( hdc, hOrigFont ));
1211 EndPaint( hDlg, &ps );
1213 return FALSE;
1216 /***********************************************************************
1217 * FormatCharDlgProcA [internal]
1219 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1221 LPCHOOSEFONTW lpcfw;
1222 LPCHOOSEFONTA lpcfa;
1223 INT_PTR res = FALSE;
1224 int len;
1226 if (uMsg!=WM_INITDIALOG) {
1227 lpcfw = GetPropW(hDlg, strWineFontData);
1228 if (lpcfw && CFn_HookCallChk32(lpcfw))
1229 res=CallWindowProcA((WNDPROC)lpcfw->lpfnHook, hDlg, uMsg, wParam, lParam);
1230 if (res)
1231 return res;
1232 } else {
1233 lpcfa=(LPCHOOSEFONTA)lParam;
1234 SetPropW(hDlg, strWineFontData_a, (HANDLE)lParam);
1236 lpcfw = HeapAlloc(GetProcessHeap(), 0, sizeof(CHOOSEFONTW));
1237 memcpy(lpcfw, lpcfa, sizeof(CHOOSEFONTA));
1238 lpcfw->lpLogFont = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGFONTW));
1239 memcpy(lpcfw->lpLogFont, lpcfa->lpLogFont, sizeof(LOGFONTA));
1240 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpLogFont->lfFaceName,
1241 LF_FACESIZE, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE);
1243 if((lpcfa->Flags & CF_USESTYLE) && lpcfa->lpszStyle) {
1244 len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, NULL, 0);
1245 lpcfw->lpszStyle = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
1246 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len);
1249 if (!CFn_WMInitDialog(hDlg, lParam, lpcfw))
1251 TRACE("CFn_WMInitDialog returned FALSE\n");
1252 return FALSE;
1254 if (CFn_HookCallChk32(lpcfw))
1255 return CallWindowProcA((WNDPROC)lpcfa->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1257 switch (uMsg)
1259 case WM_MEASUREITEM:
1260 return CFn_WMMeasureItem(hDlg,lParam);
1261 case WM_DRAWITEM:
1262 return CFn_WMDrawItem(lParam);
1263 case WM_COMMAND:
1264 return CFn_WMCommand(hDlg, wParam, lParam, lpcfw);
1265 case WM_DESTROY:
1266 return CFn_WMDestroy(hDlg, lpcfw);
1267 case WM_CHOOSEFONT_GETLOGFONT:
1269 LOGFONTA *logfont = (LOGFONTA *)lParam;
1270 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1271 memcpy( logfont, lpcfw->lpLogFont, FIELD_OFFSET( LOGFONTA, lfFaceName ));
1272 WideCharToMultiByte( CP_ACP, 0, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE,
1273 logfont->lfFaceName, LF_FACESIZE, NULL, NULL );
1274 break;
1276 case WM_PAINT:
1277 return CFn_WMPaint(hDlg, wParam, lParam, lpcfw);
1279 return res;
1282 /***********************************************************************
1283 * FormatCharDlgProcW [internal]
1285 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1287 LPCHOOSEFONTW lpcf;
1288 INT_PTR res = FALSE;
1290 if (uMsg!=WM_INITDIALOG)
1292 lpcf= GetPropW(hDlg, strWineFontData);
1293 if (lpcf && CFn_HookCallChk32(lpcf))
1294 res=CallWindowProcW((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam);
1295 if (res)
1296 return res;
1298 else
1300 lpcf=(LPCHOOSEFONTW)lParam;
1301 if (!CFn_WMInitDialog(hDlg, lParam, lpcf))
1303 TRACE("CFn_WMInitDialog returned FALSE\n");
1304 return FALSE;
1306 if (CFn_HookCallChk32(lpcf))
1307 return CallWindowProcW((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1309 switch (uMsg)
1311 case WM_MEASUREITEM:
1312 return CFn_WMMeasureItem(hDlg, lParam);
1313 case WM_DRAWITEM:
1314 return CFn_WMDrawItem(lParam);
1315 case WM_COMMAND:
1316 return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
1317 case WM_DESTROY:
1318 return TRUE;
1319 case WM_CHOOSEFONT_GETLOGFONT:
1320 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1321 memcpy( (LOGFONTW *)lParam, lpcf->lpLogFont, sizeof(LOGFONTW) );
1322 break;
1323 case WM_PAINT:
1324 return CFn_WMPaint(hDlg, wParam, lParam, lpcf);
1326 return res;