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