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