[COMDLG32]
[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 "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 int 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 1;
388 j=SendMessageW(hwnd, CB_SETITEMDATA, j,
389 MAKELONG(tm.tmWeight,fontstyles[i].italic));
390 if (j==CB_ERR) return 1;
391 }
392 }
393 return 0;
394 }
395
396 /*************************************************************************
397 * AddFontSizeToCombo3 [internal]
398 */
399 static int 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 1;
415 }
416 }
417 return 0;
418 }
419
420 /*************************************************************************
421 * SetFontSizesToCombo3 [internal]
422 */
423 static int 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 1;
430 return 0;
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 i = AddFontSizeToCombo3(hcmb3, points, lpcf);
494 if(i) return 0;
495 } else if (SetFontSizesToCombo3(hcmb3, lpcf)) return 0;
496
497 if (!SendMessageW(hcmb2, CB_GETCOUNT, 0, 0))
498 {
499 if(!(hdc = CFn_GetDC(lpcf))) return 0;
500 i=SetFontStylesToCombo2(hcmb2,hdc,lplf);
501 CFn_ReleaseDC(lpcf, hdc);
502 if (i)
503 return 0;
504 }
505 if (!( hcmb5 = GetDlgItem(hDlg, cmb5))) return 1;
506 i = SendMessageW( hcmb5, CB_FINDSTRINGEXACT, 0,
507 (LPARAM)lpElfex->elfScript);
508 if( i == CB_ERR) {
509 i = SendMessageW( hcmb5, CB_ADDSTRING, 0,
510 (LPARAM)lpElfex->elfScript);
511 if( i != CB_ERR)
512 SendMessageW( hcmb5, CB_SETITEMDATA, i, lplf->lfCharSet);
513 }
514 return 1 ;
515 }
516
517 static INT CFn_FitFontSize( HWND hDlg, int points)
518 {
519 int i,n;
520 int ret = 0;
521 /* look for fitting font size in combobox3 */
522 n=SendDlgItemMessageW(hDlg, cmb3, CB_GETCOUNT, 0, 0);
523 for (i=0;i<n;i++)
524 {
525 if (points == (int)SendDlgItemMessageW
526 (hDlg,cmb3, CB_GETITEMDATA,i,0))
527 {
528 SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,i,0);
529 SendMessageW(hDlg, WM_COMMAND,
530 MAKEWPARAM(cmb3, CBN_SELCHANGE),
531 (LPARAM)GetDlgItem(hDlg,cmb3));
532 ret = 1;
533 break;
534 }
535 }
536 return ret;
537 }
538
539 static INT CFn_FitFontStyle( HWND hDlg, LONG packedstyle )
540 {
541 LONG id;
542 int i, ret = 0;
543 /* look for fitting font style in combobox2 */
544 for (i=0;i<TEXT_EXTRAS;i++)
545 {
546 id = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
547 if (packedstyle == id)
548 {
549 SendDlgItemMessageW(hDlg, cmb2, CB_SETCURSEL, i, 0);
550 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
551 (LPARAM)GetDlgItem(hDlg,cmb2));
552 ret = 1;
553 break;
554 }
555 }
556 return ret;
557 }
558
559
560 static INT CFn_FitCharSet( HWND hDlg, int charset )
561 {
562 int i,n,cs;
563 /* look for fitting char set in combobox5 */
564 n=SendDlgItemMessageW(hDlg, cmb5, CB_GETCOUNT, 0, 0);
565 for (i=0;i<n;i++)
566 {
567 cs =SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
568 if (charset == cs)
569 {
570 SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, i, 0);
571 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
572 (LPARAM)GetDlgItem(hDlg,cmb2));
573 return 1;
574 }
575 }
576 /* no charset fits: select the first one in the list */
577 SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, 0, 0);
578 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
579 (LPARAM)GetDlgItem(hDlg,cmb2));
580 return 0;
581 }
582
583 /***********************************************************************
584 * FontStyleEnumProc32 [internal]
585 */
586 static INT WINAPI FontStyleEnumProc( const ENUMLOGFONTEXW *lpElfex,
587 const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam )
588 {
589 LPCFn_ENUMSTRUCT s=(LPCFn_ENUMSTRUCT)lParam;
590 HWND hcmb2=s->hWnd1;
591 HWND hcmb3=s->hWnd2;
592 HWND hDlg=GetParent(hcmb3);
593 return AddFontStyle( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
594 dwFontType, s->lpcf32w, hcmb2, hcmb3, hDlg);
595 }
596
597 /***********************************************************************
598 * CFn_WMInitDialog [internal]
599 */
600 static LRESULT CFn_WMInitDialog(HWND hDlg, LPARAM lParam, LPCHOOSEFONTW lpcf)
601 {
602 HDC hdc;
603 int i,j,init=0;
604 long pstyle;
605 CFn_ENUMSTRUCT s;
606 LPLOGFONTW lpxx;
607 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
608 static const WCHAR strColorName[] = {'[','c','o','l','o','r',' ','n','a','m','e',']',0};
609
610 SetPropW(hDlg, strWineFontData, lpcf);
611 lpxx=lpcf->lpLogFont;
612 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
613
614 if (lpcf->lStructSize != sizeof(CHOOSEFONTW))
615 {
616 ERR("structure size failure !!!\n");
617 EndDialog (hDlg, 0);
618 return FALSE;
619 }
620 if (!himlTT)
621 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
622 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
623
624 /* Set effect flags */
625 if((lpcf->Flags & CF_EFFECTS) && (lpcf->Flags & CF_INITTOLOGFONTSTRUCT))
626 {
627 if(lpxx->lfUnderline)
628 CheckDlgButton(hDlg, chx2, TRUE);
629 if(lpxx->lfStrikeOut)
630 CheckDlgButton(hDlg, chx1, TRUE);
631 }
632
633 if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow(lpcf->hwndOwner))
634 ShowWindow(GetDlgItem(hDlg,pshHelp),SW_HIDE);
635 if (!(lpcf->Flags & CF_APPLY))
636 ShowWindow(GetDlgItem(hDlg,psh3),SW_HIDE);
637 if (lpcf->Flags & CF_NOSCRIPTSEL)
638 EnableWindow(GetDlgItem(hDlg,cmb5),FALSE);
639 if (lpcf->Flags & CF_EFFECTS)
640 {
641 for (i=0;i<TEXT_COLORS;i++)
642 {
643 WCHAR name[30];
644
645 if( LoadStringW(COMDLG32_hInstance, IDS_COLOR_BLACK+i, name,
646 sizeof(name)/sizeof(*name) )==0 )
647 {
648 memcpy(name, strColorName, sizeof(strColorName));
649 }
650 j=SendDlgItemMessageW(hDlg, cmb4, CB_ADDSTRING, 0, (LPARAM)name);
651 SendDlgItemMessageW(hDlg, cmb4, CB_SETITEMDATA, j, textcolors[i]);
652 /* look for a fitting value in color combobox */
653 if (textcolors[i]==lpcf->rgbColors)
654 SendDlgItemMessageW(hDlg,cmb4, CB_SETCURSEL,j,0);
655 }
656 }
657 else
658 {
659 ShowWindow(GetDlgItem(hDlg,cmb4),SW_HIDE);
660 ShowWindow(GetDlgItem(hDlg,chx1),SW_HIDE);
661 ShowWindow(GetDlgItem(hDlg,chx2),SW_HIDE);
662 ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
663 ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
664 }
665 if(!(hdc = CFn_GetDC(lpcf)))
666 {
667 EndDialog (hDlg, 0);
668 return FALSE;
669 }
670 s.hWnd1=GetDlgItem(hDlg,cmb1);
671 s.lpcf32w=lpcf;
672 do {
673 LOGFONTW elf;
674 s.added = 0;
675 elf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
676 elf.lfPitchAndFamily = 0;
677 elf.lfFaceName[0] = '\0'; /* enum all fonts */
678 if (!EnumFontFamiliesExW(hdc, &elf, (FONTENUMPROCW)FontFamilyEnumProc, (LPARAM)&s, 0))
679 {
680 TRACE("EnumFontFamiliesEx returns 0\n");
681 break;
682 }
683 if (s.added) break;
684 if (lpcf->Flags & CF_FIXEDPITCHONLY) {
685 FIXME("No font found with fixed pitch only, dropping flag.\n");
686 lpcf->Flags &= ~CF_FIXEDPITCHONLY;
687 continue;
688 }
689 if (lpcf->Flags & CF_TTONLY) {
690 FIXME("No font found with truetype only, dropping flag.\n");
691 lpcf->Flags &= ~CF_TTONLY;
692 continue;
693 }
694 break;
695 } while (1);
696
697
698 if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
699 {
700 /* look for fitting font name in combobox1 */
701 j=SendDlgItemMessageW(hDlg,cmb1,CB_FINDSTRING,-1,(LPARAM)lpxx->lfFaceName);
702 if (j!=CB_ERR)
703 {
704 INT height = lpxx->lfHeight < 0 ? -lpxx->lfHeight :
705 lpxx->lfHeight;
706 INT points;
707 int charset = lpxx->lfCharSet;
708 points = MulDiv( height, 72, GetScreenDPI());
709 pstyle = MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD:
710 FW_NORMAL,lpxx->lfItalic !=0);
711 SendDlgItemMessageW(hDlg, cmb1, CB_SETCURSEL, j, 0);
712 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
713 (LPARAM)GetDlgItem(hDlg,cmb1));
714 init=1;
715 /* look for fitting font style in combobox2 */
716 CFn_FitFontStyle(hDlg, pstyle);
717 /* look for fitting font size in combobox3 */
718 CFn_FitFontSize(hDlg, points);
719 CFn_FitCharSet( hDlg, charset );
720 }
721 }
722 if (!init)
723 {
724 SendDlgItemMessageW(hDlg,cmb1,CB_SETCURSEL,0,0);
725 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
726 (LPARAM)GetDlgItem(hDlg,cmb1));
727 SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,0,0);
728 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
729 (LPARAM)GetDlgItem(hDlg,cmb1));
730 SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,0,0);
731 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb3, CBN_SELCHANGE),
732 (LPARAM)GetDlgItem(hDlg,cmb3));
733 SendDlgItemMessageW(hDlg,cmb5,CB_SETCURSEL,0,0);
734 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
735 (LPARAM)GetDlgItem(hDlg,cmb5));
736 }
737 if ((lpcf->Flags & CF_USESTYLE) && lpcf->lpszStyle)
738 {
739 j=SendDlgItemMessageW(hDlg,cmb2,CB_FINDSTRING,-1,(LPARAM)lpcf->lpszStyle);
740 if (j!=CB_ERR)
741 {
742 j=SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,j,0);
743 SendMessageW(hDlg,WM_COMMAND,cmb2,
744 MAKELONG(LOWORD(GetDlgItem(hDlg,cmb2)),CBN_SELCHANGE));
745 }
746 }
747 CFn_ReleaseDC(lpcf, hdc);
748 SetCursor(hcursor);
749 return TRUE;
750 }
751
752
753 /***********************************************************************
754 * CFn_WMMeasureItem [internal]
755 */
756 static LRESULT CFn_WMMeasureItem(HWND hDlg, LPARAM lParam)
757 {
758 HDC hdc;
759 HFONT hfontprev;
760 TEXTMETRICW tm;
761 LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam;
762 INT height = 0, cx;
763
764 if (!himlTT)
765 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
766 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
767 ImageList_GetIconSize( himlTT, &cx, &height);
768 lpmi->itemHeight = height + 2;
769 /* use MAX of bitmap height and tm.tmHeight .*/
770 hdc=GetDC(hDlg);
771 if(!hdc) return 0;
772 hfontprev = SelectObject( hdc, (HFONT)SendMessageW( hDlg, WM_GETFONT, 0, 0 ));
773 GetTextMetricsW(hdc, &tm);
774 if( tm.tmHeight > lpmi->itemHeight) lpmi->itemHeight = tm.tmHeight;
775 SelectObject(hdc, hfontprev);
776 ReleaseDC(hDlg, hdc);
777 return 0;
778 }
779
780
781 /***********************************************************************
782 * CFn_WMDrawItem [internal]
783 */
784 static LRESULT CFn_WMDrawItem(LPARAM lParam)
785 {
786 HBRUSH hBrush;
787 WCHAR buffer[40];
788 COLORREF cr, oldText=0, oldBk=0;
789 RECT rect;
790 int nFontType;
791 int cx, cy, idx;
792 LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam;
793
794 if (lpdi->itemID == (UINT)-1) /* got no items */
795 DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
796 else
797 {
798 if (lpdi->CtlType == ODT_COMBOBOX)
799 {
800 if (lpdi->itemState & ODS_SELECTED)
801 {
802 hBrush=GetSysColorBrush(COLOR_HIGHLIGHT);
803 oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
804 oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT));
805 } else
806 {
807 hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
808 SelectObject(lpdi->hDC, hBrush);
809 }
810 FillRect(lpdi->hDC, &lpdi->rcItem, hBrush);
811 }
812 else
813 return TRUE; /* this should never happen */
814
815 rect=lpdi->rcItem;
816 switch (lpdi->CtlID)
817 {
818 case cmb1:
819 /* TRACE(commdlg,"WM_Drawitem cmb1\n"); */
820 ImageList_GetIconSize( himlTT, &cx, &cy);
821 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
822 (LPARAM)buffer);
823 TextOutW(lpdi->hDC, lpdi->rcItem.left + cx + 4,
824 lpdi->rcItem.top, buffer, lstrlenW(buffer));
825 nFontType = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
826 idx = -1;
827 if (nFontType & TRUETYPE_FONTTYPE) {
828 idx = 0; /* picture: TT */
829 if( nFontType & NTM_TT_OPENTYPE)
830 idx = 2; /* picture: O */
831 } else if( nFontType & NTM_PS_OPENTYPE)
832 idx = 3; /* picture: O+ps */
833 else if( nFontType & NTM_TYPE1)
834 idx = 4; /* picture: a */
835 else if( nFontType & DEVICE_FONTTYPE)
836 idx = 1; /* picture: printer */
837 if( idx >= 0)
838 ImageList_Draw( himlTT, idx, lpdi->hDC, lpdi->rcItem.left,
839 (lpdi->rcItem.top + lpdi->rcItem.bottom - cy) / 2, ILD_TRANSPARENT);
840 break;
841 case cmb2:
842 case cmb3:
843 /* TRACE(commdlg,"WM_DRAWITEN cmb2,cmb3\n"); */
844 case cmb5:
845 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
846 (LPARAM)buffer);
847 TextOutW(lpdi->hDC, lpdi->rcItem.left,
848 lpdi->rcItem.top, buffer, lstrlenW(buffer));
849 break;
850
851 case cmb4:
852 /* TRACE(commdlg,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
853 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
854 (LPARAM)buffer);
855 TextOutW(lpdi->hDC, lpdi->rcItem.left + 25+5,
856 lpdi->rcItem.top, buffer, lstrlenW(buffer));
857 cr = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
858 hBrush = CreateSolidBrush(cr);
859 if (hBrush)
860 {
861 hBrush = SelectObject (lpdi->hDC, hBrush) ;
862 rect.right=rect.left+25;
863 rect.top++;
864 rect.left+=5;
865 rect.bottom--;
866 Rectangle( lpdi->hDC, rect.left, rect.top,
867 rect.right, rect.bottom );
868 DeleteObject( SelectObject (lpdi->hDC, hBrush)) ;
869 }
870 rect=lpdi->rcItem;
871 rect.left+=25+5;
872 break;
873
874 default:
875 return TRUE; /* this should never happen */
876 }
877 if (lpdi->itemState & ODS_SELECTED)
878 {
879 SetTextColor(lpdi->hDC, oldText);
880 SetBkColor(lpdi->hDC, oldBk);
881 }
882 }
883 return TRUE;
884 }
885
886 /***********************************************************************
887 * CFn_WMCommand [internal]
888 */
889 static LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpcf)
890 {
891 int i;
892 long l;
893 HDC hdc;
894
895 if (!lpcf) return FALSE;
896
897 TRACE("WM_COMMAND wParam=%08X lParam=%08lX\n", (LONG)wParam, lParam);
898 switch (LOWORD(wParam))
899 {
900 case cmb1:
901 if (HIWORD(wParam)==CBN_SELCHANGE)
902 {
903 INT pointsize; /* save current pointsize */
904 LONG pstyle; /* save current style */
905 int charset;
906 int idx;
907 if(!(hdc = CFn_GetDC(lpcf)))
908 {
909 EndDialog (hDlg, 0);
910 return TRUE;
911 }
912 idx = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
913 pointsize = (int)SendDlgItemMessageW( hDlg, cmb3, CB_GETITEMDATA,
914 idx, 0);
915 idx = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
916 pstyle = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, idx, 0);
917 idx = SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
918 charset = SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, idx, 0);
919
920 SendDlgItemMessageW(hDlg, cmb2, CB_RESETCONTENT, 0, 0);
921 SendDlgItemMessageW(hDlg, cmb3, CB_RESETCONTENT, 0, 0);
922 SendDlgItemMessageW(hDlg, cmb5, CB_RESETCONTENT, 0, 0);
923 i=SendDlgItemMessageW(hDlg, cmb1, CB_GETCURSEL, 0, 0);
924 if (i!=CB_ERR)
925 {
926 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
927 CFn_ENUMSTRUCT s;
928 LOGFONTW enumlf;
929 SendDlgItemMessageW(hDlg, cmb1, CB_GETLBTEXT, i,
930 (LPARAM)enumlf.lfFaceName);
931 TRACE("WM_COMMAND/cmb1 =>%s\n", debugstr_w(enumlf.lfFaceName));
932 s.hWnd1=GetDlgItem(hDlg, cmb2);
933 s.hWnd2=GetDlgItem(hDlg, cmb3);
934 s.lpcf32w=lpcf;
935 enumlf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
936 enumlf.lfPitchAndFamily = 0;
937 EnumFontFamiliesExW(hdc, &enumlf,
938 (FONTENUMPROCW)FontStyleEnumProc, (LPARAM)&s, 0);
939 CFn_FitFontStyle(hDlg, pstyle);
940 if( pointsize != CB_ERR) CFn_FitFontSize(hDlg, pointsize);
941 if( charset != CB_ERR) CFn_FitCharSet( hDlg, charset );
942 SetCursor(hcursor);
943 }
944 CFn_ReleaseDC(lpcf, hdc);
945 }
946 break;
947 case chx1:
948 case chx2:
949 case cmb2:
950 case cmb3:
951 case cmb5:
952 if (HIWORD(wParam)==CBN_SELCHANGE || HIWORD(wParam)== BN_CLICKED )
953 {
954 WCHAR str[256];
955 WINDOWINFO wininfo;
956 LPLOGFONTW lpxx=lpcf->lpLogFont;
957
958 TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
959 i=SendDlgItemMessageW(hDlg,cmb1,CB_GETCURSEL,0,0);
960 if (i==CB_ERR)
961 i=GetDlgItemTextW( hDlg, cmb1, str, 256 );
962 else
963 {
964 SendDlgItemMessageW(hDlg,cmb1,CB_GETLBTEXT,i,
965 (LPARAM)str);
966 l=SendDlgItemMessageW(hDlg,cmb1,CB_GETITEMDATA,i,0);
967 lpcf->nFontType = LOWORD(l);
968 /* FIXME: lpcf->nFontType |= .... SIMULATED_FONTTYPE and so */
969 /* same value reported to the EnumFonts
970 call back with the extra FONTTYPE_... bits added */
971 lpxx->lfPitchAndFamily = HIWORD(l) >> 8;
972 }
973 lstrcpynW(lpxx->lfFaceName, str, sizeof(lpxx->lfFaceName)/sizeof(lpxx->lfFaceName[0]));
974 i=SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
975 if (i!=CB_ERR)
976 {
977 l=SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
978 if (0!=(lpxx->lfItalic=HIWORD(l)))
979 lpcf->nFontType |= ITALIC_FONTTYPE;
980 if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
981 lpcf->nFontType |= BOLD_FONTTYPE;
982 }
983 i=SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
984 if( i != CB_ERR)
985 lpcf->iPointSize = 10 * LOWORD(SendDlgItemMessageW(hDlg, cmb3,
986 CB_GETITEMDATA , i, 0));
987 else
988 lpcf->iPointSize = 100;
989 lpxx->lfHeight = - MulDiv( lpcf->iPointSize ,
990 GetScreenDPI(), 720);
991 i=SendDlgItemMessageW(hDlg, cmb5, CB_GETCURSEL, 0, 0);
992 if (i!=CB_ERR)
993 lpxx->lfCharSet=SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
994 else
995 lpxx->lfCharSet = DEFAULT_CHARSET;
996 lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
997 lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
998 lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
999 lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
1000 lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
1001 lpxx->lfQuality=DEFAULT_QUALITY;
1002
1003 wininfo.cbSize=sizeof(wininfo);
1004
1005 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1006 {
1007 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1008 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1009 }
1010 }
1011 break;
1012
1013 case cmb4:
1014 i=SendDlgItemMessageW(hDlg, cmb4, CB_GETCURSEL, 0, 0);
1015 if (i!=CB_ERR)
1016 {
1017 WINDOWINFO wininfo;
1018
1019 lpcf->rgbColors = SendDlgItemMessageW(hDlg, cmb4, CB_GETITEMDATA, i, 0);
1020 wininfo.cbSize=sizeof(wininfo);
1021
1022 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &wininfo ) )
1023 {
1024 MapWindowPoints( 0, hDlg, (LPPOINT) &wininfo.rcWindow, 2);
1025 InvalidateRect( hDlg, &wininfo.rcWindow, TRUE );
1026 }
1027 }
1028 break;
1029
1030 case psh15:
1031 i=RegisterWindowMessageW( HELPMSGSTRINGW );
1032 if (lpcf->hwndOwner)
1033 SendMessageW(lpcf->hwndOwner, i, 0, (LPARAM)GetPropW(hDlg, strWineFontData));
1034 break;
1035
1036 case IDOK:
1037 if ( (!(lpcf->Flags & CF_LIMITSIZE)) ||
1038 ( (lpcf->Flags & CF_LIMITSIZE) &&
1039 (lpcf->iPointSize >= 10 * lpcf->nSizeMin) &&
1040 (lpcf->iPointSize <= 10 * lpcf->nSizeMax)))
1041 EndDialog(hDlg, TRUE);
1042 else
1043 {
1044 WCHAR buffer[80];
1045 WCHAR format[80];
1046 DWORD_PTR args[2];
1047 LoadStringW(COMDLG32_hInstance, IDS_FONT_SIZE, format, sizeof(format)/sizeof(WCHAR));
1048 args[0] = lpcf->nSizeMin;
1049 args[1] = lpcf->nSizeMax;
1050 FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
1051 format, 0, 0, buffer, sizeof(buffer)/sizeof(*buffer),
1052 (__ms_va_list*)args);
1053 MessageBoxW(hDlg, buffer, NULL, MB_OK);
1054 }
1055 return(TRUE);
1056 case IDCANCEL:
1057 EndDialog(hDlg, FALSE);
1058 return(TRUE);
1059 }
1060 return(FALSE);
1061 }
1062
1063 static LRESULT CFn_WMDestroy(HWND hwnd, LPCHOOSEFONTW lpcfw)
1064 {
1065 LPCHOOSEFONTA lpcfa;
1066 LPSTR lpszStyle;
1067 LPLOGFONTA lpLogFonta;
1068 int len;
1069
1070 if (!lpcfw) return FALSE;
1071
1072 lpcfa = GetPropW(hwnd, strWineFontData_a);
1073 lpLogFonta = lpcfa->lpLogFont;
1074 lpszStyle = lpcfa->lpszStyle;
1075 memcpy(lpcfa, lpcfw, sizeof(CHOOSEFONTA));
1076 lpcfa->lpLogFont = lpLogFonta;
1077 lpcfa->lpszStyle = lpszStyle;
1078 memcpy(lpcfa->lpLogFont, lpcfw->lpLogFont, sizeof(LOGFONTA));
1079 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName,
1080 LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0);
1081
1082 if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) {
1083 len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, 0, 0, 0);
1084 WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0);
1085 HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle);
1086 }
1087
1088 HeapFree(GetProcessHeap(), 0, lpcfw->lpLogFont);
1089 HeapFree(GetProcessHeap(), 0, lpcfw);
1090 SetPropW(hwnd, strWineFontData, 0);
1091
1092 return TRUE;
1093 }
1094
1095 static LRESULT CFn_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam, const CHOOSEFONTW *lpcf)
1096 {
1097 WINDOWINFO info;
1098
1099 if (!lpcf) return FALSE;
1100
1101 info.cbSize=sizeof(info);
1102 if( GetWindowInfo( GetDlgItem( hDlg, stc5), &info ) )
1103 {
1104 PAINTSTRUCT ps;
1105 HDC hdc;
1106 HFONT hOrigFont;
1107 LOGFONTW lf = *(lpcf->lpLogFont);
1108
1109 MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2);
1110 hdc = BeginPaint( hDlg, &ps );
1111
1112 TRACE("erase %d, rect=(%d,%d)-(%d,%d)\n", ps.fErase,
1113 ps.rcPaint.left, ps.rcPaint.top,
1114 ps.rcPaint.right, ps.rcPaint.bottom);
1115
1116 /* Paint frame */
1117 DrawEdge( hdc, &info.rcWindow, EDGE_SUNKEN, BF_RECT|BF_ADJUST );
1118
1119 /* Draw the sample text itself */
1120 hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
1121 SetTextColor( hdc, lpcf->rgbColors );
1122
1123 DrawTextW( hdc,
1124 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]],
1125 -1, &info.rcWindow, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
1126
1127 DeleteObject(SelectObject( hdc, hOrigFont ));
1128 EndPaint( hDlg, &ps );
1129 }
1130 return FALSE;
1131 }
1132
1133 /***********************************************************************
1134 * FormatCharDlgProcA [internal]
1135 */
1136 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1137 {
1138 LPCHOOSEFONTW lpcfw;
1139 LPCHOOSEFONTA lpcfa;
1140 INT_PTR res = FALSE;
1141 int len;
1142
1143 if (uMsg!=WM_INITDIALOG) {
1144 lpcfw = GetPropW(hDlg, strWineFontData);
1145 if (lpcfw && CFn_HookCallChk32(lpcfw))
1146 res=CallWindowProcA((WNDPROC)lpcfw->lpfnHook, hDlg, uMsg, wParam, lParam);
1147 if (res)
1148 return res;
1149 } else {
1150 lpcfa=(LPCHOOSEFONTA)lParam;
1151 SetPropW(hDlg, strWineFontData_a, (HANDLE)lParam);
1152
1153 lpcfw = HeapAlloc(GetProcessHeap(), 0, sizeof(CHOOSEFONTW));
1154 memcpy(lpcfw, lpcfa, sizeof(CHOOSEFONTA));
1155 lpcfw->lpLogFont = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGFONTW));
1156 memcpy(lpcfw->lpLogFont, lpcfa->lpLogFont, sizeof(LOGFONTA));
1157 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpLogFont->lfFaceName,
1158 LF_FACESIZE, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE);
1159
1160 if((lpcfa->Flags & CF_USESTYLE) && lpcfa->lpszStyle) {
1161 len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, NULL, 0);
1162 lpcfw->lpszStyle = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
1163 MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len);
1164 }
1165
1166 if (!CFn_WMInitDialog(hDlg, lParam, lpcfw))
1167 {
1168 TRACE("CFn_WMInitDialog returned FALSE\n");
1169 return FALSE;
1170 }
1171 if (CFn_HookCallChk32(lpcfw))
1172 return CallWindowProcA((WNDPROC)lpcfa->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1173 }
1174 switch (uMsg)
1175 {
1176 case WM_MEASUREITEM:
1177 return CFn_WMMeasureItem(hDlg,lParam);
1178 case WM_DRAWITEM:
1179 return CFn_WMDrawItem(lParam);
1180 case WM_COMMAND:
1181 return CFn_WMCommand(hDlg, wParam, lParam, lpcfw);
1182 case WM_DESTROY:
1183 return CFn_WMDestroy(hDlg, lpcfw);
1184 case WM_CHOOSEFONT_GETLOGFONT:
1185 {
1186 LOGFONTA *logfont = (LOGFONTA *)lParam;
1187 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1188 memcpy( logfont, lpcfw->lpLogFont, FIELD_OFFSET( LOGFONTA, lfFaceName ));
1189 WideCharToMultiByte( CP_ACP, 0, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE,
1190 logfont->lfFaceName, LF_FACESIZE, NULL, NULL );
1191 break;
1192 }
1193 case WM_PAINT:
1194 return CFn_WMPaint(hDlg, wParam, lParam, lpcfw);
1195 }
1196 return res;
1197 }
1198
1199 /***********************************************************************
1200 * FormatCharDlgProcW [internal]
1201 */
1202 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1203 {
1204 LPCHOOSEFONTW lpcf;
1205 INT_PTR res = FALSE;
1206
1207 if (uMsg!=WM_INITDIALOG)
1208 {
1209 lpcf= GetPropW(hDlg, strWineFontData);
1210 if (lpcf && CFn_HookCallChk32(lpcf))
1211 res=CallWindowProcW((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam);
1212 if (res)
1213 return res;
1214 }
1215 else
1216 {
1217 lpcf=(LPCHOOSEFONTW)lParam;
1218 if (!CFn_WMInitDialog(hDlg, lParam, lpcf))
1219 {
1220 TRACE("CFn_WMInitDialog returned FALSE\n");
1221 return FALSE;
1222 }
1223 if (CFn_HookCallChk32(lpcf))
1224 return CallWindowProcW((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1225 }
1226 switch (uMsg)
1227 {
1228 case WM_MEASUREITEM:
1229 return CFn_WMMeasureItem(hDlg, lParam);
1230 case WM_DRAWITEM:
1231 return CFn_WMDrawItem(lParam);
1232 case WM_COMMAND:
1233 return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
1234 case WM_DESTROY:
1235 return TRUE;
1236 case WM_CHOOSEFONT_GETLOGFONT:
1237 TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1238 memcpy( (LOGFONTW *)lParam, lpcf->lpLogFont, sizeof(LOGFONTW) );
1239 break;
1240 case WM_PAINT:
1241 return CFn_WMPaint(hDlg, wParam, lParam, lpcf);
1242 }
1243 return res;
1244 }