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