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