[WLNOTIFY] Disable the Logoff-Handler routine for the scheduler service.
[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/heap.h"
36 #include "wine/unicode.h"
37 #include "cderr.h"
38 #include "cdlg.h"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
41
42 typedef struct
43 {
44 HWND hWnd1;
45 HWND hWnd2;
46 LPCHOOSEFONTW lpcf32w;
47 int added;
48 } CFn_ENUMSTRUCT, *LPCFn_ENUMSTRUCT;
49
50
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};
56
57 /* image list with TrueType bitmaps and more */
58 static HIMAGELIST himlTT = 0;
59 #define TTBITMAP_XSIZE 20 /* x-size of the bitmaps */
60
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);
63
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.
67 */
68
69 #define CI(cs) ((IDS_CHARSET_##cs)-IDS_CHARSET_ANSI)
70
71
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 */
101
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};
108
109
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),
127 };
128
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
160 };
161
162 static void _dump_cf_flags(DWORD cflags)
163 {
164 unsigned int i;
165
166 for (i = 0; i < ARRAY_SIZE(cfflags); i++)
167 if (cfflags[i].mask & cflags)
168 TRACE("%s|",cfflags[i].name);
169 TRACE("\n");
170 }
171
172 /***********************************************************************
173 * ChooseFontW (COMDLG32.@)
174 *
175 * Create a font dialog box.
176 *
177 * PARAMS
178 * lpChFont [I/O] in: information to initialize the dialog box.
179 * out: User's color selection
180 *
181 * RETURNS
182 * TRUE: Ok button clicked.
183 * FALSE: Cancel button clicked, or error.
184 */
185 BOOL WINAPI ChooseFontW(LPCHOOSEFONTW lpChFont)
186 {
187 LPCVOID template;
188 HRSRC hResInfo;
189 HINSTANCE hDlginst;
190 HGLOBAL hDlgTmpl;
191
192 TRACE("(%p)\n", lpChFont);
193
194 if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 )
195 {
196 template=lpChFont->hInstance;
197 } else
198 {
199 if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 )
200 {
201 hDlginst=lpChFont->hInstance;
202 if( !(hResInfo = FindResourceW(hDlginst, lpChFont->lpTemplateName,
203 (LPWSTR)RT_DIALOG)))
204 {
205 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
206 return FALSE;
207 }
208 } else
209 {
210 hDlginst=COMDLG32_hInstance;
211 if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG)))
212 {
213 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
214 return FALSE;
215 }
216 }
217 if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) ||
218 !(template = LockResource( hDlgTmpl )))
219 {
220 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
221 return FALSE;
222 }
223 }
224 if (TRACE_ON(commdlg))
225 _dump_cf_flags(lpChFont->Flags);
226
227 if (lpChFont->Flags & CF_SELECTSCRIPT)
228 FIXME(": unimplemented flag (ignored)\n");
229
230 return DialogBoxIndirectParamW(COMDLG32_hInstance, template,
231 lpChFont->hwndOwner, FormatCharDlgProcW, (LPARAM)lpChFont );
232 }
233
234 /***********************************************************************
235 * ChooseFontA (COMDLG32.@)
236 *
237 * See ChooseFontW.
238 */
239 BOOL WINAPI ChooseFontA(LPCHOOSEFONTA lpChFont)
240 {
241 LPCVOID template;
242 HRSRC hResInfo;
243 HINSTANCE hDlginst;
244 HGLOBAL hDlgTmpl;
245
246 TRACE("(%p)\n", lpChFont);
247
248 if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 )
249 {
250 template=lpChFont->hInstance;
251 } else
252 {
253 if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 )
254 {
255 hDlginst=lpChFont->hInstance;
256 if( !(hResInfo = FindResourceA(hDlginst, lpChFont->lpTemplateName,
257 (LPSTR)RT_DIALOG)))
258 {
259 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
260 return FALSE;
261 }
262 } else
263 {
264 hDlginst=COMDLG32_hInstance;
265 if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG)))
266 {
267 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
268 return FALSE;
269 }
270 }
271 if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) ||
272 !(template = LockResource( hDlgTmpl )))
273 {
274 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
275 return FALSE;
276 }
277 }
278 if (TRACE_ON(commdlg))
279 _dump_cf_flags(lpChFont->Flags);
280 if (lpChFont->Flags & CF_SELECTSCRIPT)
281 FIXME(": unimplemented flag (ignored)\n");
282
283 return DialogBoxIndirectParamA(COMDLG32_hInstance, template,
284 lpChFont->hwndOwner, FormatCharDlgProcA, (LPARAM)lpChFont );
285 }
286
287 #define TEXT_EXTRAS 4
288 #define TEXT_COLORS 16
289
290 static const COLORREF textcolors[TEXT_COLORS]=
291 {
292 0x00000000L,0x00000080L,0x00008000L,0x00008080L,
293 0x00800000L,0x00800080L,0x00808000L,0x00808080L,
294 0x00c0c0c0L,0x000000ffL,0x0000ff00L,0x0000ffffL,
295 0x00ff0000L,0x00ff00ffL,0x00ffff00L,0x00FFFFFFL
296 };
297
298 /***********************************************************************
299 * CFn_HookCallChk32 [internal]
300 */
301 static BOOL CFn_HookCallChk32(const CHOOSEFONTW *lpcf)
302 {
303 if (lpcf)
304 if(lpcf->Flags & CF_ENABLEHOOK)
305 if (lpcf->lpfnHook)
306 return TRUE;
307 return FALSE;
308 }
309
310 /*************************************************************************
311 * AddFontFamily [internal]
312 */
313 static INT AddFontFamily(const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM,
314 UINT nFontType, const CHOOSEFONTW *lpcf, HWND hwnd, LPCFn_ENUMSTRUCT e)
315 {
316 int i;
317 WORD w;
318 const LOGFONTW *lplf = &(lpElfex->elfLogFont);
319
320 TRACE("font=%s (nFontType=%d)\n", debugstr_w(lplf->lfFaceName), nFontType);
321
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;
334
335 if (e) e->added++;
336
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));
345 }
346 }
347 return 1;
348 }
349
350 /*************************************************************************
351 * FontFamilyEnumProc32 [internal]
352 */
353 static INT WINAPI FontFamilyEnumProc(const ENUMLOGFONTEXW *lpElfex,
354 const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam)
355 {
356 LPCFn_ENUMSTRUCT e;
357 e=(LPCFn_ENUMSTRUCT)lParam;
358 return AddFontFamily( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
359 dwFontType, e->lpcf32w, e->hWnd1, e);
360 }
361
362 /*************************************************************************
363 * SetFontStylesToCombo2 [internal]
364 *
365 * Fill font style information into combobox (without using font.c directly)
366 */
367 static BOOL SetFontStylesToCombo2(HWND hwnd, HDC hdc, const LOGFONTW *lplf)
368 {
369 #define FSTYLES 4
370 struct FONTSTYLE
371 {
372 int italic;
373 int weight;
374 UINT resId;
375 };
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 }
381 };
382 HFONT hf;
383 TEXTMETRICW tm;
384 int i,j;
385 LOGFONTW lf;
386
387 lf = *lplf;
388
389 for (i=0;i<FSTYLES;i++)
390 {
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))
402 {
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;
410 }
411 }
412 return FALSE;
413 }
414
415 /*************************************************************************
416 * AddFontSizeToCombo3 [internal]
417 */
418 static BOOL AddFontSizeToCombo3(HWND hwnd, UINT h, const CHOOSEFONTW *lpcf)
419 {
420 int j;
421 WCHAR buffer[20];
422
423 if ( (!(lpcf->Flags & CF_LIMITSIZE)) ||
424 ((lpcf->Flags & CF_LIMITSIZE) && (h >= lpcf->nSizeMin) && (h <= lpcf->nSizeMax)))
425 {
426 sprintfW(buffer, fontsizefmtW, h);
427 j=SendMessageW(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)buffer);
428 if (j==CB_ERR)
429 {
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;
433 }
434 }
435 return FALSE;
436 }
437
438 /*************************************************************************
439 * SetFontSizesToCombo3 [internal]
440 */
441 static BOOL SetFontSizesToCombo3(HWND hwnd, const CHOOSEFONTW *lpcf)
442 {
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;
445
446 for (i = 0; i < ARRAY_SIZE(sizes); i++)
447 if (AddFontSizeToCombo3(hwnd, sizes[i], lpcf)) return TRUE;
448 return FALSE;
449 }
450
451 /*************************************************************************
452 * CFn_GetDC [internal]
453 */
454 static inline HDC CFn_GetDC(const CHOOSEFONTW *lpcf)
455 {
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;
461 }
462
463 /*************************************************************************
464 * GetScreenDPI [internal]
465 */
466 static inline int GetScreenDPI(void)
467 {
468 HDC hdc;
469 int result;
470
471 hdc = GetDC(0);
472 result = GetDeviceCaps(hdc, LOGPIXELSY);
473 ReleaseDC(0, hdc);
474
475 return result;
476 }
477
478 /*************************************************************************
479 * CFn_ReleaseDC [internal]
480 */
481 static inline void CFn_ReleaseDC(const CHOOSEFONTW *lpcf, HDC hdc)
482 {
483 if(!((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC))
484 ReleaseDC(0, hdc);
485 }
486
487 /*************************************************************************
488 * select_combo_item [internal]
489 */
490 static void select_combo_item( HWND dialog, int id, int sel )
491 {
492 HWND combo = GetDlgItem( dialog, id );
493 SendMessageW( combo, CB_SETCURSEL, sel, 0 );
494 SendMessageW( dialog, WM_COMMAND, MAKEWPARAM( id, CBN_SELCHANGE ), (LPARAM)combo );
495 }
496
497 /***********************************************************************
498 * AddFontStyle [internal]
499 */
500 static INT AddFontStyle( const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM,
501 UINT nFontType, const CHOOSEFONTW *lpcf, HWND hcmb2, HWND hcmb3, HWND hDlg)
502 {
503 int i;
504 const LOGFONTW *lplf = &(lpElfex->elfLogFont);
505 HWND hcmb5;
506 HDC hdc;
507
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)
517 {
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;
524
525 if (!SendMessageW(hcmb2, CB_GETCOUNT, 0, 0))
526 {
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;
533 }
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);
542 }
543 return 1 ;
544 }
545
546 static void CFn_FitFontSize( HWND hDlg, int points)
547 {
548 int i,n;
549
550 /* look for fitting font size in combobox3 */
551 n=SendDlgItemMessageW(hDlg, cmb3, CB_GETCOUNT, 0, 0);
552 for (i=0;i<n;i++)
553 {
554 if (points == (int)SendDlgItemMessageW
555 (hDlg,cmb3, CB_GETITEMDATA,i,0))
556 {
557 select_combo_item( hDlg, cmb3, i );
558 return;
559 }
560 }
561
562 /* no default matching size, set text manually */
563 SetDlgItemInt(hDlg, cmb3, points, TRUE);
564 }
565
566 static BOOL CFn_FitFontStyle( HWND hDlg, LONG packedstyle )
567 {
568 LONG id;
569 int i;
570 /* look for fitting font style in combobox2 */
571 for (i=0;i<TEXT_EXTRAS;i++)
572 {
573 id = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
574 if (packedstyle == id)
575 {
576 select_combo_item( hDlg, cmb2, i );
577 return TRUE;
578 }
579 }
580 return FALSE;
581 }
582
583
584 static BOOL CFn_FitCharSet( HWND hDlg, int charset )
585 {
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++)
590 {
591 cs =SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
592 if (charset == cs)
593 {
594 select_combo_item( hDlg, cmb5, i );
595 return TRUE;
596 }
597 }
598 /* no charset fits: select the first one in the list */
599 select_combo_item( hDlg, cmb5, 0 );
600 return FALSE;
601 }
602
603 /***********************************************************************
604 * FontStyleEnumProc32 [internal]
605 */
606 static INT WINAPI FontStyleEnumProc( const ENUMLOGFONTEXW *lpElfex,
607 const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam )
608 {
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);
615 }
616
617 /***********************************************************************
618 * CFn_WMInitDialog [internal]
619 */
620 static LRESULT CFn_WMInitDialog(HWND hDlg, LPARAM lParam, LPCHOOSEFONTW lpcf)
621 {
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};
630
631 SetPropW(hDlg, strWineFontData, lpcf);
632 lpxx=lpcf->lpLogFont;
633 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
634
635 if (lpcf->lStructSize != sizeof(CHOOSEFONTW))
636 {
637 ERR("structure size failure!!!\n");
638 EndDialog (hDlg, 0);
639 return FALSE;
640 }
641 if (!himlTT)
642 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
643 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
644
645 /* Set effect flags */
646 if((lpcf->Flags & CF_EFFECTS) && (lpcf->Flags & CF_INITTOLOGFONTSTRUCT))
647 {
648 if(lpxx->lfUnderline)
649 CheckDlgButton(hDlg, chx2, TRUE);
650 if(lpxx->lfStrikeOut)
651 CheckDlgButton(hDlg, chx1, TRUE);
652 }
653
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)
661 {
662 for (i=0;i<TEXT_COLORS;i++)
663 {
664 WCHAR name[30];
665
666 if( LoadStringW(COMDLG32_hInstance, IDS_COLOR_BLACK+i, name,
667 ARRAY_SIZE(name)) == 0 )
668 {
669 memcpy(name, strColorName, sizeof(strColorName));
670 }
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);
676 }
677 }
678 else
679 {
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);
685 }
686 if(!(hdc = CFn_GetDC(lpcf)))
687 {
688 EndDialog (hDlg, 0);
689 return FALSE;
690 }
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))
700 {
701 TRACE("EnumFontFamiliesEx returns 0\n");
702 break;
703 }
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;
709 }
710 if (lpcf->Flags & CF_TTONLY) {
711 FIXME("No font found with truetype only, dropping flag.\n");
712 lpcf->Flags &= ~CF_TTONLY;
713 continue;
714 }
715 break;
716 } while (1);
717
718
719 if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
720 {
721 /* look for fitting font name in combobox1 */
722 j=SendDlgItemMessageW(hDlg,cmb1,CB_FINDSTRING,-1,(LPARAM)lpxx->lfFaceName);
723 if (j!=CB_ERR)
724 {
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 );
739 }
740 }
741 if (!init)
742 {
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 );
747 }
748 /* limit text length user can type in as font size */
749 SendDlgItemMessageW(hDlg, cmb3, CB_LIMITTEXT, 5, 0);
750
751 if ((lpcf->Flags & CF_USESTYLE) && lpcf->lpszStyle)
752 {
753 j=SendDlgItemMessageW(hDlg,cmb2,CB_FINDSTRING,-1,(LPARAM)lpcf->lpszStyle);
754 if (j!=CB_ERR) select_combo_item( hDlg, cmb2, j );
755 }
756 CFn_ReleaseDC(lpcf, hdc);
757 SetCursor(hcursor);
758 return TRUE;
759 }
760
761
762 /***********************************************************************
763 * CFn_WMMeasureItem [internal]
764 */
765 static LRESULT CFn_WMMeasureItem(HWND hDlg, LPARAM lParam)
766 {
767 HDC hdc;
768 HFONT hfontprev;
769 TEXTMETRICW tm;
770 LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam;
771 INT height = 0, cx;
772
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;
787 }
788
789
790 /***********************************************************************
791 * CFn_WMDrawItem [internal]
792 */
793 static LRESULT CFn_WMDrawItem(LPARAM lParam)
794 {
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;
802
803 if (lpdi->itemID == (UINT)-1) /* got no items */
804 DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
805 else
806 {
807 if (lpdi->CtlType == ODT_COMBOBOX)
808 {
809 if (lpdi->itemState & ODS_SELECTED)
810 {
811 hBrush=GetSysColorBrush(COLOR_HIGHLIGHT);
812 oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
813 oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT));
814 } else
815 {
816 hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
817 SelectObject(lpdi->hDC, hBrush);
818 }
819 FillRect(lpdi->hDC, &lpdi->rcItem, hBrush);
820 }
821 else
822 return TRUE; /* this should never happen */
823
824 rect=lpdi->rcItem;
825 switch (lpdi->CtlID)
826 {
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;
859
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)
869 {
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)) ;
878 }
879 rect=lpdi->rcItem;
880 rect.left+=25+5;
881 break;
882
883 default:
884 return TRUE; /* this should never happen */
885 }
886 if (lpdi->itemState & ODS_SELECTED)
887 {
888 SetTextColor(lpdi->hDC, oldText);
889 SetBkColor(lpdi->hDC, oldBk);
890 }
891 }
892 return TRUE;
893 }
894
895 static INT get_dialog_font_point_size(HWND hDlg, CHOOSEFONTW *cf)
896 {
897 BOOL invalid_size = FALSE;
898 INT i, size;
899
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
904 {
905 WCHAR buffW[8], *endptrW;
906
907 GetDlgItemTextW(hDlg, cmb3, buffW, ARRAY_SIZE(buffW));
908 size = strtolW(buffW, &endptrW, 10);
909 invalid_size = size == 0 && *endptrW;
910
911 if (size == 0)
912 size = 10;
913 }
914
915 cf->iPointSize = 10 * size;
916 cf->lpLogFont->lfHeight = -MulDiv(cf->iPointSize, GetScreenDPI(), 720);
917 return invalid_size ? -1 : size;
918 }
919
920 /***********************************************************************
921 * CFn_WMCommand [internal]
922 */
923 static LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcf)
924 {
925 int i;
926 long l;
927 HDC hdc;
928 BOOL cmb_selected_by_edit = FALSE;
929
930 if (!lpcf) return FALSE;
931
932 if(HIWORD(wParam) == CBN_EDITCHANGE)
933 {
934 int idx;
935 WCHAR str_edit[256], str_cmb[256];
936 int cmb = LOWORD(wParam);
937
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)
941 {
942 SendDlgItemMessageW(hDlg, cmb, CB_GETLBTEXT, idx, (LPARAM)str_cmb);
943
944 /* Select listbox entry only if we have an exact match */
945 if(lstrcmpiW(str_edit, str_cmb) == 0)
946 {
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;
950 }
951 }
952 }
953
954 TRACE("WM_COMMAND wParam=%08X lParam=%08lX\n", (LONG)wParam, lParam);
955 switch (LOWORD(wParam))
956 {
957 case cmb1:
958 if (HIWORD(wParam) == CBN_SELCHANGE || cmb_selected_by_edit)
959 {
960 INT pointsize; /* save current pointsize */
961 LONG pstyle; /* save current style */
962 int charset;
963 int idx;
964 if(!(hdc = CFn_GetDC(lpcf)))
965 {
966 EndDialog (hDlg, 0);
967 return TRUE;
968 }
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);
976
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)
982 {
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);
1000 }
1001 CFn_ReleaseDC(lpcf, hdc);
1002 }
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)
1010 {
1011 WCHAR str[256];
1012 WINDOWINFO wininfo;
1013 LPLOGFONTW lpxx=lpcf->lpLogFont;
1014
1015 TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
1016
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
1022 {
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;
1031 }
1032 lstrcpynW(lpxx->lfFaceName, str, ARRAY_SIZE(lpxx->lfFaceName));
1033
1034 /* style */
1035 i=SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
1036 if (i!=CB_ERR)
1037 {
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;
1043 }
1044
1045 /* size */
1046 get_dialog_font_point_size(hDlg, lpcf);
1047
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;
1060
1061 wininfo.cbSize=sizeof(wininfo);
1062
1063 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1064 {
1065 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1066 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1067 }
1068 }
1069 break;
1070
1071 case cmb4:
1072 i=SendDlgItemMessageW(hDlg, cmb4, CB_GETCURSEL, 0, 0);
1073 if (i!=CB_ERR)
1074 {
1075 WINDOWINFO wininfo;
1076
1077 lpcf->rgbColors = SendDlgItemMessageW(hDlg, cmb4, CB_GETITEMDATA, i, 0);
1078 wininfo.cbSize=sizeof(wininfo);
1079
1080 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1081 {
1082 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1083 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1084 }
1085 }
1086 break;
1087
1088 case psh15:
1089 i=RegisterWindowMessageW( HELPMSGSTRINGW );
1090 if (lpcf->hwndOwner)
1091 SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData));
1092 break;
1093
1094 case IDOK:
1095 {
1096 WCHAR msgW[80];
1097 INT pointsize;
1098
1099 pointsize = get_dialog_font_point_size(hDlg, lpcf);
1100 if (pointsize == -1)
1101 {
1102 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE_INPUT, msgW, ARRAY_SIZE(msgW));
1103 MessageBoxW(hDlg, msgW, NULL, MB_OK | MB_ICONINFORMATION);
1104 return TRUE;
1105 }
1106
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
1113 {
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);
1123 }
1124 return(TRUE);
1125 }
1126 case IDCANCEL:
1127 EndDialog(hDlg, FALSE);
1128 return(TRUE);
1129 }
1130 return(FALSE);
1131 }
1132
1133 static LRESULT CFn_WMDestroy(HWND hwnd, LPCHOOSEFONTW lpcfw)
1134 {
1135 LPCHOOSEFONTA lpcfa;
1136 LPSTR lpszStyle;
1137 LPLOGFONTA lpLogFonta;
1138 int len;
1139
1140 if (!lpcfw) return FALSE;
1141
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);
1151
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);
1156 }
1157
1158 heap_free(lpcfw->lpLogFont);
1159 heap_free(lpcfw);
1160 SetPropW(hwnd, strWineFontData, 0);
1161
1162 return TRUE;
1163 }
1164
1165 static LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW *lpcf)
1166 {
1167 WINDOWINFO info;
1168
1169 if (!lpcf) return FALSE;
1170
1171 info.cbSize=sizeof(info);
1172 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &info ) )
1173 {
1174 PAINTSTRUCT ps;
1175 HDC hdc;
1176 HFONT hOrigFont;
1177 LOGFONTW lf = *(lpcf->lpLogFont);
1178
1179 MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2);
1180 hdc = BeginPaint( hDlg, &ps );
1181
1182 TRACE("erase %d, rect=%s\n", ps.fErase, wine_dbgstr_rect(&ps.rcPaint));
1183
1184 /* Paint frame */
1185 DrawEdge( hdc, &info.rcWindow, EDGE_SUNKEN, BF_RECT|BF_ADJUST );
1186
1187 /* Draw the sample text itself */
1188 hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
1189 SetTextColor( hdc, lpcf->rgbColors );
1190
1191 DrawTextW( hdc,
1192 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]],
1193 -1, &info.rcWindow, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
1194
1195 DeleteObject(SelectObject( hdc, hOrigFont ));
1196 EndPaint( hDlg, &ps );
1197 }
1198 return FALSE;
1199 }
1200
1201 /***********************************************************************
1202 * FormatCharDlgProcA [internal]
1203 */
1204 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1205 {
1206 LPCHOOSEFONTW lpcfw;
1207 LPCHOOSEFONTA lpcfa;
1208 INT_PTR res = FALSE;
1209 int len;
1210
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);
1220
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);
1227
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);
1232 }
1233
1234 if (!CFn_WMInitDialog(hDlg, lParam, lpcfw))
1235 {
1236 TRACE("CFn_WMInitDialog returned FALSE\n");
1237 return FALSE;
1238 }
1239 if (CFn_HookCallChk32(lpcfw))
1240 return CallWindowProcA((WNDPROC)lpcfa->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1241 }
1242 switch (uMsg)
1243 {
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:
1253 {
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;
1260 }
1261 case WM_PAINT:
1262 return CFn_WMPaint(hDlg, wParam, lParam, lpcfw);
1263 }
1264 return res;
1265 }
1266
1267 /***********************************************************************
1268 * FormatCharDlgProcW [internal]
1269 */
1270 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1271 {
1272 LPCHOOSEFONTW lpcf;
1273 INT_PTR res = FALSE;
1274
1275 if (uMsg!=WM_INITDIALOG)
1276 {
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;
1282 }
1283 else
1284 {
1285 lpcf=(LPCHOOSEFONTW)lParam;
1286 if (!CFn_WMInitDialog(hDlg, lParam, lpcf))
1287 {
1288 TRACE("CFn_WMInitDialog returned FALSE\n");
1289 return FALSE;
1290 }
1291 if (CFn_HookCallChk32(lpcf))
1292 return CallWindowProcW((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1293 }
1294 switch (uMsg)
1295 {
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);
1310 }
1311 return res;
1312 }