Escape \ in path and arguments.
[wine] / dlls / commdlg / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <ctype.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include "windef.h"
27 #include "winnls.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "wine/winbase16.h"
31 #include "wine/winuser16.h"
32 #include "heap.h"
33 #include "commdlg.h"
34 #include "dlgs.h"
35 #include "wine/debug.h"
36 #include "cderr.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
39
40 #include "cdlg.h"
41
42 static HBITMAP16 hBitmapTT = 0;
43
44
45 INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
46                                   LPARAM lParam);
47 INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam,
48                                   LPARAM lParam);
49 BOOL16 CALLBACK FormatCharDlgProc16(HWND16 hDlg, UINT16 message, WPARAM16 wParam,
50                                    LPARAM lParam);
51
52 static void FONT_LogFont16To32A( const LPLOGFONT16 font16, LPLOGFONTA font32 )
53 {
54     font32->lfHeight = font16->lfHeight;
55     font32->lfWidth = font16->lfWidth;
56     font32->lfEscapement = font16->lfEscapement;
57     font32->lfOrientation = font16->lfOrientation;
58     font32->lfWeight = font16->lfWeight;
59     font32->lfItalic = font16->lfItalic;
60     font32->lfUnderline = font16->lfUnderline;
61     font32->lfStrikeOut = font16->lfStrikeOut;
62     font32->lfCharSet = font16->lfCharSet;
63     font32->lfOutPrecision = font16->lfOutPrecision;
64     font32->lfClipPrecision = font16->lfClipPrecision;
65     font32->lfQuality = font16->lfQuality;
66     font32->lfPitchAndFamily = font16->lfPitchAndFamily;
67     lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
68 }
69
70 static void CFn_CHOOSEFONT16to32A(LPCHOOSEFONT16 chf16, LPCHOOSEFONTA chf32a)
71 {
72   chf32a->lStructSize=sizeof(CHOOSEFONTA);
73   chf32a->hwndOwner=HWND_32(chf16->hwndOwner);
74   chf32a->hDC=chf16->hDC;
75   chf32a->iPointSize=chf16->iPointSize;
76   chf32a->Flags=chf16->Flags;
77   chf32a->rgbColors=chf16->rgbColors;
78   chf32a->lCustData=chf16->lCustData;
79   chf32a->lpfnHook=NULL;
80   chf32a->lpTemplateName=MapSL(chf16->lpTemplateName);
81   chf32a->hInstance=chf16->hInstance;
82   chf32a->lpszStyle=MapSL(chf16->lpszStyle);
83   chf32a->nFontType=chf16->nFontType;
84   chf32a->nSizeMax=chf16->nSizeMax;
85   chf32a->nSizeMin=chf16->nSizeMin;
86   FONT_LogFont16To32A(MapSL(chf16->lpLogFont), chf32a->lpLogFont);
87 }
88
89 struct {
90     int         mask;
91     char        *name;
92 } cfflags[] = {
93 #define XX(x) { x, #x },
94     XX(CF_SCREENFONTS)
95     XX(CF_PRINTERFONTS)
96     XX(CF_SHOWHELP)
97     XX(CF_ENABLEHOOK)
98     XX(CF_ENABLETEMPLATE)
99     XX(CF_ENABLETEMPLATEHANDLE)
100     XX(CF_INITTOLOGFONTSTRUCT)
101     XX(CF_USESTYLE)
102     XX(CF_EFFECTS)
103     XX(CF_APPLY)
104     XX(CF_ANSIONLY)
105     XX(CF_NOVECTORFONTS)
106     XX(CF_NOSIMULATIONS)
107     XX(CF_LIMITSIZE)
108     XX(CF_FIXEDPITCHONLY)
109     XX(CF_WYSIWYG)
110     XX(CF_FORCEFONTEXIST)
111     XX(CF_SCALABLEONLY)
112     XX(CF_TTONLY)
113     XX(CF_NOFACESEL)
114     XX(CF_NOSTYLESEL)
115     XX(CF_NOSIZESEL)
116     XX(CF_SELECTSCRIPT)
117     XX(CF_NOSCRIPTSEL)
118     XX(CF_NOVERTFONTS)
119 #undef XX
120     {0,NULL},
121 };
122
123 static void
124 _dump_cf_flags(DWORD cflags) {
125     int i;
126
127     for (i=0;cfflags[i].name;i++)
128         if (cfflags[i].mask & cflags)
129             MESSAGE("%s|",cfflags[i].name);
130     MESSAGE("\n");
131 }
132
133
134 /***********************************************************************
135  *                        ChooseFont   (COMMDLG.15)
136  */
137 BOOL16 WINAPI ChooseFont16(LPCHOOSEFONT16 lpChFont)
138 {
139     HINSTANCE16 hInst;
140     HANDLE16 hDlgTmpl16 = 0, hResource16 = 0;
141     HGLOBAL16 hGlobal16 = 0;
142     BOOL16 bRet = FALSE;
143     LPCVOID template;
144     FARPROC16 ptr;
145     CHOOSEFONTA cf32a;
146     LOGFONTA lf32a;
147     LOGFONT16 *font16;
148     SEGPTR lpTemplateName;
149
150     cf32a.lpLogFont=&lf32a;
151     CFn_CHOOSEFONT16to32A(lpChFont, &cf32a);
152
153     TRACE("ChooseFont\n");
154     if (!lpChFont) return FALSE;
155
156     if (TRACE_ON(commdlg))
157         _dump_cf_flags(lpChFont->Flags);
158
159     if (lpChFont->Flags & CF_ENABLETEMPLATEHANDLE)
160     {
161         if (!(template = LockResource16( lpChFont->hInstance )))
162         {
163             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
164             return FALSE;
165         }
166     }
167     else if (lpChFont->Flags & CF_ENABLETEMPLATE)
168     {
169         HANDLE16 hResInfo;
170         if (!(hResInfo = FindResource16( lpChFont->hInstance,
171                                          MapSL(lpChFont->lpTemplateName),
172                                          RT_DIALOGA)))
173         {
174             COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
175             return FALSE;
176         }
177         if (!(hDlgTmpl16 = LoadResource16( lpChFont->hInstance, hResInfo )) ||
178             !(template = LockResource16( hDlgTmpl16 )))
179         {
180             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
181             return FALSE;
182         }
183     }
184     else
185     {
186         HRSRC hResInfo;
187         HGLOBAL hDlgTmpl32;
188         LPCVOID template32;
189         DWORD size;
190         if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "CHOOSE_FONT", RT_DIALOGA)))
191         {
192             COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
193             return FALSE;
194         }
195         if (!(hDlgTmpl32 = LoadResource(COMMDLG_hInstance32, hResInfo)) ||
196             !(template32 = LockResource(hDlgTmpl32)))
197         {
198             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
199             return FALSE;
200         }
201         size = SizeofResource(GetModuleHandleA("COMDLG32"), hResInfo);
202         hGlobal16 = GlobalAlloc16(0, size);
203         if (!hGlobal16)
204         {
205             COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE);
206             ERR("alloc failure for %ld bytes\n", size);
207             return FALSE;
208         }
209         template = GlobalLock16(hGlobal16);
210         if (!template)
211         {
212             COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE);
213             ERR("global lock failure for %x handle\n", hGlobal16);
214             GlobalFree16(hGlobal16);
215             return FALSE;
216         }
217         ConvertDialog32To16((LPVOID)template32, size, (LPVOID)template);
218         hDlgTmpl16 = hGlobal16;
219
220     }
221
222     /* lpTemplateName is not used in the dialog */
223     lpTemplateName=lpChFont->lpTemplateName;
224     lpChFont->lpTemplateName=(SEGPTR)&cf32a;
225
226     ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR) 16);
227     hInst = GetWindowLongA(HWND_32(lpChFont->hwndOwner), GWL_HINSTANCE);
228     bRet = DialogBoxIndirectParam16(hInst, hDlgTmpl16, lpChFont->hwndOwner,
229                      (DLGPROC16) ptr, (DWORD)lpChFont);
230     if (hResource16) FreeResource16(hDlgTmpl16);
231     if (hGlobal16)
232     {
233         GlobalUnlock16(hGlobal16);
234         GlobalFree16(hGlobal16);
235     }
236     lpChFont->lpTemplateName=lpTemplateName;
237
238
239     font16 = MapSL(lpChFont->lpLogFont);
240     font16->lfHeight = cf32a.lpLogFont->lfHeight;
241     font16->lfWidth = cf32a.lpLogFont->lfWidth;
242     font16->lfEscapement = cf32a.lpLogFont->lfEscapement;
243     font16->lfOrientation = cf32a.lpLogFont->lfOrientation;
244     font16->lfWeight = cf32a.lpLogFont->lfWeight;
245     font16->lfItalic = cf32a.lpLogFont->lfItalic;
246     font16->lfUnderline = cf32a.lpLogFont->lfUnderline;
247     font16->lfStrikeOut = cf32a.lpLogFont->lfStrikeOut;
248     font16->lfCharSet = cf32a.lpLogFont->lfCharSet;
249     font16->lfOutPrecision = cf32a.lpLogFont->lfOutPrecision;
250     font16->lfClipPrecision = cf32a.lpLogFont->lfClipPrecision;
251     font16->lfQuality = cf32a.lpLogFont->lfQuality;
252     font16->lfPitchAndFamily = cf32a.lpLogFont->lfPitchAndFamily;
253     lstrcpynA( font16->lfFaceName, cf32a.lpLogFont->lfFaceName, LF_FACESIZE );
254     return bRet;
255 }
256
257
258 /***********************************************************************
259  *           ChooseFontA   (COMDLG32.@)
260  */
261 BOOL WINAPI ChooseFontA(LPCHOOSEFONTA lpChFont)
262 {
263   LPCVOID template;
264   HRSRC hResInfo;
265   HGLOBAL hDlgTmpl;
266
267   if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "CHOOSE_FONT", RT_DIALOGA)))
268   {
269     COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
270     return FALSE;
271   }
272   if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
273       !(template = LockResource( hDlgTmpl )))
274   {
275     COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
276     return FALSE;
277   }
278   if (TRACE_ON(commdlg))
279         _dump_cf_flags(lpChFont->Flags);
280
281   if (lpChFont->Flags & (CF_SELECTSCRIPT | CF_NOVERTFONTS | CF_ENABLETEMPLATE |
282     CF_ENABLETEMPLATEHANDLE)) FIXME(": unimplemented flag (ignored)\n");
283   return DialogBoxIndirectParamA(COMMDLG_hInstance32, template,
284             lpChFont->hwndOwner, FormatCharDlgProcA, (LPARAM)lpChFont );
285 }
286
287 /***********************************************************************
288  *           ChooseFontW   (COMDLG32.@)
289  *
290  *  NOTES:
291  *
292  *      The LOGFONT conversion functions will break if the structure ever
293  *      grows beyond the lfFaceName element.
294  *
295  *      The CHOOSEFONT conversion functions assume that both versions of
296  *      lpLogFont and lpszStyle (if used) point to pre-allocated objects.
297  *
298  *      The ASCII version of lpTemplateName is created by ChooseFontAtoW
299  *      and freed by ChooseFontWtoA.
300  */
301 inline static VOID LogFontWtoA(const LOGFONTW *lfw, LOGFONTA *lfa)
302 {
303     memcpy(lfa, lfw, sizeof(LOGFONTA));
304     WideCharToMultiByte(CP_ACP, 0, lfw->lfFaceName, -1, lfa->lfFaceName,
305             LF_FACESIZE, NULL, NULL);
306     lfa->lfFaceName[LF_FACESIZE - 1] = '\0';
307 }
308
309 inline static VOID LogFontAtoW(const LOGFONTA *lfa, LOGFONTW *lfw)
310 {
311     memcpy(lfw, lfa, sizeof(LOGFONTA));
312     MultiByteToWideChar(CP_ACP, 0, lfa->lfFaceName, -1, lfw->lfFaceName,
313             LF_FACESIZE);
314     lfw->lfFaceName[LF_FACESIZE - 1] = 0;
315 }
316
317 static BOOL ChooseFontWtoA(const CHOOSEFONTW *cfw, CHOOSEFONTA *cfa)
318 {
319     LOGFONTA    *lpLogFont = cfa->lpLogFont;
320     LPSTR       lpszStyle = cfa->lpszStyle;
321
322     memcpy(cfa, cfw, sizeof(CHOOSEFONTA));
323     cfa->lpLogFont = lpLogFont;
324     cfa->lpszStyle = lpszStyle;
325
326     LogFontWtoA(cfw->lpLogFont, lpLogFont);
327
328     if ((cfw->Flags&CF_ENABLETEMPLATE)!=0 && HIWORD(cfw->lpTemplateName)!=0)
329     {
330         cfa->lpTemplateName = HEAP_strdupWtoA(GetProcessHeap(), 0,
331                 cfw->lpTemplateName);
332         if (cfa->lpTemplateName == NULL)
333             return FALSE;
334     }
335
336     if ((cfw->Flags & CF_USESTYLE) != 0 && cfw->lpszStyle != NULL)
337     {
338         WideCharToMultiByte(CP_ACP, 0, cfw->lpszStyle, -1, cfa->lpszStyle,
339                 LF_FACESIZE, NULL, NULL);
340         cfa->lpszStyle[LF_FACESIZE - 1] = '\0';
341     }
342
343     return TRUE;
344 }
345
346 static VOID ChooseFontAtoW(const CHOOSEFONTA *cfa, CHOOSEFONTW *cfw)
347 {
348     LOGFONTW    *lpLogFont = cfw->lpLogFont;
349     LPWSTR      lpszStyle = cfw->lpszStyle;
350     LPCWSTR     lpTemplateName = cfw->lpTemplateName;
351
352     memcpy(cfw, cfa, sizeof(CHOOSEFONTA));
353     cfw->lpLogFont = lpLogFont;
354     cfw->lpszStyle = lpszStyle;
355     cfw->lpTemplateName = lpTemplateName;
356
357     LogFontAtoW(cfa->lpLogFont, lpLogFont);
358
359     if ((cfa->Flags&CF_ENABLETEMPLATE)!=0 && HIWORD(cfa->lpTemplateName) != 0)
360         HeapFree(GetProcessHeap(), 0, (LPSTR)(cfa->lpTemplateName));
361
362     if ((cfa->Flags & CF_USESTYLE) != 0 && cfa->lpszStyle != NULL)
363     {
364         MultiByteToWideChar(CP_ACP, 0, cfa->lpszStyle, -1, cfw->lpszStyle,
365                 LF_FACESIZE);
366         cfw->lpszStyle[LF_FACESIZE - 1] = 0;
367     }
368 }
369
370 BOOL WINAPI ChooseFontW(LPCHOOSEFONTW lpChFont)
371 {
372     CHOOSEFONTA     cf_a;
373     LOGFONTA        lf_a;
374     CHAR            style_a[LF_FACESIZE];
375
376     cf_a.lpLogFont = &lf_a;
377     cf_a.lpszStyle = style_a;
378
379     if (ChooseFontWtoA(lpChFont, &cf_a) == FALSE)
380     {
381         COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE);
382         return FALSE;
383     }
384
385     if (ChooseFontA(&cf_a) == FALSE)
386     {
387         if (cf_a.lpTemplateName != NULL)
388             HeapFree(GetProcessHeap(), 0, (LPSTR)(cf_a.lpTemplateName));
389         return FALSE;
390     }
391
392     ChooseFontAtoW(&cf_a, lpChFont);
393
394     return TRUE;
395 }
396
397 #if 0
398 /***********************************************************************
399  *           ChooseFontW   (COMDLG32.@)
400  */
401 BOOL WINAPI ChooseFontW(LPCHOOSEFONTW lpChFont)
402 {
403   BOOL bRet=FALSE;
404   CHOOSEFONTA cf32a;
405   LOGFONTA lf32a;
406   LPCVOID template;
407   HANDLE hResInfo, hDlgTmpl;
408
409   if (TRACE_ON(commdlg))
410         _dump_cf_flags(lpChFont->Flags);
411
412   if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "CHOOSE_FONT", RT_DIALOGA)))
413   {
414     COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
415     return FALSE;
416   }
417   if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
418       !(template = LockResource( hDlgTmpl )))
419   {
420     COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
421     return FALSE;
422   }
423
424   if (lpChFont->Flags & (CF_SELECTSCRIPT | CF_NOVERTFONTS | CF_ENABLETEMPLATE |
425     CF_ENABLETEMPLATEHANDLE)) FIXME(": unimplemented flag (ignored)\n");
426   memcpy(&cf32a, lpChFont, sizeof(cf32a));
427   memcpy(&lf32a, lpChFont->lpLogFont, sizeof(LOGFONTA));
428
429   WideCharToMultiByte( CP_ACP, 0, lpChFont->lpLogFont->lfFaceName, -1,
430                        lf32a.lfFaceName, LF_FACESIZE, NULL, NULL );
431   lf32a.lfFaceName[LF_FACESIZE-1] = 0;
432   cf32a.lpLogFont=&lf32a;
433   cf32a.lpszStyle=HEAP_strdupWtoA(GetProcessHeap(), 0, lpChFont->lpszStyle);
434   lpChFont->lpTemplateName=(LPWSTR)&cf32a;
435   bRet = DialogBoxIndirectParamW(COMMDLG_hInstance32, template,
436             lpChFont->hwndOwner, FormatCharDlgProcW, (LPARAM)lpChFont );
437   HeapFree(GetProcessHeap(), 0, cf32a.lpszStyle);
438   lpChFont->lpTemplateName=(LPWSTR)cf32a.lpTemplateName;
439   memcpy(lpChFont->lpLogFont, &lf32a, sizeof(CHOOSEFONTA));
440   MultiByteToWideChar( CP_ACP, 0, lf32a.lfFaceName, -1,
441                        lpChFont->lpLogFont->lfFaceName, LF_FACESIZE );
442   lpChFont->lpLogFont->lfFaceName[LF_FACESIZE-1] = 0;
443   return bRet;
444 }
445 #endif
446
447 #define TEXT_EXTRAS 4
448 #define TEXT_COLORS 16
449
450 static const COLORREF textcolors[TEXT_COLORS]=
451 {
452  0x00000000L,0x00000080L,0x00008000L,0x00008080L,
453  0x00800000L,0x00800080L,0x00808000L,0x00808080L,
454  0x00c0c0c0L,0x000000ffL,0x0000ff00L,0x0000ffffL,
455  0x00ff0000L,0x00ff00ffL,0x00ffff00L,0x00FFFFFFL
456 };
457
458 /***********************************************************************
459  *                          CFn_HookCallChk                 [internal]
460  */
461 static BOOL CFn_HookCallChk(LPCHOOSEFONT16 lpcf)
462 {
463  if (lpcf)
464   if(lpcf->Flags & CF_ENABLEHOOK)
465    if (lpcf->lpfnHook)
466     return TRUE;
467  return FALSE;
468 }
469
470 /***********************************************************************
471  *                          CFn_HookCallChk32                 [internal]
472  */
473 static BOOL CFn_HookCallChk32(LPCHOOSEFONTA lpcf)
474 {
475  if (lpcf)
476   if(lpcf->Flags & CF_ENABLEHOOK)
477    if (lpcf->lpfnHook)
478     return TRUE;
479  return FALSE;
480 }
481
482 typedef struct
483 {
484   HWND hWnd1;
485   HWND hWnd2;
486   LPCHOOSEFONTA lpcf32a;
487   int  added;
488 } CFn_ENUMSTRUCT, *LPCFn_ENUMSTRUCT;
489
490 /*************************************************************************
491  *              AddFontFamily                               [internal]
492  */
493 static INT AddFontFamily(const LOGFONTA *lplf, UINT nFontType,
494                            LPCHOOSEFONTA lpcf, HWND hwnd, LPCFn_ENUMSTRUCT e)
495 {
496   int i;
497   WORD w;
498
499   TRACE("font=%s (nFontType=%d)\n", lplf->lfFaceName,nFontType);
500
501   if (lpcf->Flags & CF_FIXEDPITCHONLY)
502    if (!(lplf->lfPitchAndFamily & FIXED_PITCH))
503      return 1;
504   if (lpcf->Flags & CF_ANSIONLY)
505    if (lplf->lfCharSet != ANSI_CHARSET)
506      return 1;
507   if (lpcf->Flags & CF_TTONLY)
508    if (!(nFontType & TRUETYPE_FONTTYPE))
509      return 1;
510
511   if (e) e->added++;
512
513   i=SendMessageA(hwnd, CB_ADDSTRING, 0, (LPARAM)lplf->lfFaceName);
514   if (i!=CB_ERR)
515   {
516     w=(lplf->lfCharSet << 8) | lplf->lfPitchAndFamily;
517     SendMessageA(hwnd, CB_SETITEMDATA, i, MAKELONG(nFontType,w));
518     return 1 ;        /* store some important font information */
519   }
520   else
521     return 0;
522 }
523
524 /*************************************************************************
525  *              FontFamilyEnumProc32                           [internal]
526  */
527 static INT WINAPI FontFamilyEnumProc(const LOGFONTA *lpLogFont,
528           const TEXTMETRICA *metrics, DWORD dwFontType, LPARAM lParam)
529 {
530   LPCFn_ENUMSTRUCT e;
531   e=(LPCFn_ENUMSTRUCT)lParam;
532   return AddFontFamily(lpLogFont, dwFontType, e->lpcf32a, e->hWnd1, e);
533 }
534
535 /***********************************************************************
536  *                FontFamilyEnumProc                     (COMMDLG.19)
537  */
538 INT16 WINAPI FontFamilyEnumProc16( SEGPTR logfont, SEGPTR metrics,
539                                    UINT16 nFontType, LPARAM lParam )
540 {
541   HWND hwnd=HWND_32(LOWORD(lParam));
542   HWND hDlg=GetParent(hwnd);
543   LPCHOOSEFONT16 lpcf=(LPCHOOSEFONT16)GetWindowLongA(hDlg, DWL_USER);
544   LOGFONT16 *lplf = MapSL( logfont );
545   LOGFONTA lf32a;
546   FONT_LogFont16To32A(lplf, &lf32a);
547   return AddFontFamily(&lf32a, nFontType, (LPCHOOSEFONTA)lpcf->lpTemplateName,
548                        hwnd,NULL);
549 }
550
551 /*************************************************************************
552  *              SetFontStylesToCombo2                           [internal]
553  *
554  * Fill font style information into combobox  (without using font.c directly)
555  */
556 static int SetFontStylesToCombo2(HWND hwnd, HDC hdc, const LOGFONTA *lplf)
557 {
558    #define FSTYLES 4
559    struct FONTSTYLE
560           { int italic;
561             int weight;
562             char stname[20]; };
563    static struct FONTSTYLE fontstyles[FSTYLES]={
564           { 0,FW_NORMAL,"Regular"},{0,FW_BOLD,"Bold"},
565           { 1,FW_NORMAL,"Italic"}, {1,FW_BOLD,"Bold Italic"}};
566    HFONT hf;
567    TEXTMETRICA tm;
568    int i,j;
569    LOGFONTA lf;
570
571    memcpy(&lf, lplf, sizeof(LOGFONTA));
572
573    for (i=0;i<FSTYLES;i++)
574    {
575      lf.lfItalic=fontstyles[i].italic;
576      lf.lfWeight=fontstyles[i].weight;
577      hf=CreateFontIndirectA(&lf);
578      hf=SelectObject(hdc,hf);
579      GetTextMetricsA(hdc,&tm);
580      hf=SelectObject(hdc,hf);
581      DeleteObject(hf);
582
583      if (tm.tmWeight==fontstyles[i].weight &&
584          tm.tmItalic==fontstyles[i].italic)    /* font successful created ? */
585      {
586        j=SendMessageA(hwnd,CB_ADDSTRING,0,(LPARAM)fontstyles[i].stname );
587        if (j==CB_ERR) return 1;
588        j=SendMessageA(hwnd, CB_SETITEMDATA, j,
589                                  MAKELONG(fontstyles[i].weight,fontstyles[i].italic));
590        if (j==CB_ERR) return 1;
591      }
592    }
593   return 0;
594 }
595
596 /*************************************************************************
597  *              AddFontSizeToCombo3                           [internal]
598  */
599 static int AddFontSizeToCombo3(HWND hwnd, UINT h, LPCHOOSEFONTA lpcf)
600 {
601     int j;
602     char buffer[20];
603
604     if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
605         ((lpcf->Flags & CF_LIMITSIZE) && (h >= lpcf->nSizeMin) && (h <= lpcf->nSizeMax)))
606     {
607         sprintf(buffer, "%2d", h);
608         j=SendMessageA(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)buffer);
609         if (j==CB_ERR)
610         {
611             j=SendMessageA(hwnd, CB_ADDSTRING, 0, (LPARAM)buffer);
612             if (j!=CB_ERR) j = SendMessageA(hwnd, CB_SETITEMDATA, j, h);
613             if (j==CB_ERR) return 1;
614         }
615     }
616     return 0;
617 }
618
619 /*************************************************************************
620  *              SetFontSizesToCombo3                           [internal]
621  */
622 static int SetFontSizesToCombo3(HWND hwnd, LPCHOOSEFONTA lpcf)
623 {
624   static const int sizes[]={8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72,0};
625   int i;
626
627   for (i=0; sizes[i]; i++)
628     if (AddFontSizeToCombo3(hwnd, sizes[i], lpcf)) return 1;
629   return 0;
630 }
631
632 /***********************************************************************
633  *                 AddFontStyle                          [internal]
634  */
635 static INT AddFontStyle(const LOGFONTA *lplf, UINT nFontType,
636     LPCHOOSEFONTA lpcf, HWND hcmb2, HWND hcmb3, HWND hDlg)
637 {
638   int i;
639
640   TRACE("(nFontType=%d)\n",nFontType);
641   TRACE("  %s h=%ld w=%ld e=%ld o=%ld wg=%ld i=%d u=%d s=%d"
642                " ch=%d op=%d cp=%d q=%d pf=%xh\n",
643                lplf->lfFaceName,lplf->lfHeight,lplf->lfWidth,
644                lplf->lfEscapement,lplf->lfOrientation,
645                lplf->lfWeight,lplf->lfItalic,lplf->lfUnderline,
646                lplf->lfStrikeOut,lplf->lfCharSet, lplf->lfOutPrecision,
647                lplf->lfClipPrecision,lplf->lfQuality, lplf->lfPitchAndFamily);
648   if (nFontType & RASTER_FONTTYPE)
649   {
650     if (AddFontSizeToCombo3(hcmb3, lplf->lfHeight, lpcf)) return 0;
651   } else if (SetFontSizesToCombo3(hcmb3, lpcf)) return 0;
652
653   if (!SendMessageA(hcmb2, CB_GETCOUNT, 0, 0))
654   {
655        HDC hdc= ((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
656        i=SetFontStylesToCombo2(hcmb2,hdc,lplf);
657        if (!((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC))
658          ReleaseDC(hDlg,hdc);
659        if (i)
660         return 0;
661   }
662   return 1 ;
663
664 }
665
666 /***********************************************************************
667  *                 FontStyleEnumProc                     (COMMDLG.18)
668  */
669 INT16 WINAPI FontStyleEnumProc16( SEGPTR logfont, SEGPTR metrics,
670                                   UINT16 nFontType, LPARAM lParam )
671 {
672   HWND hcmb2=HWND_32(LOWORD(lParam));
673   HWND hcmb3=HWND_32(HIWORD(lParam));
674   HWND hDlg=GetParent(hcmb3);
675   LPCHOOSEFONT16 lpcf=(LPCHOOSEFONT16)GetWindowLongA(hDlg, DWL_USER);
676   LOGFONT16 *lplf = MapSL(logfont);
677   LOGFONTA lf32a;
678   FONT_LogFont16To32A(lplf, &lf32a);
679   return AddFontStyle(&lf32a, nFontType, (LPCHOOSEFONTA)lpcf->lpTemplateName,
680                       hcmb2, hcmb3, hDlg);
681 }
682
683 /***********************************************************************
684  *                 FontStyleEnumProc32                     [internal]
685  */
686 static INT WINAPI FontStyleEnumProc( const LOGFONTA *lpFont,
687           const TEXTMETRICA *metrics, DWORD dwFontType, LPARAM lParam )
688 {
689   LPCFn_ENUMSTRUCT s=(LPCFn_ENUMSTRUCT)lParam;
690   HWND hcmb2=s->hWnd1;
691   HWND hcmb3=s->hWnd2;
692   HWND hDlg=GetParent(hcmb3);
693   return AddFontStyle(lpFont, dwFontType, s->lpcf32a, hcmb2,
694                       hcmb3, hDlg);
695 }
696
697 /***********************************************************************
698  *           CFn_WMInitDialog                            [internal]
699  */
700 static LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam,
701                          LPCHOOSEFONTA lpcf)
702 {
703   HDC hdc;
704   int i,j,res,init=0;
705   long l;
706   LPLOGFONTA lpxx;
707   HCURSOR hcursor=SetCursor(LoadCursorA(0,IDC_WAITA));
708
709   SetWindowLongA(hDlg, DWL_USER, lParam);
710   lpxx=lpcf->lpLogFont;
711   TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
712
713   if (lpcf->lStructSize != sizeof(CHOOSEFONTA))
714   {
715     ERR("structure size failure !!!\n");
716     EndDialog (hDlg, 0);
717     return FALSE;
718   }
719   if (!hBitmapTT)
720     hBitmapTT = LoadBitmapA(0, MAKEINTRESOURCEA(OBM_TRTYPE));
721
722   /* This font will be deleted by WM_COMMAND */
723   SendDlgItemMessageA(hDlg,stc6,WM_SETFONT,
724      CreateFontA(0, 0, 1, 1, 400, 0, 0, 0, 0, 0, 0, 0, 0, NULL),FALSE);
725
726   if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow(lpcf->hwndOwner))
727     ShowWindow(GetDlgItem(hDlg,pshHelp),SW_HIDE);
728   if (!(lpcf->Flags & CF_APPLY))
729     ShowWindow(GetDlgItem(hDlg,psh3),SW_HIDE);
730   if (lpcf->Flags & CF_EFFECTS)
731   {
732     for (res=1,i=0;res && i<TEXT_COLORS;i++)
733     {
734       /* FIXME: load color name from resource:  res=LoadString(...,i+....,buffer,.....); */
735       char name[20];
736       strcpy( name, "[color name]" );
737       j=SendDlgItemMessageA(hDlg, cmb4, CB_ADDSTRING, 0, (LPARAM)name);
738       SendDlgItemMessageA(hDlg, cmb4, CB_SETITEMDATA16, j, textcolors[j]);
739       /* look for a fitting value in color combobox */
740       if (textcolors[j]==lpcf->rgbColors)
741         SendDlgItemMessageA(hDlg,cmb4, CB_SETCURSEL,j,0);
742     }
743   }
744   else
745   {
746     ShowWindow(GetDlgItem(hDlg,cmb4),SW_HIDE);
747     ShowWindow(GetDlgItem(hDlg,chx1),SW_HIDE);
748     ShowWindow(GetDlgItem(hDlg,chx2),SW_HIDE);
749     ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
750     ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
751   }
752   hdc= ((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
753   if (hdc)
754   {
755     CFn_ENUMSTRUCT s;
756     s.hWnd1=GetDlgItem(hDlg,cmb1);
757     s.lpcf32a=lpcf;
758     do {
759         s.added = 0;
760         if (!EnumFontFamiliesA(hdc, NULL, FontFamilyEnumProc, (LPARAM)&s)) {
761           TRACE("EnumFontFamilies returns 0\n");
762           break;
763         }
764         if (s.added) break;
765         if (lpcf->Flags & CF_FIXEDPITCHONLY) {
766             FIXME("No founds found with fixed pitch only, dropping flag.\n");
767             lpcf->Flags &= ~CF_FIXEDPITCHONLY;
768             continue;
769         }
770         if (lpcf->Flags & CF_TTONLY) {
771             FIXME("No founds found with truetype only, dropping flag.\n");
772             lpcf->Flags &= ~CF_TTONLY;
773             continue;
774         }
775         break;
776      } while (1);
777
778
779     if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
780     {
781       /* look for fitting font name in combobox1 */
782       j=SendDlgItemMessageA(hDlg,cmb1,CB_FINDSTRING,-1,(LONG)lpxx->lfFaceName);
783       if (j!=CB_ERR)
784       {
785         SendDlgItemMessageA(hDlg, cmb1, CB_SETCURSEL, j, 0);
786         SendMessageA(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
787                      (LPARAM)GetDlgItem(hDlg,cmb1));
788         init=1;
789         /* look for fitting font style in combobox2 */
790         l=MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD:FW_NORMAL,lpxx->lfItalic !=0);
791         for (i=0;i<TEXT_EXTRAS;i++)
792         {
793           if (l==SendDlgItemMessageA(hDlg, cmb2, CB_GETITEMDATA, i, 0))
794             SendDlgItemMessageA(hDlg, cmb2, CB_SETCURSEL, i, 0);
795         }
796
797         /* look for fitting font size in combobox3 */
798         j=SendDlgItemMessageA(hDlg, cmb3, CB_GETCOUNT, 0, 0);
799         for (i=0;i<j;i++)
800         {
801           if (lpxx->lfHeight==(int)SendDlgItemMessageA(hDlg,cmb3, CB_GETITEMDATA,i,0))
802             SendDlgItemMessageA(hDlg,cmb3,CB_SETCURSEL,i,0);
803         }
804       }
805     }
806     if (!init)
807     {
808       SendDlgItemMessageA(hDlg,cmb1,CB_SETCURSEL,0,0);
809       SendMessageA(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
810                    (LPARAM)GetDlgItem(hDlg,cmb1));
811     }
812     if (lpcf->Flags & CF_USESTYLE && lpcf->lpszStyle)
813     {
814       j=SendDlgItemMessageA(hDlg,cmb2,CB_FINDSTRING,-1,(LONG)lpcf->lpszStyle);
815       if (j!=CB_ERR)
816       {
817         j=SendDlgItemMessageA(hDlg,cmb2,CB_SETCURSEL,j,0);
818         SendMessageA(hDlg,WM_COMMAND,cmb2,
819                        MAKELONG(HWND_16(GetDlgItem(hDlg,cmb2)),CBN_SELCHANGE));
820       }
821     }
822   }
823   else
824   {
825     WARN("HDC failure !!!\n");
826     EndDialog (hDlg, 0);
827     return FALSE;
828   }
829
830   if (!((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC))
831     ReleaseDC(hDlg,hdc);
832   SetCursor(hcursor);
833   return TRUE;
834 }
835
836
837 /***********************************************************************
838  *           CFn_WMMeasureItem                           [internal]
839  */
840 static LRESULT CFn_WMMeasureItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
841 {
842   BITMAP bm;
843   LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam;
844   if (!hBitmapTT)
845     hBitmapTT = LoadBitmapA(0, MAKEINTRESOURCEA(OBM_TRTYPE));
846   GetObjectA( hBitmapTT, sizeof(bm), &bm );
847   lpmi->itemHeight=bm.bmHeight;
848   /* FIXME: use MAX of bm.bmHeight and tm.tmHeight .*/
849   return 0;
850 }
851
852
853 /***********************************************************************
854  *           CFn_WMDrawItem                              [internal]
855  */
856 static LRESULT CFn_WMDrawItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
857 {
858   HBRUSH hBrush;
859   char buffer[40];
860   BITMAP bm;
861   COLORREF cr, oldText=0, oldBk=0;
862   RECT rect;
863 #if 0
864   HDC hMemDC;
865   int nFontType;
866   HBITMAP hBitmap; /* for later TT usage */
867 #endif
868   LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam;
869
870   if (lpdi->itemID == (UINT)-1)  /* got no items */
871     DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
872   else
873   {
874    if (lpdi->CtlType == ODT_COMBOBOX)
875    {
876      if (lpdi->itemState ==ODS_SELECTED)
877      {
878        hBrush=GetSysColorBrush(COLOR_HIGHLIGHT);
879        oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
880        oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT));
881      }  else
882      {
883        hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
884        SelectObject(lpdi->hDC, hBrush);
885      }
886      FillRect(lpdi->hDC, &lpdi->rcItem, hBrush);
887    }
888    else
889      return TRUE;       /* this should never happen */
890
891    rect=lpdi->rcItem;
892    switch (lpdi->CtlID)
893    {
894     case cmb1:  /* TRACE(commdlg,"WM_Drawitem cmb1\n"); */
895                 SendMessageA(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
896                                (LPARAM)buffer);
897                 GetObjectA( hBitmapTT, sizeof(bm), &bm );
898                 TextOutA(lpdi->hDC, lpdi->rcItem.left + bm.bmWidth + 10,
899                            lpdi->rcItem.top, buffer, strlen(buffer));
900 #if 0
901                 nFontType = SendMessageA(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
902                   /* FIXME: draw bitmap if truetype usage */
903                 if (nFontType&TRUETYPE_FONTTYPE)
904                 {
905                   hMemDC = CreateCompatibleDC(lpdi->hDC);
906                   hBitmap = SelectObject(hMemDC, hBitmapTT);
907                   BitBlt(lpdi->hDC, lpdi->rcItem.left, lpdi->rcItem.top,
908                            bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
909                   SelectObject(hMemDC, hBitmap);
910                   DeleteDC(hMemDC);
911                 }
912 #endif
913                 break;
914     case cmb2:
915     case cmb3:  /* TRACE(commdlg,"WM_DRAWITEN cmb2,cmb3\n"); */
916                 SendMessageA(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
917                                (LPARAM)buffer);
918                 TextOutA(lpdi->hDC, lpdi->rcItem.left,
919                            lpdi->rcItem.top, buffer, strlen(buffer));
920                 break;
921
922     case cmb4:  /* TRACE(commdlg,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
923                 SendMessageA(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
924                                (LPARAM)buffer);
925                 TextOutA(lpdi->hDC, lpdi->rcItem.left +  25+5,
926                            lpdi->rcItem.top, buffer, strlen(buffer));
927                 cr = SendMessageA(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
928                 hBrush = CreateSolidBrush(cr);
929                 if (hBrush)
930                 {
931                   hBrush = SelectObject (lpdi->hDC, hBrush) ;
932                   rect.right=rect.left+25;
933                   rect.top++;
934                   rect.left+=5;
935                   rect.bottom--;
936                   Rectangle( lpdi->hDC, rect.left, rect.top,
937                                rect.right, rect.bottom );
938                   DeleteObject( SelectObject (lpdi->hDC, hBrush)) ;
939                 }
940                 rect=lpdi->rcItem;
941                 rect.left+=25+5;
942                 break;
943
944     default:    return TRUE;    /* this should never happen */
945    }
946    if (lpdi->itemState == ODS_SELECTED)
947    {
948      SetTextColor(lpdi->hDC, oldText);
949      SetBkColor(lpdi->hDC, oldBk);
950    }
951  }
952  return TRUE;
953 }
954
955 /***********************************************************************
956  *           CFn_WMCtlColor                              [internal]
957  */
958 static LRESULT CFn_WMCtlColorStatic(HWND hDlg, WPARAM wParam, LPARAM lParam,
959                              LPCHOOSEFONTA lpcf)
960 {
961   if (lpcf->Flags & CF_EFFECTS)
962    if (GetDlgCtrlID(HWND_32(LOWORD(lParam)))==stc6)
963    {
964      SetTextColor((HDC)wParam, lpcf->rgbColors);
965      return GetStockObject(WHITE_BRUSH);
966    }
967   return 0;
968 }
969
970 /***********************************************************************
971  *           CFn_WMCommand                               [internal]
972  */
973 static LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam,
974                       LPCHOOSEFONTA lpcf)
975 {
976   HFONT hFont;
977   int i,j;
978   long l;
979   HDC hdc;
980   LPLOGFONTA lpxx=lpcf->lpLogFont;
981
982   TRACE("WM_COMMAND wParam=%08lX lParam=%08lX\n", (LONG)wParam, lParam);
983   switch (LOWORD(wParam))
984   {
985         case cmb1:if (HIWORD(wParam)==CBN_SELCHANGE)
986                   {
987                     hdc=((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
988                     if (hdc)
989                     {
990                       SendDlgItemMessageA(hDlg, cmb2, CB_RESETCONTENT16, 0, 0);
991                       SendDlgItemMessageA(hDlg, cmb3, CB_RESETCONTENT16, 0, 0);
992                       i=SendDlgItemMessageA(hDlg, cmb1, CB_GETCURSEL16, 0, 0);
993                       if (i!=CB_ERR)
994                       {
995                         HCURSOR hcursor=SetCursor(LoadCursorA(0,IDC_WAITA));
996                         CFn_ENUMSTRUCT s;
997                         char str[256];
998                         SendDlgItemMessageA(hDlg, cmb1, CB_GETLBTEXT, i,
999                                               (LPARAM)str);
1000                         TRACE("WM_COMMAND/cmb1 =>%s\n",str);
1001                         s.hWnd1=GetDlgItem(hDlg, cmb2);
1002                         s.hWnd2=GetDlgItem(hDlg, cmb3);
1003                         s.lpcf32a=lpcf;
1004                         EnumFontFamiliesA(hdc, str, FontStyleEnumProc, (LPARAM)&s);
1005                         SendDlgItemMessageA(hDlg,cmb2, CB_SETCURSEL, 0, 0);
1006                         SendDlgItemMessageA(hDlg,cmb3, CB_SETCURSEL, 0, 0);
1007                         SetCursor(hcursor);
1008                       }
1009                       if (!((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC))
1010                         ReleaseDC(hDlg,hdc);
1011                     }
1012                     else
1013                     {
1014                       WARN("HDC failure !!!\n");
1015                       EndDialog (hDlg, 0);
1016                       return TRUE;
1017                     }
1018                   }
1019         case chx1:
1020         case chx2:
1021         case cmb2:
1022         case cmb3:if (HIWORD(wParam)==CBN_SELCHANGE || HIWORD(wParam)== BN_CLICKED )
1023                   {
1024                     char str[256];
1025                     TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
1026                     i=SendDlgItemMessageA(hDlg,cmb1,CB_GETCURSEL,0,0);
1027                     if (i==CB_ERR)
1028                       i=GetDlgItemTextA( hDlg, cmb1, str, 256 );
1029                     else
1030                     {
1031                       SendDlgItemMessageA(hDlg,cmb1,CB_GETLBTEXT,i,
1032                                             (LPARAM)str);
1033                       l=SendDlgItemMessageA(hDlg,cmb1,CB_GETITEMDATA,i,0);
1034                       j=HIWORD(l);
1035                       lpcf->nFontType = LOWORD(l);
1036                       /* FIXME:   lpcf->nFontType |= ....  SIMULATED_FONTTYPE and so */
1037                       /* same value reported to the EnumFonts
1038                        call back with the extra FONTTYPE_...  bits added */
1039                       lpxx->lfPitchAndFamily=j&0xff;
1040                       lpxx->lfCharSet=j>>8;
1041                     }
1042                     strcpy(lpxx->lfFaceName,str);
1043                     i=SendDlgItemMessageA(hDlg, cmb2, CB_GETCURSEL, 0, 0);
1044                     if (i!=CB_ERR)
1045                     {
1046                       l=SendDlgItemMessageA(hDlg, cmb2, CB_GETITEMDATA, i, 0);
1047                       if (0!=(lpxx->lfItalic=HIWORD(l)))
1048                         lpcf->nFontType |= ITALIC_FONTTYPE;
1049                       if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
1050                         lpcf->nFontType |= BOLD_FONTTYPE;
1051                     }
1052                     i=SendDlgItemMessageA(hDlg, cmb3, CB_GETCURSEL, 0, 0);
1053                     if (i!=CB_ERR)
1054                       lpxx->lfHeight=-LOWORD(SendDlgItemMessageA(hDlg, cmb3, CB_GETITEMDATA, i, 0));
1055                     else
1056                       lpxx->lfHeight=0;
1057                     lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
1058                     lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
1059                     lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
1060                     lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
1061                     lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
1062                     lpxx->lfQuality=DEFAULT_QUALITY;
1063                     lpcf->iPointSize= -10*lpxx->lfHeight;
1064
1065                     hFont=CreateFontIndirectA(lpxx);
1066                     if (hFont)
1067                     {
1068                       HFONT oldFont=SendDlgItemMessageA(hDlg, stc6,
1069                           WM_GETFONT, 0, 0);
1070                       SendDlgItemMessageA(hDlg,stc6,WM_SETFONT,hFont,TRUE);
1071                       DeleteObject(oldFont);
1072                     }
1073                   }
1074                   break;
1075
1076         case cmb4:i=SendDlgItemMessageA(hDlg, cmb4, CB_GETCURSEL, 0, 0);
1077                   if (i!=CB_ERR)
1078                   {
1079                    lpcf->rgbColors=textcolors[i];
1080                    InvalidateRect( GetDlgItem(hDlg,stc6), NULL, 0 );
1081                   }
1082                   break;
1083
1084         case psh15:i=RegisterWindowMessageA( HELPMSGSTRINGA );
1085                   if (lpcf->hwndOwner)
1086                     SendMessageA(lpcf->hwndOwner, i, 0, (LPARAM)GetWindowLongA(hDlg, DWL_USER));
1087 /*                if (CFn_HookCallChk(lpcf))
1088                     CallWindowProc16(lpcf->lpfnHook,hDlg,WM_COMMAND,psh15,(LPARAM)lpcf);*/
1089                   break;
1090
1091         case IDOK:if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
1092                      ( (lpcf->Flags & CF_LIMITSIZE) &&
1093                       (-lpxx->lfHeight >= lpcf->nSizeMin) &&
1094                       (-lpxx->lfHeight <= lpcf->nSizeMax)))
1095                      EndDialog(hDlg, TRUE);
1096                   else
1097                   {
1098                    char buffer[80];
1099                    sprintf(buffer,"Select a font size between %d and %d points.",
1100                            lpcf->nSizeMin,lpcf->nSizeMax);
1101                    MessageBoxA(hDlg, buffer, NULL, MB_OK);
1102                   }
1103                   return(TRUE);
1104         case IDCANCEL:EndDialog(hDlg, FALSE);
1105                   return(TRUE);
1106         }
1107       return(FALSE);
1108 }
1109
1110 static LRESULT CFn_WMDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam)
1111 {
1112   DeleteObject(SendDlgItemMessageA(hwnd, stc6, WM_GETFONT, 0, 0));
1113   return TRUE;
1114 }
1115
1116
1117 /***********************************************************************
1118  *           FormatCharDlgProc   (COMMDLG.16)
1119              FIXME: 1. some strings are "hardcoded", but it's better load from sysres
1120                     2. some CF_.. flags are not supported
1121                     3. some TType extensions
1122  */
1123 BOOL16 CALLBACK FormatCharDlgProc16(HWND16 hDlg16, UINT16 message,
1124                                    WPARAM16 wParam, LPARAM lParam)
1125 {
1126   HWND hDlg = HWND_32(hDlg16);
1127   LPCHOOSEFONT16 lpcf;
1128   LPCHOOSEFONTA lpcf32a;
1129   BOOL16 res=0;
1130   if (message!=WM_INITDIALOG)
1131   {
1132    lpcf=(LPCHOOSEFONT16)GetWindowLongA(hDlg, DWL_USER);
1133    if (!lpcf)
1134       return FALSE;
1135    if (CFn_HookCallChk(lpcf))
1136      res=CallWindowProc16((WNDPROC16)lpcf->lpfnHook,hDlg16,message,wParam,lParam);
1137    if (res)
1138     return res;
1139   }
1140   else
1141   {
1142     lpcf=(LPCHOOSEFONT16)lParam;
1143     lpcf32a=(LPCHOOSEFONTA)lpcf->lpTemplateName;
1144     if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcf32a))
1145     {
1146       TRACE("CFn_WMInitDialog returned FALSE\n");
1147       return FALSE;
1148     }
1149     if (CFn_HookCallChk(lpcf))
1150       return CallWindowProc16((WNDPROC16)lpcf->lpfnHook,hDlg16,WM_INITDIALOG,wParam,lParam);
1151   }
1152   lpcf32a=(LPCHOOSEFONTA)lpcf->lpTemplateName;
1153   switch (message)
1154     {
1155     case WM_MEASUREITEM:
1156         {
1157             MEASUREITEMSTRUCT16* mis16 = MapSL(lParam);
1158             MEASUREITEMSTRUCT mis;
1159             mis.CtlType    = mis16->CtlType;
1160             mis.CtlID      = mis16->CtlID;
1161             mis.itemID     = mis16->itemID;
1162             mis.itemWidth  = mis16->itemWidth;
1163             mis.itemHeight = mis16->itemHeight;
1164             mis.itemData   = mis16->itemData;
1165             res = CFn_WMMeasureItem(hDlg, wParam, (LPARAM)&mis);
1166             mis16->itemWidth  = (UINT16)mis.itemWidth;
1167             mis16->itemHeight = (UINT16)mis.itemHeight;
1168         }
1169         break;
1170     case WM_DRAWITEM:
1171         {
1172             DRAWITEMSTRUCT16* dis16 = MapSL(lParam);
1173             DRAWITEMSTRUCT dis;
1174             dis.CtlType    = dis16->CtlType;
1175             dis.CtlID      = dis16->CtlID;
1176             dis.itemID     = dis16->itemID;
1177             dis.itemAction = dis16->itemAction;
1178             dis.itemState  = dis16->itemState;
1179             dis.hwndItem   = HWND_32(dis16->hwndItem);
1180             dis.hDC        = dis16->hDC;
1181             dis.itemData   = dis16->itemData;
1182             CONV_RECT16TO32( &dis16->rcItem, &dis.rcItem );
1183             res = CFn_WMDrawItem(hDlg, wParam, (LPARAM)&dis);
1184         }
1185         break;
1186     case WM_CTLCOLOR:
1187         if (HIWORD(lParam) == CTLCOLOR_STATIC)
1188             res=CFn_WMCtlColorStatic(hDlg, (HDC)wParam, LOWORD(lParam), lpcf32a);
1189         break;
1190     case WM_COMMAND:
1191         res=CFn_WMCommand(hDlg, MAKEWPARAM( wParam, HIWORD(lParam) ), LOWORD(lParam), lpcf32a);
1192         break;
1193     case WM_DESTROY:
1194         res=CFn_WMDestroy(hDlg, wParam, lParam);
1195         break;
1196     case WM_CHOOSEFONT_GETLOGFONT:
1197         TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
1198         FIXME("current logfont back to caller\n");
1199         break;
1200     }
1201   return res;
1202 }
1203
1204 /***********************************************************************
1205  *           FormatCharDlgProcA   [internal]
1206  */
1207 INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
1208                                     LPARAM lParam)
1209 {
1210   LPCHOOSEFONTA lpcf;
1211   INT_PTR res = FALSE;
1212   if (uMsg!=WM_INITDIALOG)
1213   {
1214    lpcf=(LPCHOOSEFONTA)GetWindowLongA(hDlg, DWL_USER);
1215    if (!lpcf)
1216      return FALSE;
1217    if (CFn_HookCallChk32(lpcf))
1218      res=CallWindowProcA((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam);
1219    if (res)
1220      return res;
1221   }
1222   else
1223   {
1224     lpcf=(LPCHOOSEFONTA)lParam;
1225     if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcf))
1226     {
1227       TRACE("CFn_WMInitDialog returned FALSE\n");
1228       return FALSE;
1229     }
1230     if (CFn_HookCallChk32(lpcf))
1231       return CallWindowProcA((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1232   }
1233   switch (uMsg)
1234     {
1235       case WM_MEASUREITEM:
1236                         return CFn_WMMeasureItem(hDlg, wParam, lParam);
1237       case WM_DRAWITEM:
1238                         return CFn_WMDrawItem(hDlg, wParam, lParam);
1239       case WM_CTLCOLORSTATIC:
1240                         return CFn_WMCtlColorStatic(hDlg, wParam, lParam, lpcf);
1241       case WM_COMMAND:
1242                         return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
1243       case WM_DESTROY:
1244                         return CFn_WMDestroy(hDlg, wParam, lParam);
1245       case WM_CHOOSEFONT_GETLOGFONT:
1246                          TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n",
1247                                       lParam);
1248                          FIXME("current logfont back to caller\n");
1249                         break;
1250     }
1251   return res;
1252 }
1253
1254 /***********************************************************************
1255  *           FormatCharDlgProcW   [internal]
1256  */
1257 INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam,
1258                                     LPARAM lParam)
1259 {
1260   LPCHOOSEFONTW lpcf32w;
1261   LPCHOOSEFONTA lpcf32a;
1262   INT_PTR res = FALSE;
1263   if (uMsg!=WM_INITDIALOG)
1264   {
1265    lpcf32w=(LPCHOOSEFONTW)GetWindowLongA(hDlg, DWL_USER);
1266    if (!lpcf32w)
1267      return FALSE;
1268    if (CFn_HookCallChk32((LPCHOOSEFONTA)lpcf32w))
1269      res=CallWindowProcW((WNDPROC)lpcf32w->lpfnHook, hDlg, uMsg, wParam, lParam);
1270    if (res)
1271      return res;
1272   }
1273   else
1274   {
1275     lpcf32w=(LPCHOOSEFONTW)lParam;
1276     lpcf32a=(LPCHOOSEFONTA)lpcf32w->lpTemplateName;
1277     if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcf32a))
1278     {
1279       TRACE("CFn_WMInitDialog returned FALSE\n");
1280       return FALSE;
1281     }
1282     if (CFn_HookCallChk32((LPCHOOSEFONTA)lpcf32w))
1283       return CallWindowProcW((WNDPROC)lpcf32w->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1284   }
1285   lpcf32a=(LPCHOOSEFONTA)lpcf32w->lpTemplateName;
1286   switch (uMsg)
1287     {
1288       case WM_MEASUREITEM:
1289                         return CFn_WMMeasureItem(hDlg, wParam, lParam);
1290       case WM_DRAWITEM:
1291                         return CFn_WMDrawItem(hDlg, wParam, lParam);
1292       case WM_CTLCOLORSTATIC:
1293                         return CFn_WMCtlColorStatic(hDlg, wParam, lParam, lpcf32a);
1294       case WM_COMMAND:
1295                         return CFn_WMCommand(hDlg, wParam, lParam, lpcf32a);
1296       case WM_DESTROY:
1297                         return CFn_WMDestroy(hDlg, wParam, lParam);
1298       case WM_CHOOSEFONT_GETLOGFONT:
1299                          TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n",
1300                                       lParam);
1301                          FIXME("current logfont back to caller\n");
1302                         break;
1303     }
1304   return res;
1305 }