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