msi: Avoid duplicate product codes in FindRelatedProducts.
[wine.git] / dlls / comdlg32 / fontdlg.c
blob9f9f48aeea232ca5e7423fb8e740d267d85a5fe8
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/heap.h"
36 #include "wine/unicode.h"
37 #include "cderr.h"
38 #include "cdlg.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
42 typedef struct
44 HWND hWnd1;
45 HWND hWnd2;
46 LPCHOOSEFONTW lpcf32w;
47 int added;
48 } CFn_ENUMSTRUCT, *LPCFn_ENUMSTRUCT;
51 static const WCHAR strWineFontData[] = {'_','_','W','I','N','E','_','F','O','N','T','D','L','G','D','A','T','A',0};
52 static const WCHAR strWineFontData_a[] =
53 {'_','_','W','I','N','E','_','F','O','N','T','D','L','G','D','A','T','A','_','A',0};
54 static const WCHAR chooseFontW[] = {'C','H','O','O','S','E','_','F','O','N','T',0};
55 static const WCHAR fontsizefmtW[] = {'%','d',0};
57 /* image list with TrueType bitmaps and more */
58 static HIMAGELIST himlTT = 0;
59 #define TTBITMAP_XSIZE 20 /* x-size of the bitmaps */
61 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
62 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
64 /* There is a table here of all charsets, and the sample text for each.
65 * There is a second table that translates a charset into an index into
66 * the first table.
69 #define CI(cs) ((IDS_CHARSET_##cs)-IDS_CHARSET_ANSI)
72 static const WCHAR stWestern[]={'A','a','B','b','Y','y','Z','z',0}; /* Western and default */
73 static const WCHAR stSymbol[]={'S','y','m','b','o','l',0}; /* Symbol */
74 static const WCHAR stShiftJis[]={'A','a',0x3042,0x3041,0x30a2,0x30a1,0x4e9c,0x5b87,0}; /* Shift JIS */
75 static const WCHAR stHangul[]={0xac00,0xb098,0xb2e4,'A','a','B','Y','y','Z','z',0}; /* Hangul */
76 static const WCHAR stGB2312[]={0x5fae,0x8f6f,0x4e2d,0x6587,0x8f6f,0x4ef6,0}; /* GB2312 */
77 static const WCHAR stBIG5[]={0x4e2d,0x6587,0x5b57,0x578b,0x7bc4,0x4f8b,0}; /* BIG5 */
78 static const WCHAR stGreek[]={'A','a','B','b',0x0391,0x03b1,0x0392,0x03b2,0}; /* Greek */
79 static const WCHAR stTurkish[]={'A','a','B','b',0x011e,0x011f,0x015e,0x015f,0}; /* Turkish */
80 static const WCHAR stHebrew[]={'A','a','B','b',0x05e0,0x05e1,0x05e9,0x05ea,0}; /* Hebrew */
81 static const WCHAR stArabic[]={'A','a','B','b',0x0627,0x0628,0x062c,0x062f,0x0647,0x0648,0x0632,0};/* Arabic */
82 static const WCHAR stBaltic[]={'A','a','B','b','Y','y','Z','z',0}; /* Baltic */
83 static const WCHAR stVietname[]={'A','a','B','b',0x01a0,0x01a1,0x01af,0x01b0,0}; /* Vietnamese */
84 static const WCHAR stCyrillic[]={'A','a','B','b',0x0411,0x0431,0x0424,0x0444,0}; /* Cyrillic */
85 static const WCHAR stEastEur[]={'A','a','B','b',0xc1,0xe1,0xd4,0xf4,0}; /* East European */
86 static const WCHAR stThai[]={'A','a','B','b',0x0e2d,0x0e31,0x0e01,0x0e29,0x0e23,0x0e44,0x0e17,0x0e22,0}; /* Thai */
87 static const WCHAR stJohab[]={0xac00,0xb098,0xb2e4,'A','a','B','Y','y','Z','z',0}; /* Johab */
88 static const WCHAR stMac[]={'A','a','B','b','Y','y','Z','z',0}; /* Mac */
89 static const WCHAR stOEM[]={'A','a','B','b',0xf8,0xf1,0xfd,0}; /* OEM */
90 /* the following character sets actually behave different (Win2K observation):
91 * the sample string is 'sticky': it uses the sample string of the previous
92 * selected character set. That behaviour looks like some default, which is
93 * not (yet) implemented. */
94 static const WCHAR stVISCII[]={'A','a','B','b',0}; /* VISCII */
95 static const WCHAR stTCVN[]={'A','a','B','b',0}; /* TCVN */
96 static const WCHAR stKOI8[]={'A','a','B','b',0}; /* KOI-8 */
97 static const WCHAR stIso88593[]={'A','a','B','b',0}; /* ISO-8859-3 */
98 static const WCHAR stIso88594[]={'A','a','B','b',0}; /* ISO-8859-4 */
99 static const WCHAR stIso885910[]={'A','a','B','b',0}; /* ISO-8859-10 */
100 static const WCHAR stCeltic[]={'A','a','B','b',0};/* Celtic */
102 static const WCHAR * const sample_lang_text[]={
103 stWestern,stSymbol,stShiftJis,stHangul,stGB2312,
104 stBIG5,stGreek,stTurkish,stHebrew,stArabic,
105 stBaltic,stVietname,stCyrillic,stEastEur,stThai,
106 stJohab,stMac,stOEM,stVISCII,stTCVN,
107 stKOI8,stIso88593,stIso88594,stIso885910,stCeltic};
110 static const BYTE CHARSET_ORDER[256]={
111 CI(ANSI), 0, CI(SYMBOL), 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, 0, 0, 0,
115 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(MAC), 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
119 CI(JIS), CI(HANGUL), CI(JOHAB), 0, 0, 0, CI(GB2312), 0, CI(BIG5), 0, 0, 0, 0, 0, 0, 0,
120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
121 0, CI(GREEK), CI(TURKISH), CI(VIETNAMESE), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
122 0, CI(HEBREW), CI(ARABIC), 0, 0, 0, 0, 0, 0, 0, CI(BALTIC), 0, 0, 0, 0, 0,
123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(RUSSIAN), 0, 0, 0,
124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(THAI), 0,
125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(EE), 0,
126 CI(VISCII), CI(TCVN), CI(KOI8), CI(ISO3), CI(ISO4), CI(ISO10), CI(CELTIC), 0, 0, 0, 0, 0, 0, 0, 0, CI(OEM),
129 static const struct {
130 DWORD mask;
131 const char *name;
132 } cfflags[] = {
133 #define XX(x) { x, #x },
134 XX(CF_SCREENFONTS)
135 XX(CF_PRINTERFONTS)
136 XX(CF_SHOWHELP)
137 XX(CF_ENABLEHOOK)
138 XX(CF_ENABLETEMPLATE)
139 XX(CF_ENABLETEMPLATEHANDLE)
140 XX(CF_INITTOLOGFONTSTRUCT)
141 XX(CF_USESTYLE)
142 XX(CF_EFFECTS)
143 XX(CF_APPLY)
144 XX(CF_ANSIONLY)
145 XX(CF_NOVECTORFONTS)
146 XX(CF_NOSIMULATIONS)
147 XX(CF_LIMITSIZE)
148 XX(CF_FIXEDPITCHONLY)
149 XX(CF_WYSIWYG)
150 XX(CF_FORCEFONTEXIST)
151 XX(CF_SCALABLEONLY)
152 XX(CF_TTONLY)
153 XX(CF_NOFACESEL)
154 XX(CF_NOSTYLESEL)
155 XX(CF_NOSIZESEL)
156 XX(CF_SELECTSCRIPT)
157 XX(CF_NOSCRIPTSEL)
158 XX(CF_NOVERTFONTS)
159 #undef XX
162 static void _dump_cf_flags(DWORD cflags)
164 unsigned int i;
166 for (i = 0; i < ARRAY_SIZE(cfflags); i++)
167 if (cfflags[i].mask & cflags)
168 TRACE("%s|",cfflags[i].name);
169 TRACE("\n");
172 /***********************************************************************
173 * ChooseFontW (COMDLG32.@)
175 * Create a font dialog box.
177 * PARAMS
178 * lpChFont [I/O] in: information to initialize the dialog box.
179 * out: User's color selection
181 * RETURNS
182 * TRUE: Ok button clicked.
183 * FALSE: Cancel button clicked, or error.
185 BOOL WINAPI ChooseFontW(LPCHOOSEFONTW lpChFont)
187 LPCVOID template;
188 HRSRC hResInfo;
189 HINSTANCE hDlginst;
190 HGLOBAL hDlgTmpl;
192 TRACE("(%p)\n", lpChFont);
194 if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 )
196 template=lpChFont->hInstance;
197 } else
199 if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 )
201 hDlginst=lpChFont->hInstance;
202 if( !(hResInfo = FindResourceW(hDlginst, lpChFont->lpTemplateName,
203 (LPWSTR)RT_DIALOG)))
205 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
206 return FALSE;
208 } else
210 hDlginst=COMDLG32_hInstance;
211 if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG)))
213 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
214 return FALSE;
217 if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) ||
218 !(template = LockResource( hDlgTmpl )))
220 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
221 return FALSE;
224 if (TRACE_ON(commdlg))
225 _dump_cf_flags(lpChFont->Flags);
227 if (lpChFont->Flags & CF_SELECTSCRIPT)
228 FIXME(": unimplemented flag (ignored)\n");
230 return DialogBoxIndirectParamW(COMDLG32_hInstance, template,
231 lpChFont->hwndOwner, FormatCharDlgProcW, (LPARAM)lpChFont );
234 /***********************************************************************
235 * ChooseFontA (COMDLG32.@)
237 * See ChooseFontW.
239 BOOL WINAPI ChooseFontA(LPCHOOSEFONTA lpChFont)
241 LPCVOID template;
242 HRSRC hResInfo;
243 HINSTANCE hDlginst;
244 HGLOBAL hDlgTmpl;
246 TRACE("(%p)\n", lpChFont);
248 if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 )
250 template=lpChFont->hInstance;
251 } else
253 if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 )
255 hDlginst=lpChFont->hInstance;
256 if( !(hResInfo = FindResourceA(hDlginst, lpChFont->lpTemplateName,
257 (LPSTR)RT_DIALOG)))
259 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
260 return FALSE;
262 } else
264 hDlginst=COMDLG32_hInstance;
265 if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG)))
267 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
268 return FALSE;
271 if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) ||
272 !(template = LockResource( hDlgTmpl )))
274 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
275 return FALSE;
278 if (TRACE_ON(commdlg))
279 _dump_cf_flags(lpChFont->Flags);
280 if (lpChFont->Flags & CF_SELECTSCRIPT)
281 FIXME(": unimplemented flag (ignored)\n");
283 return DialogBoxIndirectParamA(COMDLG32_hInstance, template,
284 lpChFont->hwndOwner, FormatCharDlgProcA, (LPARAM)lpChFont );
287 #define TEXT_EXTRAS 4
288 #define TEXT_COLORS 16
290 static const COLORREF textcolors[TEXT_COLORS]=
292 0x00000000L,0x00000080L,0x00008000L,0x00008080L,
293 0x00800000L,0x00800080L,0x00808000L,0x00808080L,
294 0x00c0c0c0L,0x000000ffL,0x0000ff00L,0x0000ffffL,
295 0x00ff0000L,0x00ff00ffL,0x00ffff00L,0x00FFFFFFL
298 /***********************************************************************
299 * CFn_HookCallChk32 [internal]
301 static BOOL CFn_HookCallChk32(const CHOOSEFONTW *lpcf)
303 if (lpcf)
304 if(lpcf->Flags & CF_ENABLEHOOK)
305 if (lpcf->lpfnHook)
306 return TRUE;
307 return FALSE;
310 /*************************************************************************
311 * AddFontFamily [internal]
313 static INT AddFontFamily(const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM,
314 UINT nFontType, const CHOOSEFONTW *lpcf, HWND hwnd, LPCFn_ENUMSTRUCT e)
316 int i;
317 WORD w;
318 const LOGFONTW *lplf = &(lpElfex->elfLogFont);
320 TRACE("font=%s (nFontType=%d)\n", debugstr_w(lplf->lfFaceName), nFontType);
322 if (lpcf->Flags & CF_FIXEDPITCHONLY)
323 if (!(lplf->lfPitchAndFamily & FIXED_PITCH))
324 return 1;
325 if (lpcf->Flags & CF_ANSIONLY)
326 if (lplf->lfCharSet != ANSI_CHARSET)
327 return 1;
328 if (lpcf->Flags & CF_TTONLY)
329 if (!(nFontType & TRUETYPE_FONTTYPE))
330 return 1;
331 if (lpcf->Flags & CF_NOVERTFONTS)
332 if (lplf->lfFaceName[0] == '@')
333 return 1;
335 if (e) e->added++;
337 i=SendMessageW(hwnd, CB_FINDSTRINGEXACT, 0, (LPARAM)lplf->lfFaceName);
338 if (i == CB_ERR) {
339 i = SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)lplf->lfFaceName);
340 if( i != CB_ERR) {
341 /* store some important font information */
342 w = (lplf->lfPitchAndFamily) << 8 |
343 (HIWORD(lpNTM->ntmTm.ntmFlags) & 0xff);
344 SendMessageW(hwnd, CB_SETITEMDATA, i, MAKELONG(nFontType,w));
347 return 1;
350 /*************************************************************************
351 * FontFamilyEnumProc32 [internal]
353 static INT WINAPI FontFamilyEnumProc(const ENUMLOGFONTEXW *lpElfex,
354 const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam)
356 LPCFn_ENUMSTRUCT e;
357 e=(LPCFn_ENUMSTRUCT)lParam;
358 return AddFontFamily( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
359 dwFontType, e->lpcf32w, e->hWnd1, e);
362 /*************************************************************************
363 * SetFontStylesToCombo2 [internal]
365 * Fill font style information into combobox (without using font.c directly)
367 static BOOL SetFontStylesToCombo2(HWND hwnd, HDC hdc, const LOGFONTW *lplf)
369 #define FSTYLES 4
370 struct FONTSTYLE
372 int italic;
373 int weight;
374 UINT resId;
376 static const struct FONTSTYLE fontstyles[FSTYLES]={
377 { 0, FW_NORMAL, IDS_FONT_REGULAR },
378 { 1, FW_NORMAL, IDS_FONT_ITALIC },
379 { 0, FW_BOLD, IDS_FONT_BOLD },
380 { 1, FW_BOLD, IDS_FONT_BOLD_ITALIC }
382 HFONT hf;
383 TEXTMETRICW tm;
384 int i,j;
385 LOGFONTW lf;
387 lf = *lplf;
389 for (i=0;i<FSTYLES;i++)
391 lf.lfItalic=fontstyles[i].italic;
392 lf.lfWeight=fontstyles[i].weight;
393 hf=CreateFontIndirectW(&lf);
394 hf=SelectObject(hdc,hf);
395 GetTextMetricsW(hdc,&tm);
396 hf=SelectObject(hdc,hf);
397 DeleteObject(hf);
398 /* font successful created ? */
399 if (((fontstyles[i].weight == FW_NORMAL && tm.tmWeight <= FW_MEDIUM) ||
400 (fontstyles[i].weight == FW_BOLD && tm.tmWeight > FW_MEDIUM)) &&
401 ((tm.tmItalic != 0)==fontstyles[i].italic))
403 WCHAR name[64];
404 LoadStringW(COMDLG32_hInstance, fontstyles[i].resId, name, 64);
405 j=SendMessageW(hwnd,CB_ADDSTRING,0,(LPARAM)name );
406 if (j==CB_ERR) return TRUE;
407 j=SendMessageW(hwnd, CB_SETITEMDATA, j,
408 MAKELONG(tm.tmWeight,fontstyles[i].italic));
409 if (j==CB_ERR) return TRUE;
412 return FALSE;
415 /*************************************************************************
416 * AddFontSizeToCombo3 [internal]
418 static BOOL AddFontSizeToCombo3(HWND hwnd, UINT h, const CHOOSEFONTW *lpcf)
420 int j;
421 WCHAR buffer[20];
423 if ( (!(lpcf->Flags & CF_LIMITSIZE)) ||
424 ((lpcf->Flags & CF_LIMITSIZE) && (h >= lpcf->nSizeMin) && (h <= lpcf->nSizeMax)))
426 sprintfW(buffer, fontsizefmtW, h);
427 j=SendMessageW(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)buffer);
428 if (j==CB_ERR)
430 j=SendMessageW(hwnd, CB_INSERTSTRING, -1, (LPARAM)buffer);
431 if (j!=CB_ERR) j = SendMessageW(hwnd, CB_SETITEMDATA, j, h);
432 if (j==CB_ERR) return TRUE;
435 return FALSE;
438 /*************************************************************************
439 * SetFontSizesToCombo3 [internal]
441 static BOOL SetFontSizesToCombo3(HWND hwnd, const CHOOSEFONTW *lpcf)
443 static const BYTE sizes[]={6,7,8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
444 unsigned int i;
446 for (i = 0; i < ARRAY_SIZE(sizes); i++)
447 if (AddFontSizeToCombo3(hwnd, sizes[i], lpcf)) return TRUE;
448 return FALSE;
451 /*************************************************************************
452 * CFn_GetDC [internal]
454 static inline HDC CFn_GetDC(const CHOOSEFONTW *lpcf)
456 HDC ret = ((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC) ?
457 lpcf->hDC :
458 GetDC(0);
459 if(!ret) ERR("HDC failure!!!\n");
460 return ret;
463 /*************************************************************************
464 * GetScreenDPI [internal]
466 static inline int GetScreenDPI(void)
468 HDC hdc;
469 int result;
471 hdc = GetDC(0);
472 result = GetDeviceCaps(hdc, LOGPIXELSY);
473 ReleaseDC(0, hdc);
475 return result;
478 /*************************************************************************
479 * CFn_ReleaseDC [internal]
481 static inline void CFn_ReleaseDC(const CHOOSEFONTW *lpcf, HDC hdc)
483 if(!((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC))
484 ReleaseDC(0, hdc);
487 /*************************************************************************
488 * select_combo_item [internal]
490 static void select_combo_item( HWND dialog, int id, int sel )
492 HWND combo = GetDlgItem( dialog, id );
493 SendMessageW( combo, CB_SETCURSEL, sel, 0 );
494 SendMessageW( dialog, WM_COMMAND, MAKEWPARAM( id, CBN_SELCHANGE ), (LPARAM)combo );
497 /***********************************************************************
498 * AddFontStyle [internal]
500 static INT AddFontStyle( const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM,
501 UINT nFontType, const CHOOSEFONTW *lpcf, HWND hcmb2, HWND hcmb3, HWND hDlg)
503 int i;
504 const LOGFONTW *lplf = &(lpElfex->elfLogFont);
505 HWND hcmb5;
506 HDC hdc;
508 TRACE("(nFontType=%d)\n",nFontType);
509 TRACE(" %s h=%d w=%d e=%d o=%d wg=%d i=%d u=%d s=%d"
510 " ch=%d op=%d cp=%d q=%d pf=%xh\n",
511 debugstr_w(lplf->lfFaceName),lplf->lfHeight,lplf->lfWidth,
512 lplf->lfEscapement,lplf->lfOrientation,
513 lplf->lfWeight,lplf->lfItalic,lplf->lfUnderline,
514 lplf->lfStrikeOut,lplf->lfCharSet, lplf->lfOutPrecision,
515 lplf->lfClipPrecision,lplf->lfQuality, lplf->lfPitchAndFamily);
516 if (nFontType & RASTER_FONTTYPE)
518 INT points;
519 points = MulDiv( lpNTM->ntmTm.tmHeight - lpNTM->ntmTm.tmInternalLeading,
520 72, GetScreenDPI());
521 if (AddFontSizeToCombo3(hcmb3, points, lpcf))
522 return 0;
523 } else if (SetFontSizesToCombo3(hcmb3, lpcf)) return 0;
525 if (!SendMessageW(hcmb2, CB_GETCOUNT, 0, 0))
527 BOOL res;
528 if(!(hdc = CFn_GetDC(lpcf))) return 0;
529 res = SetFontStylesToCombo2(hcmb2,hdc,lplf);
530 CFn_ReleaseDC(lpcf, hdc);
531 if (res)
532 return 0;
534 if (!( hcmb5 = GetDlgItem(hDlg, cmb5))) return 1;
535 i = SendMessageW( hcmb5, CB_FINDSTRINGEXACT, 0,
536 (LPARAM)lpElfex->elfScript);
537 if( i == CB_ERR) {
538 i = SendMessageW( hcmb5, CB_ADDSTRING, 0,
539 (LPARAM)lpElfex->elfScript);
540 if( i != CB_ERR)
541 SendMessageW( hcmb5, CB_SETITEMDATA, i, lplf->lfCharSet);
543 return 1 ;
546 static void CFn_FitFontSize( HWND hDlg, int points)
548 int i,n;
550 /* look for fitting font size in combobox3 */
551 n=SendDlgItemMessageW(hDlg, cmb3, CB_GETCOUNT, 0, 0);
552 for (i=0;i<n;i++)
554 if (points == (int)SendDlgItemMessageW
555 (hDlg,cmb3, CB_GETITEMDATA,i,0))
557 select_combo_item( hDlg, cmb3, i );
558 return;
562 /* no default matching size, set text manually */
563 SetDlgItemInt(hDlg, cmb3, points, TRUE);
566 static BOOL CFn_FitFontStyle( HWND hDlg, LONG packedstyle )
568 LONG id;
569 int i;
570 /* look for fitting font style in combobox2 */
571 for (i=0;i<TEXT_EXTRAS;i++)
573 id = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
574 if (packedstyle == id)
576 select_combo_item( hDlg, cmb2, i );
577 return TRUE;
580 return FALSE;
584 static BOOL CFn_FitCharSet( HWND hDlg, int charset )
586 int i,n,cs;
587 /* look for fitting char set in combobox5 */
588 n=SendDlgItemMessageW(hDlg, cmb5, CB_GETCOUNT, 0, 0);
589 for (i=0;i<n;i++)
591 cs =SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
592 if (charset == cs)
594 select_combo_item( hDlg, cmb5, i );
595 return TRUE;
598 /* no charset fits: select the first one in the list */
599 select_combo_item( hDlg, cmb5, 0 );
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 ARRAY_SIZE(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 select_combo_item( hDlg, cmb1, j );
733 init = TRUE;
734 /* look for fitting font style in combobox2 */
735 CFn_FitFontStyle(hDlg, pstyle);
736 /* look for fitting font size in combobox3 */
737 CFn_FitFontSize(hDlg, points);
738 CFn_FitCharSet( hDlg, charset );
741 if (!init)
743 select_combo_item( hDlg, cmb1, 0 );
744 select_combo_item( hDlg, cmb2, 0 );
745 select_combo_item( hDlg, cmb3, 0 );
746 select_combo_item( hDlg, cmb5, 0 );
748 /* limit text length user can type in as font size */
749 SendDlgItemMessageW(hDlg, cmb3, CB_LIMITTEXT, 5, 0);
751 if ((lpcf->Flags & CF_USESTYLE) && lpcf->lpszStyle)
753 j=SendDlgItemMessageW(hDlg,cmb2,CB_FINDSTRING,-1,(LPARAM)lpcf->lpszStyle);
754 if (j!=CB_ERR) select_combo_item( hDlg, cmb2, j );
756 CFn_ReleaseDC(lpcf, hdc);
757 SetCursor(hcursor);
758 return TRUE;
762 /***********************************************************************
763 * CFn_WMMeasureItem [internal]
765 static LRESULT CFn_WMMeasureItem(HWND hDlg, LPARAM lParam)
767 HDC hdc;
768 HFONT hfontprev;
769 TEXTMETRICW tm;
770 LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam;
771 INT height = 0, cx;
773 if (!himlTT)
774 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
775 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
776 ImageList_GetIconSize( himlTT, &cx, &height);
777 lpmi->itemHeight = height + 2;
778 /* use MAX of bitmap height and tm.tmHeight .*/
779 hdc=GetDC(hDlg);
780 if(!hdc) return 0;
781 hfontprev = SelectObject( hdc, (HFONT)SendMessageW( hDlg, WM_GETFONT, 0, 0 ));
782 GetTextMetricsW(hdc, &tm);
783 if( tm.tmHeight > lpmi->itemHeight) lpmi->itemHeight = tm.tmHeight;
784 SelectObject(hdc, hfontprev);
785 ReleaseDC(hDlg, hdc);
786 return 0;
790 /***********************************************************************
791 * CFn_WMDrawItem [internal]
793 static LRESULT CFn_WMDrawItem(LPARAM lParam)
795 HBRUSH hBrush;
796 WCHAR buffer[40];
797 COLORREF cr, oldText=0, oldBk=0;
798 RECT rect;
799 int nFontType;
800 int cx, cy, idx;
801 LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam;
803 if (lpdi->itemID == (UINT)-1) /* got no items */
804 DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
805 else
807 if (lpdi->CtlType == ODT_COMBOBOX)
809 if (lpdi->itemState & ODS_SELECTED)
811 hBrush=GetSysColorBrush(COLOR_HIGHLIGHT);
812 oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
813 oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT));
814 } else
816 hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
817 SelectObject(lpdi->hDC, hBrush);
819 FillRect(lpdi->hDC, &lpdi->rcItem, hBrush);
821 else
822 return TRUE; /* this should never happen */
824 rect=lpdi->rcItem;
825 switch (lpdi->CtlID)
827 case cmb1:
828 /* TRACE(commdlg,"WM_Drawitem cmb1\n"); */
829 ImageList_GetIconSize( himlTT, &cx, &cy);
830 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
831 (LPARAM)buffer);
832 TextOutW(lpdi->hDC, lpdi->rcItem.left + cx + 4,
833 lpdi->rcItem.top, buffer, lstrlenW(buffer));
834 nFontType = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
835 idx = -1;
836 if (nFontType & TRUETYPE_FONTTYPE) {
837 idx = 0; /* picture: TT */
838 if( nFontType & NTM_TT_OPENTYPE)
839 idx = 2; /* picture: O */
840 } else if( nFontType & NTM_PS_OPENTYPE)
841 idx = 3; /* picture: O+ps */
842 else if( nFontType & NTM_TYPE1)
843 idx = 4; /* picture: a */
844 else if( nFontType & DEVICE_FONTTYPE)
845 idx = 1; /* picture: printer */
846 if( idx >= 0)
847 ImageList_Draw( himlTT, idx, lpdi->hDC, lpdi->rcItem.left,
848 (lpdi->rcItem.top + lpdi->rcItem.bottom - cy) / 2, ILD_TRANSPARENT);
849 break;
850 case cmb2:
851 case cmb3:
852 /* TRACE(commdlg,"WM_DRAWITEN cmb2,cmb3\n"); */
853 case cmb5:
854 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
855 (LPARAM)buffer);
856 TextOutW(lpdi->hDC, lpdi->rcItem.left,
857 lpdi->rcItem.top, buffer, lstrlenW(buffer));
858 break;
860 case cmb4:
861 /* TRACE(commdlg,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
862 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
863 (LPARAM)buffer);
864 TextOutW(lpdi->hDC, lpdi->rcItem.left + 25+5,
865 lpdi->rcItem.top, buffer, lstrlenW(buffer));
866 cr = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
867 hBrush = CreateSolidBrush(cr);
868 if (hBrush)
870 hBrush = SelectObject (lpdi->hDC, hBrush) ;
871 rect.right=rect.left+25;
872 rect.top++;
873 rect.left+=5;
874 rect.bottom--;
875 Rectangle( lpdi->hDC, rect.left, rect.top,
876 rect.right, rect.bottom );
877 DeleteObject( SelectObject (lpdi->hDC, hBrush)) ;
879 rect=lpdi->rcItem;
880 rect.left+=25+5;
881 break;
883 default:
884 return TRUE; /* this should never happen */
886 if (lpdi->itemState & ODS_SELECTED)
888 SetTextColor(lpdi->hDC, oldText);
889 SetBkColor(lpdi->hDC, oldBk);
892 return TRUE;
895 static INT get_dialog_font_point_size(HWND hDlg, CHOOSEFONTW *cf)
897 BOOL invalid_size = FALSE;
898 INT i, size;
900 i = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
901 if (i != CB_ERR)
902 size = LOWORD(SendDlgItemMessageW(hDlg, cmb3, CB_GETITEMDATA , i, 0));
903 else
905 WCHAR buffW[8], *endptrW;
907 GetDlgItemTextW(hDlg, cmb3, buffW, ARRAY_SIZE(buffW));
908 size = strtolW(buffW, &endptrW, 10);
909 invalid_size = size == 0 && *endptrW;
911 if (size == 0)
912 size = 10;
915 cf->iPointSize = 10 * size;
916 cf->lpLogFont->lfHeight = -MulDiv(cf->iPointSize, GetScreenDPI(), 720);
917 return invalid_size ? -1 : size;
920 /***********************************************************************
921 * CFn_WMCommand [internal]
923 static LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcf)
925 int i;
926 long l;
927 HDC hdc;
928 BOOL cmb_selected_by_edit = FALSE;
930 if (!lpcf) return FALSE;
932 if(HIWORD(wParam) == CBN_EDITCHANGE)
934 int idx;
935 WCHAR str_edit[256], str_cmb[256];
936 int cmb = LOWORD(wParam);
938 GetDlgItemTextW(hDlg, cmb, str_edit, ARRAY_SIZE(str_edit));
939 idx = SendDlgItemMessageW(hDlg, cmb, CB_FINDSTRING, -1, (LPARAM)str_edit);
940 if(idx != -1)
942 SendDlgItemMessageW(hDlg, cmb, CB_GETLBTEXT, idx, (LPARAM)str_cmb);
944 /* Select listbox entry only if we have an exact match */
945 if(lstrcmpiW(str_edit, str_cmb) == 0)
947 SendDlgItemMessageW(hDlg, cmb, CB_SETCURSEL, idx, 0);
948 SendDlgItemMessageW(hDlg, cmb, CB_SETEDITSEL, 0, -1); /* Remove edit field selection */
949 cmb_selected_by_edit = TRUE;
954 TRACE("WM_COMMAND wParam=%08X lParam=%08lX\n", (LONG)wParam, lParam);
955 switch (LOWORD(wParam))
957 case cmb1:
958 if (HIWORD(wParam) == CBN_SELCHANGE || cmb_selected_by_edit)
960 INT pointsize; /* save current pointsize */
961 LONG pstyle; /* save current style */
962 int charset;
963 int idx;
964 if(!(hdc = CFn_GetDC(lpcf)))
966 EndDialog (hDlg, 0);
967 return TRUE;
969 idx = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
970 pointsize = (int)SendDlgItemMessageW( hDlg, cmb3, CB_GETITEMDATA,
971 idx, 0);
972 idx = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
973 pstyle = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, idx, 0);
974 idx = SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
975 charset = SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, idx, 0);
977 SendDlgItemMessageW(hDlg, cmb2, CB_RESETCONTENT, 0, 0);
978 SendDlgItemMessageW(hDlg, cmb3, CB_RESETCONTENT, 0, 0);
979 SendDlgItemMessageW(hDlg, cmb5, CB_RESETCONTENT, 0, 0);
980 i=SendDlgItemMessageW(hDlg, cmb1, CB_GETCURSEL, 0, 0);
981 if (i!=CB_ERR)
983 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
984 CFn_ENUMSTRUCT s;
985 LOGFONTW enumlf;
986 SendDlgItemMessageW(hDlg, cmb1, CB_GETLBTEXT, i,
987 (LPARAM)enumlf.lfFaceName);
988 TRACE("WM_COMMAND/cmb1 =>%s\n", debugstr_w(enumlf.lfFaceName));
989 s.hWnd1=GetDlgItem(hDlg, cmb2);
990 s.hWnd2=GetDlgItem(hDlg, cmb3);
991 s.lpcf32w=lpcf;
992 enumlf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
993 enumlf.lfPitchAndFamily = 0;
994 EnumFontFamiliesExW(hdc, &enumlf,
995 (FONTENUMPROCW)FontStyleEnumProc, (LPARAM)&s, 0);
996 CFn_FitFontStyle(hDlg, pstyle);
997 if( pointsize != CB_ERR) CFn_FitFontSize(hDlg, pointsize);
998 if( charset != CB_ERR) CFn_FitCharSet( hDlg, charset );
999 SetCursor(hcursor);
1001 CFn_ReleaseDC(lpcf, hdc);
1003 break;
1004 case chx1:
1005 case chx2:
1006 case cmb2:
1007 case cmb3:
1008 case cmb5:
1009 if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == BN_CLICKED || cmb_selected_by_edit)
1011 WCHAR str[256];
1012 WINDOWINFO wininfo;
1013 LPLOGFONTW lpxx=lpcf->lpLogFont;
1015 TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
1017 /* face name */
1018 i=SendDlgItemMessageW(hDlg,cmb1,CB_GETCURSEL,0,0);
1019 if (i==CB_ERR)
1020 GetDlgItemTextW( hDlg, cmb1, str, ARRAY_SIZE(str));
1021 else
1023 SendDlgItemMessageW(hDlg,cmb1,CB_GETLBTEXT,i,
1024 (LPARAM)str);
1025 l=SendDlgItemMessageW(hDlg,cmb1,CB_GETITEMDATA,i,0);
1026 lpcf->nFontType = LOWORD(l);
1027 /* FIXME: lpcf->nFontType |= .... SIMULATED_FONTTYPE and so */
1028 /* same value reported to the EnumFonts
1029 call back with the extra FONTTYPE_... bits added */
1030 lpxx->lfPitchAndFamily = HIWORD(l) >> 8;
1032 lstrcpynW(lpxx->lfFaceName, str, ARRAY_SIZE(lpxx->lfFaceName));
1034 /* style */
1035 i=SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
1036 if (i!=CB_ERR)
1038 l=SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
1039 if (0!=(lpxx->lfItalic=HIWORD(l)))
1040 lpcf->nFontType |= ITALIC_FONTTYPE;
1041 if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
1042 lpcf->nFontType |= BOLD_FONTTYPE;
1045 /* size */
1046 get_dialog_font_point_size(hDlg, lpcf);
1048 /* charset */
1049 i=SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
1050 if (i!=CB_ERR)
1051 lpxx->lfCharSet=SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
1052 else
1053 lpxx->lfCharSet = DEFAULT_CHARSET;
1054 lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
1055 lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
1056 lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
1057 lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
1058 lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
1059 lpxx->lfQuality=DEFAULT_QUALITY;
1061 wininfo.cbSize=sizeof(wininfo);
1063 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1065 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1066 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1069 break;
1071 case cmb4:
1072 i=SendDlgItemMessageW(hDlg, cmb4, CB_GETCURSEL, 0, 0);
1073 if (i!=CB_ERR)
1075 WINDOWINFO wininfo;
1077 lpcf->rgbColors = SendDlgItemMessageW(hDlg, cmb4, CB_GETITEMDATA, i, 0);
1078 wininfo.cbSize=sizeof(wininfo);
1080 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1082 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1083 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1086 break;
1088 case psh15:
1089 i=RegisterWindowMessageW( HELPMSGSTRINGW );
1090 if (lpcf->hwndOwner)
1091 SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData));
1092 break;
1094 case IDOK:
1096 WCHAR msgW[80];
1097 INT pointsize;
1099 pointsize = get_dialog_font_point_size(hDlg, lpcf);
1100 if (pointsize == -1)
1102 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE_INPUT, msgW, ARRAY_SIZE(msgW));
1103 MessageBoxW(hDlg, msgW, NULL, MB_OK | MB_ICONINFORMATION);
1104 return TRUE;
1107 if ( (!(lpcf->Flags & CF_LIMITSIZE)) ||
1108 ( (lpcf->Flags & CF_LIMITSIZE) &&
1109 (lpcf->iPointSize >= 10 * lpcf->nSizeMin) &&
1110 (lpcf->iPointSize <= 10 * lpcf->nSizeMax)))
1111 EndDialog(hDlg, TRUE);
1112 else
1114 WCHAR format[80];
1115 DWORD_PTR args[2];
1116 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE, format, ARRAY_SIZE(format));
1117 args[0] = lpcf->nSizeMin;
1118 args[1] = lpcf->nSizeMax;
1119 FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
1120 format, 0, 0, msgW, ARRAY_SIZE(msgW),
1121 (__ms_va_list*)args);
1122 MessageBoxW(hDlg, msgW, NULL, MB_OK);
1124 return(TRUE);
1126 case IDCANCEL:
1127 EndDialog(hDlg, FALSE);
1128 return(TRUE);
1130 return(FALSE);
1133 static LRESULT CFn_WMDestroy(HWND hwnd, LPCHOOSEFONTW lpcfw)
1135 LPCHOOSEFONTA lpcfa;
1136 LPSTR lpszStyle;
1137 LPLOGFONTA lpLogFonta;
1138 int len;
1140 if (!lpcfw) return FALSE;
1142 lpcfa = GetPropW(hwnd, strWineFontData_a);
1143 lpLogFonta = lpcfa->lpLogFont;
1144 lpszStyle = lpcfa->lpszStyle;
1145 memcpy(lpcfa, lpcfw, sizeof(CHOOSEFONTA));
1146 lpcfa->lpLogFont = lpLogFonta;
1147 lpcfa->lpszStyle = lpszStyle;
1148 memcpy(lpcfa->lpLogFont, lpcfw->lpLogFont, sizeof(LOGFONTA));
1149 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName,
1150 LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0);
1152 if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) {
1153 len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, 0, 0, 0);
1154 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0);
1155 heap_free(lpcfw->lpszStyle);
1158 heap_free(lpcfw->lpLogFont);
1159 heap_free(lpcfw);
1160 SetPropW(hwnd, strWineFontData, 0);
1162 return TRUE;
1165 static LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW *lpcf)
1167 WINDOWINFO info;
1169 if (!lpcf) return FALSE;
1171 info.cbSize=sizeof(info);
1172 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &info ) )
1174 PAINTSTRUCT ps;
1175 HDC hdc;
1176 HFONT hOrigFont;
1177 LOGFONTW lf = *(lpcf->lpLogFont);
1179 MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2);
1180 hdc = BeginPaint( hDlg, &ps );
1182 TRACE("erase %d, rect=%s\n", ps.fErase, wine_dbgstr_rect(&ps.rcPaint));
1184 /* Paint frame */
1185 DrawEdge( hdc, &info.rcWindow, EDGE_SUNKEN, BF_RECT|BF_ADJUST );
1187 /* Draw the sample text itself */
1188 hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
1189 SetTextColor( hdc, lpcf->rgbColors );
1191 DrawTextW( hdc,
1192 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]],
1193 -1, &info.rcWindow, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
1195 DeleteObject(SelectObject( hdc, hOrigFont ));
1196 EndPaint( hDlg, &ps );
1198 return FALSE;
1201 /***********************************************************************
1202 * FormatCharDlgProcA [internal]
1204 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1206 LPCHOOSEFONTW lpcfw;
1207 LPCHOOSEFONTA lpcfa;
1208 INT_PTR res = FALSE;
1209 int len;
1211 if (uMsg!=WM_INITDIALOG) {
1212 lpcfw = GetPropW(hDlg, strWineFontData);
1213 if (lpcfw && CFn_HookCallChk32(lpcfw))
1214 res=CallWindowProcA((WNDPROC)lpcfw->lpfnHook, hDlg, uMsg, wParam, lParam);
1215 if (res)
1216 return res;
1217 } else {
1218 lpcfa=(LPCHOOSEFONTA)lParam;
1219 SetPropW(hDlg, strWineFontData_a, (HANDLE)lParam);
1221 lpcfw = heap_alloc(sizeof(*lpcfw));
1222 memcpy(lpcfw, lpcfa, sizeof(CHOOSEFONTA));
1223 lpcfw->lpLogFont = heap_alloc(sizeof(*lpcfw->lpLogFont));
1224 memcpy(lpcfw->lpLogFont, lpcfa->lpLogFont, sizeof(LOGFONTA));
1225 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpLogFont->lfFaceName,
1226 LF_FACESIZE, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE);
1228 if((lpcfa->Flags & CF_USESTYLE) && lpcfa->lpszStyle) {
1229 len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, NULL, 0);
1230 lpcfw->lpszStyle = heap_alloc(len * sizeof(WCHAR));
1231 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len);
1234 if (!CFn_WMInitDialog(hDlg, lParam, lpcfw))
1236 TRACE("CFn_WMInitDialog returned FALSE\n");
1237 return FALSE;
1239 if (CFn_HookCallChk32(lpcfw))
1240 return CallWindowProcA((WNDPROC)lpcfa->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1242 switch (uMsg)
1244 case WM_MEASUREITEM:
1245 return CFn_WMMeasureItem(hDlg,lParam);
1246 case WM_DRAWITEM:
1247 return CFn_WMDrawItem(lParam);
1248 case WM_COMMAND:
1249 return CFn_WMCommand(hDlg, wParam, lParam, lpcfw);
1250 case WM_DESTROY:
1251 return CFn_WMDestroy(hDlg, lpcfw);
1252 case WM_CHOOSEFONT_GETLOGFONT:
1254 LOGFONTA *logfont = (LOGFONTA *)lParam;
1255 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1256 memcpy( logfont, lpcfw->lpLogFont, FIELD_OFFSET( LOGFONTA, lfFaceName ));
1257 WideCharToMultiByte( CP_ACP, 0, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE,
1258 logfont->lfFaceName, LF_FACESIZE, NULL, NULL );
1259 break;
1261 case WM_PAINT:
1262 return CFn_WMPaint(hDlg, wParam, lParam, lpcfw);
1264 return res;
1267 /***********************************************************************
1268 * FormatCharDlgProcW [internal]
1270 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1272 LPCHOOSEFONTW lpcf;
1273 INT_PTR res = FALSE;
1275 if (uMsg!=WM_INITDIALOG)
1277 lpcf= GetPropW(hDlg, strWineFontData);
1278 if (lpcf && CFn_HookCallChk32(lpcf))
1279 res=CallWindowProcW((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam);
1280 if (res)
1281 return res;
1283 else
1285 lpcf=(LPCHOOSEFONTW)lParam;
1286 if (!CFn_WMInitDialog(hDlg, lParam, lpcf))
1288 TRACE("CFn_WMInitDialog returned FALSE\n");
1289 return FALSE;
1291 if (CFn_HookCallChk32(lpcf))
1292 return CallWindowProcW((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1294 switch (uMsg)
1296 case WM_MEASUREITEM:
1297 return CFn_WMMeasureItem(hDlg, lParam);
1298 case WM_DRAWITEM:
1299 return CFn_WMDrawItem(lParam);
1300 case WM_COMMAND:
1301 return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
1302 case WM_DESTROY:
1303 return TRUE;
1304 case WM_CHOOSEFONT_GETLOGFONT:
1305 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1306 memcpy( (LOGFONTW *)lParam, lpcf->lpLogFont, sizeof(LOGFONTW) );
1307 break;
1308 case WM_PAINT:
1309 return CFn_WMPaint(hDlg, wParam, lParam, lpcf);
1311 return res;