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