ws2_32: Accept shouldn't fail when addrlen32 is NULL.
[wine.git] / dlls / comdlg32 / fontdlg.c
blobed2615d5fdcd45fcbc0b50f39e6b701039a9b6a0
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 WCHAR buffW[16];
538 int i,n;
540 /* look for fitting font size in combobox3 */
541 n=SendDlgItemMessageW(hDlg, cmb3, CB_GETCOUNT, 0, 0);
542 for (i=0;i<n;i++)
544 if (points == (int)SendDlgItemMessageW
545 (hDlg,cmb3, CB_GETITEMDATA,i,0))
547 SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,i,0);
548 SendMessageW(hDlg, WM_COMMAND,
549 MAKEWPARAM(cmb3, CBN_SELCHANGE),
550 (LPARAM)GetDlgItem(hDlg,cmb3));
551 return;
555 /* no default matching size, set text manually */
556 sprintfW(buffW, fontsizefmtW, points);
557 SetDlgItemTextW(hDlg, cmb3, buffW);
560 static BOOL CFn_FitFontStyle( HWND hDlg, LONG packedstyle )
562 LONG id;
563 int i;
564 BOOL ret = FALSE;
565 /* look for fitting font style in combobox2 */
566 for (i=0;i<TEXT_EXTRAS;i++)
568 id = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
569 if (packedstyle == id)
571 SendDlgItemMessageW(hDlg, cmb2, CB_SETCURSEL, i, 0);
572 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
573 (LPARAM)GetDlgItem(hDlg,cmb2));
574 ret = TRUE;
575 break;
578 return ret;
582 static BOOL CFn_FitCharSet( HWND hDlg, int charset )
584 int i,n,cs;
585 /* look for fitting char set in combobox5 */
586 n=SendDlgItemMessageW(hDlg, cmb5, CB_GETCOUNT, 0, 0);
587 for (i=0;i<n;i++)
589 cs =SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
590 if (charset == cs)
592 SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, i, 0);
593 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
594 (LPARAM)GetDlgItem(hDlg,cmb2));
595 return TRUE;
598 /* no charset fits: select the first one in the list */
599 SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, 0, 0);
600 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
601 (LPARAM)GetDlgItem(hDlg,cmb2));
602 return FALSE;
605 /***********************************************************************
606 * FontStyleEnumProc32 [internal]
608 static INT WINAPI FontStyleEnumProc( const ENUMLOGFONTEXW *lpElfex,
609 const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam )
611 LPCFn_ENUMSTRUCT s=(LPCFn_ENUMSTRUCT)lParam;
612 HWND hcmb2=s->hWnd1;
613 HWND hcmb3=s->hWnd2;
614 HWND hDlg=GetParent(hcmb3);
615 return AddFontStyle( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
616 dwFontType, s->lpcf32w, hcmb2, hcmb3, hDlg);
619 /***********************************************************************
620 * CFn_WMInitDialog [internal]
622 static LRESULT CFn_WMInitDialog(HWND hDlg, LPARAM lParam, LPCHOOSEFONTW lpcf)
624 HDC hdc;
625 int i,j;
626 BOOL init = FALSE;
627 long pstyle;
628 CFn_ENUMSTRUCT s;
629 LPLOGFONTW lpxx;
630 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
631 static const WCHAR strColorName[] = {'[','c','o','l','o','r',' ','n','a','m','e',']',0};
633 SetPropW(hDlg, strWineFontData, lpcf);
634 lpxx=lpcf->lpLogFont;
635 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
637 if (lpcf->lStructSize != sizeof(CHOOSEFONTW))
639 ERR("structure size failure!!!\n");
640 EndDialog (hDlg, 0);
641 return FALSE;
643 if (!himlTT)
644 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
645 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
647 /* Set effect flags */
648 if((lpcf->Flags & CF_EFFECTS) && (lpcf->Flags & CF_INITTOLOGFONTSTRUCT))
650 if(lpxx->lfUnderline)
651 CheckDlgButton(hDlg, chx2, TRUE);
652 if(lpxx->lfStrikeOut)
653 CheckDlgButton(hDlg, chx1, TRUE);
656 if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow(lpcf->hwndOwner))
657 ShowWindow(GetDlgItem(hDlg,pshHelp),SW_HIDE);
658 if (!(lpcf->Flags & CF_APPLY))
659 ShowWindow(GetDlgItem(hDlg,psh3),SW_HIDE);
660 if (lpcf->Flags & CF_NOSCRIPTSEL)
661 EnableWindow(GetDlgItem(hDlg,cmb5),FALSE);
662 if (lpcf->Flags & CF_EFFECTS)
664 for (i=0;i<TEXT_COLORS;i++)
666 WCHAR name[30];
668 if( LoadStringW(COMDLG32_hInstance, IDS_COLOR_BLACK+i, name,
669 sizeof(name)/sizeof(*name) )==0 )
671 memcpy(name, strColorName, sizeof(strColorName));
673 j=SendDlgItemMessageW(hDlg, cmb4, CB_ADDSTRING, 0, (LPARAM)name);
674 SendDlgItemMessageW(hDlg, cmb4, CB_SETITEMDATA, j, textcolors[i]);
675 /* look for a fitting value in color combobox */
676 if (textcolors[i]==lpcf->rgbColors)
677 SendDlgItemMessageW(hDlg,cmb4, CB_SETCURSEL,j,0);
680 else
682 ShowWindow(GetDlgItem(hDlg,cmb4),SW_HIDE);
683 ShowWindow(GetDlgItem(hDlg,chx1),SW_HIDE);
684 ShowWindow(GetDlgItem(hDlg,chx2),SW_HIDE);
685 ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
686 ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
688 if(!(hdc = CFn_GetDC(lpcf)))
690 EndDialog (hDlg, 0);
691 return FALSE;
693 s.hWnd1=GetDlgItem(hDlg,cmb1);
694 s.lpcf32w=lpcf;
695 do {
696 LOGFONTW elf;
697 s.added = 0;
698 elf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
699 elf.lfPitchAndFamily = 0;
700 elf.lfFaceName[0] = '\0'; /* enum all fonts */
701 if (!EnumFontFamiliesExW(hdc, &elf, (FONTENUMPROCW)FontFamilyEnumProc, (LPARAM)&s, 0))
703 TRACE("EnumFontFamiliesEx returns 0\n");
704 break;
706 if (s.added) break;
707 if (lpcf->Flags & CF_FIXEDPITCHONLY) {
708 FIXME("No font found with fixed pitch only, dropping flag.\n");
709 lpcf->Flags &= ~CF_FIXEDPITCHONLY;
710 continue;
712 if (lpcf->Flags & CF_TTONLY) {
713 FIXME("No font found with truetype only, dropping flag.\n");
714 lpcf->Flags &= ~CF_TTONLY;
715 continue;
717 break;
718 } while (1);
721 if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
723 /* look for fitting font name in combobox1 */
724 j=SendDlgItemMessageW(hDlg,cmb1,CB_FINDSTRING,-1,(LPARAM)lpxx->lfFaceName);
725 if (j!=CB_ERR)
727 INT height = lpxx->lfHeight < 0 ? -lpxx->lfHeight :
728 lpxx->lfHeight;
729 INT points;
730 int charset = lpxx->lfCharSet;
731 points = MulDiv( height, 72, GetScreenDPI());
732 pstyle = MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD:
733 FW_NORMAL,lpxx->lfItalic !=0);
734 SendDlgItemMessageW(hDlg, cmb1, CB_SETCURSEL, j, 0);
735 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
736 (LPARAM)GetDlgItem(hDlg,cmb1));
737 init = TRUE;
738 /* look for fitting font style in combobox2 */
739 CFn_FitFontStyle(hDlg, pstyle);
740 /* look for fitting font size in combobox3 */
741 CFn_FitFontSize(hDlg, points);
742 CFn_FitCharSet( hDlg, charset );
745 if (!init)
747 SendDlgItemMessageW(hDlg,cmb1,CB_SETCURSEL,0,0);
748 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
749 (LPARAM)GetDlgItem(hDlg,cmb1));
750 SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,0,0);
751 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
752 (LPARAM)GetDlgItem(hDlg,cmb1));
753 SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,0,0);
754 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb3, CBN_SELCHANGE),
755 (LPARAM)GetDlgItem(hDlg,cmb3));
756 SendDlgItemMessageW(hDlg,cmb5,CB_SETCURSEL,0,0);
757 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
758 (LPARAM)GetDlgItem(hDlg,cmb5));
760 /* limit text length user can type in as font size */
761 SendDlgItemMessageW(hDlg, cmb3, CB_LIMITTEXT, 5, 0);
763 if ((lpcf->Flags & CF_USESTYLE) && lpcf->lpszStyle)
765 j=SendDlgItemMessageW(hDlg,cmb2,CB_FINDSTRING,-1,(LPARAM)lpcf->lpszStyle);
766 if (j!=CB_ERR)
768 j=SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,j,0);
769 SendMessageW(hDlg,WM_COMMAND,cmb2,
770 MAKELONG(LOWORD(GetDlgItem(hDlg,cmb2)),CBN_SELCHANGE));
773 CFn_ReleaseDC(lpcf, hdc);
774 SetCursor(hcursor);
775 return TRUE;
779 /***********************************************************************
780 * CFn_WMMeasureItem [internal]
782 static LRESULT CFn_WMMeasureItem(HWND hDlg, LPARAM lParam)
784 HDC hdc;
785 HFONT hfontprev;
786 TEXTMETRICW tm;
787 LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam;
788 INT height = 0, cx;
790 if (!himlTT)
791 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
792 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
793 ImageList_GetIconSize( himlTT, &cx, &height);
794 lpmi->itemHeight = height + 2;
795 /* use MAX of bitmap height and tm.tmHeight .*/
796 hdc=GetDC(hDlg);
797 if(!hdc) return 0;
798 hfontprev = SelectObject( hdc, (HFONT)SendMessageW( hDlg, WM_GETFONT, 0, 0 ));
799 GetTextMetricsW(hdc, &tm);
800 if( tm.tmHeight > lpmi->itemHeight) lpmi->itemHeight = tm.tmHeight;
801 SelectObject(hdc, hfontprev);
802 ReleaseDC(hDlg, hdc);
803 return 0;
807 /***********************************************************************
808 * CFn_WMDrawItem [internal]
810 static LRESULT CFn_WMDrawItem(LPARAM lParam)
812 HBRUSH hBrush;
813 WCHAR buffer[40];
814 COLORREF cr, oldText=0, oldBk=0;
815 RECT rect;
816 int nFontType;
817 int cx, cy, idx;
818 LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam;
820 if (lpdi->itemID == (UINT)-1) /* got no items */
821 DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
822 else
824 if (lpdi->CtlType == ODT_COMBOBOX)
826 if (lpdi->itemState & ODS_SELECTED)
828 hBrush=GetSysColorBrush(COLOR_HIGHLIGHT);
829 oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
830 oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT));
831 } else
833 hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
834 SelectObject(lpdi->hDC, hBrush);
836 FillRect(lpdi->hDC, &lpdi->rcItem, hBrush);
838 else
839 return TRUE; /* this should never happen */
841 rect=lpdi->rcItem;
842 switch (lpdi->CtlID)
844 case cmb1:
845 /* TRACE(commdlg,"WM_Drawitem cmb1\n"); */
846 ImageList_GetIconSize( himlTT, &cx, &cy);
847 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
848 (LPARAM)buffer);
849 TextOutW(lpdi->hDC, lpdi->rcItem.left + cx + 4,
850 lpdi->rcItem.top, buffer, lstrlenW(buffer));
851 nFontType = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
852 idx = -1;
853 if (nFontType & TRUETYPE_FONTTYPE) {
854 idx = 0; /* picture: TT */
855 if( nFontType & NTM_TT_OPENTYPE)
856 idx = 2; /* picture: O */
857 } else if( nFontType & NTM_PS_OPENTYPE)
858 idx = 3; /* picture: O+ps */
859 else if( nFontType & NTM_TYPE1)
860 idx = 4; /* picture: a */
861 else if( nFontType & DEVICE_FONTTYPE)
862 idx = 1; /* picture: printer */
863 if( idx >= 0)
864 ImageList_Draw( himlTT, idx, lpdi->hDC, lpdi->rcItem.left,
865 (lpdi->rcItem.top + lpdi->rcItem.bottom - cy) / 2, ILD_TRANSPARENT);
866 break;
867 case cmb2:
868 case cmb3:
869 /* TRACE(commdlg,"WM_DRAWITEN cmb2,cmb3\n"); */
870 case cmb5:
871 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
872 (LPARAM)buffer);
873 TextOutW(lpdi->hDC, lpdi->rcItem.left,
874 lpdi->rcItem.top, buffer, lstrlenW(buffer));
875 break;
877 case cmb4:
878 /* TRACE(commdlg,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
879 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
880 (LPARAM)buffer);
881 TextOutW(lpdi->hDC, lpdi->rcItem.left + 25+5,
882 lpdi->rcItem.top, buffer, lstrlenW(buffer));
883 cr = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
884 hBrush = CreateSolidBrush(cr);
885 if (hBrush)
887 hBrush = SelectObject (lpdi->hDC, hBrush) ;
888 rect.right=rect.left+25;
889 rect.top++;
890 rect.left+=5;
891 rect.bottom--;
892 Rectangle( lpdi->hDC, rect.left, rect.top,
893 rect.right, rect.bottom );
894 DeleteObject( SelectObject (lpdi->hDC, hBrush)) ;
896 rect=lpdi->rcItem;
897 rect.left+=25+5;
898 break;
900 default:
901 return TRUE; /* this should never happen */
903 if (lpdi->itemState & ODS_SELECTED)
905 SetTextColor(lpdi->hDC, oldText);
906 SetBkColor(lpdi->hDC, oldBk);
909 return TRUE;
912 static INT get_dialog_font_point_size(HWND hDlg, CHOOSEFONTW *cf)
914 BOOL invalid_size = FALSE;
915 INT i, size;
917 i = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
918 if (i != CB_ERR)
919 size = LOWORD(SendDlgItemMessageW(hDlg, cmb3, CB_GETITEMDATA , i, 0));
920 else
922 WCHAR buffW[8], *endptrW;
924 GetDlgItemTextW(hDlg, cmb3, buffW, sizeof(buffW)/sizeof(*buffW));
925 size = strtolW(buffW, &endptrW, 10);
926 invalid_size = size == 0 && *endptrW;
928 if (size == 0)
929 size = 10;
932 cf->iPointSize = 10 * size;
933 cf->lpLogFont->lfHeight = -MulDiv(cf->iPointSize, GetScreenDPI(), 720);
934 return invalid_size ? -1 : size;
937 /***********************************************************************
938 * CFn_WMCommand [internal]
940 static LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcf)
942 int i;
943 long l;
944 HDC hdc;
946 if (!lpcf) return FALSE;
948 TRACE("WM_COMMAND wParam=%08X lParam=%08lX\n", (LONG)wParam, lParam);
949 switch (LOWORD(wParam))
951 case cmb1:
952 if (HIWORD(wParam)==CBN_SELCHANGE)
954 INT pointsize; /* save current pointsize */
955 LONG pstyle; /* save current style */
956 int charset;
957 int idx;
958 if(!(hdc = CFn_GetDC(lpcf)))
960 EndDialog (hDlg, 0);
961 return TRUE;
963 idx = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
964 pointsize = (int)SendDlgItemMessageW( hDlg, cmb3, CB_GETITEMDATA,
965 idx, 0);
966 idx = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
967 pstyle = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, idx, 0);
968 idx = SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
969 charset = SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, idx, 0);
971 SendDlgItemMessageW(hDlg, cmb2, CB_RESETCONTENT, 0, 0);
972 SendDlgItemMessageW(hDlg, cmb3, CB_RESETCONTENT, 0, 0);
973 SendDlgItemMessageW(hDlg, cmb5, CB_RESETCONTENT, 0, 0);
974 i=SendDlgItemMessageW(hDlg, cmb1, CB_GETCURSEL, 0, 0);
975 if (i!=CB_ERR)
977 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
978 CFn_ENUMSTRUCT s;
979 LOGFONTW enumlf;
980 SendDlgItemMessageW(hDlg, cmb1, CB_GETLBTEXT, i,
981 (LPARAM)enumlf.lfFaceName);
982 TRACE("WM_COMMAND/cmb1 =>%s\n", debugstr_w(enumlf.lfFaceName));
983 s.hWnd1=GetDlgItem(hDlg, cmb2);
984 s.hWnd2=GetDlgItem(hDlg, cmb3);
985 s.lpcf32w=lpcf;
986 enumlf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
987 enumlf.lfPitchAndFamily = 0;
988 EnumFontFamiliesExW(hdc, &enumlf,
989 (FONTENUMPROCW)FontStyleEnumProc, (LPARAM)&s, 0);
990 CFn_FitFontStyle(hDlg, pstyle);
991 if( pointsize != CB_ERR) CFn_FitFontSize(hDlg, pointsize);
992 if( charset != CB_ERR) CFn_FitCharSet( hDlg, charset );
993 SetCursor(hcursor);
995 CFn_ReleaseDC(lpcf, hdc);
997 break;
998 case chx1:
999 case chx2:
1000 case cmb2:
1001 case cmb3:
1002 case cmb5:
1003 if (HIWORD(wParam)==CBN_SELCHANGE || HIWORD(wParam)== BN_CLICKED )
1005 WCHAR str[256];
1006 WINDOWINFO wininfo;
1007 LPLOGFONTW lpxx=lpcf->lpLogFont;
1009 TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
1011 /* face name */
1012 i=SendDlgItemMessageW(hDlg,cmb1,CB_GETCURSEL,0,0);
1013 if (i==CB_ERR)
1014 GetDlgItemTextW( hDlg, cmb1, str, sizeof(str)/sizeof(str[0]) );
1015 else
1017 SendDlgItemMessageW(hDlg,cmb1,CB_GETLBTEXT,i,
1018 (LPARAM)str);
1019 l=SendDlgItemMessageW(hDlg,cmb1,CB_GETITEMDATA,i,0);
1020 lpcf->nFontType = LOWORD(l);
1021 /* FIXME: lpcf->nFontType |= .... SIMULATED_FONTTYPE and so */
1022 /* same value reported to the EnumFonts
1023 call back with the extra FONTTYPE_... bits added */
1024 lpxx->lfPitchAndFamily = HIWORD(l) >> 8;
1026 lstrcpynW(lpxx->lfFaceName, str, sizeof(lpxx->lfFaceName)/sizeof(lpxx->lfFaceName[0]));
1028 /* style */
1029 i=SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
1030 if (i!=CB_ERR)
1032 l=SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
1033 if (0!=(lpxx->lfItalic=HIWORD(l)))
1034 lpcf->nFontType |= ITALIC_FONTTYPE;
1035 if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
1036 lpcf->nFontType |= BOLD_FONTTYPE;
1039 /* size */
1040 get_dialog_font_point_size(hDlg, lpcf);
1042 /* charset */
1043 i=SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
1044 if (i!=CB_ERR)
1045 lpxx->lfCharSet=SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
1046 else
1047 lpxx->lfCharSet = DEFAULT_CHARSET;
1048 lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
1049 lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
1050 lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
1051 lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
1052 lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
1053 lpxx->lfQuality=DEFAULT_QUALITY;
1055 wininfo.cbSize=sizeof(wininfo);
1057 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1059 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1060 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1063 break;
1065 case cmb4:
1066 i=SendDlgItemMessageW(hDlg, cmb4, CB_GETCURSEL, 0, 0);
1067 if (i!=CB_ERR)
1069 WINDOWINFO wininfo;
1071 lpcf->rgbColors = SendDlgItemMessageW(hDlg, cmb4, CB_GETITEMDATA, i, 0);
1072 wininfo.cbSize=sizeof(wininfo);
1074 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1076 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1077 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1080 break;
1082 case psh15:
1083 i=RegisterWindowMessageW( HELPMSGSTRINGW );
1084 if (lpcf->hwndOwner)
1085 SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData));
1086 break;
1088 case IDOK:
1090 WCHAR msgW[80];
1091 INT pointsize;
1093 pointsize = get_dialog_font_point_size(hDlg, lpcf);
1094 if (pointsize == -1)
1096 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE_INPUT, msgW, sizeof(msgW)/sizeof(*msgW));
1097 MessageBoxW(hDlg, msgW, NULL, MB_OK | MB_ICONINFORMATION);
1098 return TRUE;
1101 if ( (!(lpcf->Flags & CF_LIMITSIZE)) ||
1102 ( (lpcf->Flags & CF_LIMITSIZE) &&
1103 (lpcf->iPointSize >= 10 * lpcf->nSizeMin) &&
1104 (lpcf->iPointSize <= 10 * lpcf->nSizeMax)))
1105 EndDialog(hDlg, TRUE);
1106 else
1108 WCHAR format[80];
1109 DWORD_PTR args[2];
1110 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE, format, sizeof(format)/sizeof(WCHAR));
1111 args[0] = lpcf->nSizeMin;
1112 args[1] = lpcf->nSizeMax;
1113 FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
1114 format, 0, 0, msgW, sizeof(msgW)/sizeof(*msgW),
1115 (__ms_va_list*)args);
1116 MessageBoxW(hDlg, msgW, NULL, MB_OK);
1118 return(TRUE);
1120 case IDCANCEL:
1121 EndDialog(hDlg, FALSE);
1122 return(TRUE);
1124 return(FALSE);
1127 static LRESULT CFn_WMDestroy(HWND hwnd, LPCHOOSEFONTW lpcfw)
1129 LPCHOOSEFONTA lpcfa;
1130 LPSTR lpszStyle;
1131 LPLOGFONTA lpLogFonta;
1132 int len;
1134 if (!lpcfw) return FALSE;
1136 lpcfa = GetPropW(hwnd, strWineFontData_a);
1137 lpLogFonta = lpcfa->lpLogFont;
1138 lpszStyle = lpcfa->lpszStyle;
1139 memcpy(lpcfa, lpcfw, sizeof(CHOOSEFONTA));
1140 lpcfa->lpLogFont = lpLogFonta;
1141 lpcfa->lpszStyle = lpszStyle;
1142 memcpy(lpcfa->lpLogFont, lpcfw->lpLogFont, sizeof(LOGFONTA));
1143 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName,
1144 LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0);
1146 if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) {
1147 len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, 0, 0, 0);
1148 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0);
1149 HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle);
1152 HeapFree(GetProcessHeap(), 0, lpcfw->lpLogFont);
1153 HeapFree(GetProcessHeap(), 0, lpcfw);
1154 SetPropW(hwnd, strWineFontData, 0);
1156 return TRUE;
1159 static LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW *lpcf)
1161 WINDOWINFO info;
1163 if (!lpcf) return FALSE;
1165 info.cbSize=sizeof(info);
1166 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &info ) )
1168 PAINTSTRUCT ps;
1169 HDC hdc;
1170 HFONT hOrigFont;
1171 LOGFONTW lf = *(lpcf->lpLogFont);
1173 MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2);
1174 hdc = BeginPaint( hDlg, &ps );
1176 TRACE("erase %d, rect=%s\n", ps.fErase, wine_dbgstr_rect(&ps.rcPaint));
1178 /* Paint frame */
1179 DrawEdge( hdc, &info.rcWindow, EDGE_SUNKEN, BF_RECT|BF_ADJUST );
1181 /* Draw the sample text itself */
1182 hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
1183 SetTextColor( hdc, lpcf->rgbColors );
1185 DrawTextW( hdc,
1186 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]],
1187 -1, &info.rcWindow, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
1189 DeleteObject(SelectObject( hdc, hOrigFont ));
1190 EndPaint( hDlg, &ps );
1192 return FALSE;
1195 /***********************************************************************
1196 * FormatCharDlgProcA [internal]
1198 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1200 LPCHOOSEFONTW lpcfw;
1201 LPCHOOSEFONTA lpcfa;
1202 INT_PTR res = FALSE;
1203 int len;
1205 if (uMsg!=WM_INITDIALOG) {
1206 lpcfw = GetPropW(hDlg, strWineFontData);
1207 if (lpcfw && CFn_HookCallChk32(lpcfw))
1208 res=CallWindowProcA((WNDPROC)lpcfw->lpfnHook, hDlg, uMsg, wParam, lParam);
1209 if (res)
1210 return res;
1211 } else {
1212 lpcfa=(LPCHOOSEFONTA)lParam;
1213 SetPropW(hDlg, strWineFontData_a, (HANDLE)lParam);
1215 lpcfw = HeapAlloc(GetProcessHeap(), 0, sizeof(CHOOSEFONTW));
1216 memcpy(lpcfw, lpcfa, sizeof(CHOOSEFONTA));
1217 lpcfw->lpLogFont = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGFONTW));
1218 memcpy(lpcfw->lpLogFont, lpcfa->lpLogFont, sizeof(LOGFONTA));
1219 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpLogFont->lfFaceName,
1220 LF_FACESIZE, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE);
1222 if((lpcfa->Flags & CF_USESTYLE) && lpcfa->lpszStyle) {
1223 len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, NULL, 0);
1224 lpcfw->lpszStyle = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
1225 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len);
1228 if (!CFn_WMInitDialog(hDlg, lParam, lpcfw))
1230 TRACE("CFn_WMInitDialog returned FALSE\n");
1231 return FALSE;
1233 if (CFn_HookCallChk32(lpcfw))
1234 return CallWindowProcA((WNDPROC)lpcfa->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1236 switch (uMsg)
1238 case WM_MEASUREITEM:
1239 return CFn_WMMeasureItem(hDlg,lParam);
1240 case WM_DRAWITEM:
1241 return CFn_WMDrawItem(lParam);
1242 case WM_COMMAND:
1243 return CFn_WMCommand(hDlg, wParam, lParam, lpcfw);
1244 case WM_DESTROY:
1245 return CFn_WMDestroy(hDlg, lpcfw);
1246 case WM_CHOOSEFONT_GETLOGFONT:
1248 LOGFONTA *logfont = (LOGFONTA *)lParam;
1249 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1250 memcpy( logfont, lpcfw->lpLogFont, FIELD_OFFSET( LOGFONTA, lfFaceName ));
1251 WideCharToMultiByte( CP_ACP, 0, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE,
1252 logfont->lfFaceName, LF_FACESIZE, NULL, NULL );
1253 break;
1255 case WM_PAINT:
1256 return CFn_WMPaint(hDlg, wParam, lParam, lpcfw);
1258 return res;
1261 /***********************************************************************
1262 * FormatCharDlgProcW [internal]
1264 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1266 LPCHOOSEFONTW lpcf;
1267 INT_PTR res = FALSE;
1269 if (uMsg!=WM_INITDIALOG)
1271 lpcf= GetPropW(hDlg, strWineFontData);
1272 if (lpcf && CFn_HookCallChk32(lpcf))
1273 res=CallWindowProcW((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam);
1274 if (res)
1275 return res;
1277 else
1279 lpcf=(LPCHOOSEFONTW)lParam;
1280 if (!CFn_WMInitDialog(hDlg, lParam, lpcf))
1282 TRACE("CFn_WMInitDialog returned FALSE\n");
1283 return FALSE;
1285 if (CFn_HookCallChk32(lpcf))
1286 return CallWindowProcW((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1288 switch (uMsg)
1290 case WM_MEASUREITEM:
1291 return CFn_WMMeasureItem(hDlg, lParam);
1292 case WM_DRAWITEM:
1293 return CFn_WMDrawItem(lParam);
1294 case WM_COMMAND:
1295 return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
1296 case WM_DESTROY:
1297 return TRUE;
1298 case WM_CHOOSEFONT_GETLOGFONT:
1299 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1300 memcpy( (LOGFONTW *)lParam, lpcf->lpLogFont, sizeof(LOGFONTW) );
1301 break;
1302 case WM_PAINT:
1303 return CFn_WMPaint(hDlg, wParam, lParam, lpcf);
1305 return res;