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