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