ANSI C fixes.
[wine] / dlls / commdlg / fontdlg.c
1 /*
2  * COMMDLG - Font Dialog
3  *
4  * Copyright 1994 Martin Ayotte
5  * Copyright 1996 Albrecht Kleine
6  */
7
8 #include <ctype.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "winbase.h"
12 #include "wine/winbase16.h"
13 #include "wine/winuser16.h"
14 #include "ldt.h"
15 #include "heap.h"
16 #include "commdlg.h"
17 #include "resource.h"
18 #include "dialog.h"
19 #include "dlgs.h"
20 #include "module.h"
21 #include "debugtools.h"
22 #include "font.h"
23 #include "winproc.h"
24 #include "cderr.h"
25
26 DEFAULT_DEBUG_CHANNEL(commdlg)
27
28 #include "cdlg.h"
29
30 static HBITMAP16 hBitmapTT = 0; 
31
32
33
34
35 static void CFn_CHOOSEFONT16to32A(LPCHOOSEFONT16 chf16, LPCHOOSEFONTA chf32a)
36 {
37   chf32a->lStructSize=sizeof(CHOOSEFONTA);
38   chf32a->hwndOwner=chf16->hwndOwner;
39   chf32a->hDC=chf16->hDC;
40   chf32a->iPointSize=chf16->iPointSize;
41   chf32a->Flags=chf16->Flags;
42   chf32a->rgbColors=chf16->rgbColors;
43   chf32a->lCustData=chf16->lCustData;
44   chf32a->lpfnHook=NULL;
45   chf32a->lpTemplateName=PTR_SEG_TO_LIN(chf16->lpTemplateName);
46   chf32a->hInstance=chf16->hInstance;
47   chf32a->lpszStyle=PTR_SEG_TO_LIN(chf16->lpszStyle);
48   chf32a->nFontType=chf16->nFontType;
49   chf32a->nSizeMax=chf16->nSizeMax;
50   chf32a->nSizeMin=chf16->nSizeMin;
51   FONT_LogFont16To32A(PTR_SEG_TO_LIN(chf16->lpLogFont), chf32a->lpLogFont);
52 }
53
54
55 /***********************************************************************
56  *                        ChooseFont16   (COMMDLG.15)     
57  */
58 BOOL16 WINAPI ChooseFont16(LPCHOOSEFONT16 lpChFont)
59 {
60     HINSTANCE16 hInst;
61     HANDLE16 hDlgTmpl = 0;
62     BOOL16 bRet = FALSE, win32Format = FALSE;
63     LPCVOID template;
64     HWND hwndDialog;
65     CHOOSEFONTA cf32a;
66     LOGFONTA lf32a;
67     SEGPTR lpTemplateName;
68     
69     cf32a.lpLogFont=&lf32a;
70     CFn_CHOOSEFONT16to32A(lpChFont, &cf32a);
71
72     TRACE("ChooseFont\n");
73     if (!lpChFont) return FALSE;    
74
75     if (lpChFont->Flags & CF_ENABLETEMPLATEHANDLE)
76     {
77         if (!(template = LockResource16( lpChFont->hInstance )))
78         {
79             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
80             return FALSE;
81         }
82     }
83     else if (lpChFont->Flags & CF_ENABLETEMPLATE)
84     {
85         HANDLE16 hResInfo;
86         if (!(hResInfo = FindResource16( lpChFont->hInstance,
87                                          lpChFont->lpTemplateName,
88                                          RT_DIALOG16)))
89         {
90             COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
91             return FALSE;
92         }
93         if (!(hDlgTmpl = LoadResource16( lpChFont->hInstance, hResInfo )) ||
94             !(template = LockResource16( hDlgTmpl )))
95         {
96             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
97             return FALSE;
98         }
99     }
100     else
101     {
102         HANDLE hResInfo;
103         if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "CHOOSE_FONT", RT_DIALOGA)))
104         {
105             COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
106             return FALSE;
107         }
108         if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
109             !(template = LockResource( hDlgTmpl )))
110         {
111             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
112             return FALSE;
113         }
114         win32Format = TRUE;
115     }
116
117     hInst = GetWindowLongA( lpChFont->hwndOwner, GWL_HINSTANCE );
118     
119     /* lpTemplateName is not used in the dialog */
120     lpTemplateName=lpChFont->lpTemplateName;
121     lpChFont->lpTemplateName=(SEGPTR)&cf32a;
122     
123     hwndDialog = DIALOG_CreateIndirect( hInst, template, win32Format,
124                                         lpChFont->hwndOwner,
125                       (DLGPROC16)MODULE_GetWndProcEntry16("FormatCharDlgProc"),
126                                         (DWORD)lpChFont, WIN_PROC_16 );
127     if (hwndDialog) bRet = DIALOG_DoDialogBox(hwndDialog, lpChFont->hwndOwner);
128     if (hDlgTmpl) FreeResource16( hDlgTmpl );
129     lpChFont->lpTemplateName=lpTemplateName;
130     FONT_LogFont32ATo16(cf32a.lpLogFont, 
131         (LPLOGFONT16)(PTR_SEG_TO_LIN(lpChFont->lpLogFont)));
132     return bRet;
133 }
134
135
136 /***********************************************************************
137  *           ChooseFont32A   (COMDLG32.3)
138  */
139 BOOL WINAPI ChooseFontA(LPCHOOSEFONTA lpChFont)
140 {
141   BOOL bRet=FALSE;
142   HWND hwndDialog;
143   HINSTANCE hInst=GetWindowLongA( lpChFont->hwndOwner, GWL_HINSTANCE );
144   LPCVOID template;
145   HANDLE hResInfo, hDlgTmpl;
146
147   if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "CHOOSE_FONT", RT_DIALOGA)))
148   {
149     COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
150     return FALSE;
151   }
152   if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
153       !(template = LockResource( hDlgTmpl )))
154   {
155     COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
156     return FALSE;
157   }
158
159   if (lpChFont->Flags & (CF_SELECTSCRIPT | CF_NOVERTFONTS | CF_ENABLETEMPLATE |
160     CF_ENABLETEMPLATEHANDLE)) FIXME(": unimplemented flag (ignored)\n");
161   hwndDialog = DIALOG_CreateIndirect(hInst, template, TRUE, lpChFont->hwndOwner,
162             (DLGPROC16)FormatCharDlgProcA, (LPARAM)lpChFont, WIN_PROC_32A );
163   if (hwndDialog) bRet = DIALOG_DoDialogBox(hwndDialog, lpChFont->hwndOwner);  
164   return bRet;
165 }
166
167 /***********************************************************************
168  *           ChooseFont32W   (COMDLG32.4)
169  */
170 BOOL WINAPI ChooseFontW(LPCHOOSEFONTW lpChFont)
171 {
172   BOOL bRet=FALSE;
173   HWND hwndDialog;
174   HINSTANCE hInst=GetWindowLongA( lpChFont->hwndOwner, GWL_HINSTANCE );
175   CHOOSEFONTA cf32a;
176   LOGFONTA lf32a;
177   LPCVOID template;
178   HANDLE hResInfo, hDlgTmpl;
179
180   if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "CHOOSE_FONT", RT_DIALOGA)))
181   {
182     COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
183     return FALSE;
184   }
185   if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
186       !(template = LockResource( hDlgTmpl )))
187   {
188     COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
189     return FALSE;
190   }
191
192   if (lpChFont->Flags & (CF_SELECTSCRIPT | CF_NOVERTFONTS | CF_ENABLETEMPLATE |
193     CF_ENABLETEMPLATEHANDLE)) FIXME(": unimplemented flag (ignored)\n");
194   memcpy(&cf32a, lpChFont, sizeof(cf32a));
195   memcpy(&lf32a, lpChFont->lpLogFont, sizeof(LOGFONTA));
196   lstrcpynWtoA(lf32a.lfFaceName, lpChFont->lpLogFont->lfFaceName, LF_FACESIZE);
197   cf32a.lpLogFont=&lf32a;
198   cf32a.lpszStyle=HEAP_strdupWtoA(GetProcessHeap(), 0, lpChFont->lpszStyle);
199   lpChFont->lpTemplateName=(LPWSTR)&cf32a;
200   hwndDialog=DIALOG_CreateIndirect(hInst, template, TRUE, lpChFont->hwndOwner,
201             (DLGPROC16)FormatCharDlgProcW, (LPARAM)lpChFont, WIN_PROC_32W );
202   if (hwndDialog)bRet=DIALOG_DoDialogBox(hwndDialog, lpChFont->hwndOwner);  
203   HeapFree(GetProcessHeap(), 0, cf32a.lpszStyle);
204   lpChFont->lpTemplateName=(LPWSTR)cf32a.lpTemplateName;
205   memcpy(lpChFont->lpLogFont, &lf32a, sizeof(CHOOSEFONTA));
206   lstrcpynAtoW(lpChFont->lpLogFont->lfFaceName, lf32a.lfFaceName, LF_FACESIZE);
207   return bRet;
208 }
209
210
211 #define TEXT_EXTRAS 4
212 #define TEXT_COLORS 16
213
214 static const COLORREF textcolors[TEXT_COLORS]=
215 {
216  0x00000000L,0x00000080L,0x00008000L,0x00008080L,
217  0x00800000L,0x00800080L,0x00808000L,0x00808080L,
218  0x00c0c0c0L,0x000000ffL,0x0000ff00L,0x0000ffffL,
219  0x00ff0000L,0x00ff00ffL,0x00ffff00L,0x00FFFFFFL
220 };
221
222 /***********************************************************************
223  *                          CFn_HookCallChk                 [internal]
224  */
225 static BOOL CFn_HookCallChk(LPCHOOSEFONT16 lpcf)
226 {
227  if (lpcf)
228   if(lpcf->Flags & CF_ENABLEHOOK)
229    if (lpcf->lpfnHook)
230     return TRUE;
231  return FALSE;
232 }
233
234 /***********************************************************************
235  *                          CFn_HookCallChk32                 [internal]
236  */
237 static BOOL CFn_HookCallChk32(LPCHOOSEFONTA lpcf)
238 {
239  if (lpcf)
240   if(lpcf->Flags & CF_ENABLEHOOK)
241    if (lpcf->lpfnHook)
242     return TRUE;
243  return FALSE;
244 }
245
246
247 /*************************************************************************
248  *              AddFontFamily                               [internal]
249  */
250 static INT AddFontFamily(LPLOGFONTA lplf, UINT nFontType, 
251                            LPCHOOSEFONTA lpcf, HWND hwnd)
252 {
253   int i;
254   WORD w;
255
256   TRACE("font=%s (nFontType=%d)\n", lplf->lfFaceName,nFontType);
257
258   if (lpcf->Flags & CF_FIXEDPITCHONLY)
259    if (!(lplf->lfPitchAndFamily & FIXED_PITCH))
260      return 1;
261   if (lpcf->Flags & CF_ANSIONLY)
262    if (lplf->lfCharSet != ANSI_CHARSET)
263      return 1;
264   if (lpcf->Flags & CF_TTONLY)
265    if (!(nFontType & TRUETYPE_FONTTYPE))
266      return 1;   
267
268   i=SendMessageA(hwnd, CB_ADDSTRING, 0, (LPARAM)lplf->lfFaceName);
269   if (i!=CB_ERR)
270   {
271     w=(lplf->lfCharSet << 8) | lplf->lfPitchAndFamily;
272     SendMessageA(hwnd, CB_SETITEMDATA, i, MAKELONG(nFontType,w));
273     return 1 ;        /* store some important font information */
274   }
275   else
276     return 0;
277 }
278
279 typedef struct
280 {
281   HWND hWnd1;
282   HWND hWnd2;
283   LPCHOOSEFONTA lpcf32a;
284 } CFn_ENUMSTRUCT, *LPCFn_ENUMSTRUCT;
285
286 /*************************************************************************
287  *              FontFamilyEnumProc32                           [internal]
288  */
289 static INT WINAPI FontFamilyEnumProc(LPENUMLOGFONTA lpEnumLogFont, 
290           LPNEWTEXTMETRICA metrics, UINT nFontType, LPARAM lParam)
291 {
292   LPCFn_ENUMSTRUCT e;
293   e=(LPCFn_ENUMSTRUCT)lParam;
294   return AddFontFamily(&lpEnumLogFont->elfLogFont, nFontType, e->lpcf32a, e->hWnd1);
295 }
296
297 /***********************************************************************
298  *                FontFamilyEnumProc16                     (COMMDLG.19)
299  */
300 INT16 WINAPI FontFamilyEnumProc16( SEGPTR logfont, SEGPTR metrics,
301                                    UINT16 nFontType, LPARAM lParam )
302 {
303   HWND16 hwnd=LOWORD(lParam);
304   HWND16 hDlg=GetParent16(hwnd);
305   LPCHOOSEFONT16 lpcf=(LPCHOOSEFONT16)GetWindowLongA(hDlg, DWL_USER); 
306   LOGFONT16 *lplf = (LOGFONT16 *)PTR_SEG_TO_LIN( logfont );
307   LOGFONTA lf32a;
308   FONT_LogFont16To32A(lplf, &lf32a);
309   return AddFontFamily(&lf32a, nFontType, (LPCHOOSEFONTA)lpcf->lpTemplateName,
310                        hwnd);
311 }
312
313 /*************************************************************************
314  *              SetFontStylesToCombo2                           [internal]
315  *
316  * Fill font style information into combobox  (without using font.c directly)
317  */
318 static int SetFontStylesToCombo2(HWND hwnd, HDC hdc, LPLOGFONTA lplf)
319 {
320    #define FSTYLES 4
321    struct FONTSTYLE
322           { int italic; 
323             int weight;
324             char stname[20]; };
325    static struct FONTSTYLE fontstyles[FSTYLES]={ 
326           { 0,FW_NORMAL,"Regular"},{0,FW_BOLD,"Bold"},
327           { 1,FW_NORMAL,"Italic"}, {1,FW_BOLD,"Bold Italic"}};
328    HFONT16 hf;
329    TEXTMETRIC16 tm;
330    int i,j;
331
332    for (i=0;i<FSTYLES;i++)
333    {
334      lplf->lfItalic=fontstyles[i].italic;
335      lplf->lfWeight=fontstyles[i].weight;
336      hf=CreateFontIndirectA(lplf);
337      hf=SelectObject(hdc,hf);
338      GetTextMetrics16(hdc,&tm);
339      hf=SelectObject(hdc,hf);
340      DeleteObject(hf);
341
342      if (tm.tmWeight==fontstyles[i].weight &&
343          tm.tmItalic==fontstyles[i].italic)    /* font successful created ? */
344      {
345        char *str = SEGPTR_STRDUP(fontstyles[i].stname);
346        j=SendMessage16(hwnd,CB_ADDSTRING16,0,(LPARAM)SEGPTR_GET(str) );
347        SEGPTR_FREE(str);
348        if (j==CB_ERR) return 1;
349        j=SendMessage16(hwnd, CB_SETITEMDATA16, j, 
350                                  MAKELONG(fontstyles[i].weight,fontstyles[i].italic));
351        if (j==CB_ERR) return 1;                                 
352      }
353    }  
354   return 0;
355 }
356
357 /*************************************************************************
358  *              AddFontSizeToCombo3                           [internal]
359  */
360 static int AddFontSizeToCombo3(HWND hwnd, UINT h, LPCHOOSEFONTA lpcf)
361 {
362     int j;
363     char buffer[20];
364
365     if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
366         ((lpcf->Flags & CF_LIMITSIZE) && (h >= lpcf->nSizeMin) && (h <= lpcf->nSizeMax)))
367     {
368         sprintf(buffer, "%2d", h);
369         j=SendMessageA(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)buffer);
370         if (j==CB_ERR)
371         {
372             j=SendMessageA(hwnd, CB_ADDSTRING, 0, (LPARAM)buffer);      
373             if (j!=CB_ERR) j = SendMessageA(hwnd, CB_SETITEMDATA, j, h); 
374             if (j==CB_ERR) return 1;
375         }
376     }
377     return 0;
378
379  
380 /*************************************************************************
381  *              SetFontSizesToCombo3                           [internal]
382  */
383 static int SetFontSizesToCombo3(HWND hwnd, LPCHOOSEFONTA lpcf)
384 {
385   static const int sizes[]={8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72,0};
386   int i;
387
388   for (i=0; sizes[i]; i++)
389     if (AddFontSizeToCombo3(hwnd, sizes[i], lpcf)) return 1;
390   return 0;
391 }
392
393 /***********************************************************************
394  *                 AddFontStyle                          [internal]
395  */
396 static INT AddFontStyle(LPLOGFONTA lplf, UINT nFontType, 
397     LPCHOOSEFONTA lpcf, HWND hcmb2, HWND hcmb3, HWND hDlg)
398 {
399   int i;
400   
401   TRACE("(nFontType=%d)\n",nFontType);
402   TRACE("  %s h=%ld w=%ld e=%ld o=%ld wg=%ld i=%d u=%d s=%d"
403                " ch=%d op=%d cp=%d q=%d pf=%xh\n",
404                lplf->lfFaceName,lplf->lfHeight,lplf->lfWidth,
405                lplf->lfEscapement,lplf->lfOrientation,
406                lplf->lfWeight,lplf->lfItalic,lplf->lfUnderline,
407                lplf->lfStrikeOut,lplf->lfCharSet, lplf->lfOutPrecision,
408                lplf->lfClipPrecision,lplf->lfQuality, lplf->lfPitchAndFamily);
409   if (nFontType & RASTER_FONTTYPE)
410   {
411     if (AddFontSizeToCombo3(hcmb3, lplf->lfHeight, lpcf)) return 0;
412   } else if (SetFontSizesToCombo3(hcmb3, lpcf)) return 0;
413
414   if (!SendMessageA(hcmb2, CB_GETCOUNT, 0, 0))
415   {
416        HDC hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
417        i=SetFontStylesToCombo2(hcmb2,hdc,lplf);
418        if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
419          ReleaseDC(hDlg,hdc);
420        if (i)
421         return 0;
422   }
423   return 1 ;
424
425 }    
426
427 /***********************************************************************
428  *                 FontStyleEnumProc16                     (COMMDLG.18)
429  */
430 INT16 WINAPI FontStyleEnumProc16( SEGPTR logfont, SEGPTR metrics,
431                                   UINT16 nFontType, LPARAM lParam )
432 {
433   HWND16 hcmb2=LOWORD(lParam);
434   HWND16 hcmb3=HIWORD(lParam);
435   HWND16 hDlg=GetParent16(hcmb3);
436   LPCHOOSEFONT16 lpcf=(LPCHOOSEFONT16)GetWindowLongA(hDlg, DWL_USER); 
437   LOGFONT16 *lplf = (LOGFONT16 *)PTR_SEG_TO_LIN(logfont);
438   LOGFONTA lf32a;
439   FONT_LogFont16To32A(lplf, &lf32a);
440   return AddFontStyle(&lf32a, nFontType, (LPCHOOSEFONTA)lpcf->lpTemplateName,
441                       hcmb2, hcmb3, hDlg);
442 }
443
444 /***********************************************************************
445  *                 FontStyleEnumProc32                     [internal]
446  */
447 static INT WINAPI FontStyleEnumProc( LPENUMLOGFONTA lpFont, 
448           LPNEWTEXTMETRICA metrics, UINT nFontType, LPARAM lParam )
449 {
450   LPCFn_ENUMSTRUCT s=(LPCFn_ENUMSTRUCT)lParam;
451   HWND hcmb2=s->hWnd1;
452   HWND hcmb3=s->hWnd2;
453   HWND hDlg=GetParent(hcmb3);
454   return AddFontStyle(&lpFont->elfLogFont, nFontType, s->lpcf32a, hcmb2,
455                       hcmb3, hDlg);
456 }
457
458 /***********************************************************************
459  *           CFn_WMInitDialog                            [internal]
460  */
461 static LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam,
462                          LPCHOOSEFONTA lpcf)
463 {
464   HDC hdc;
465   int i,j,res,init=0;
466   long l;
467   LPLOGFONTA lpxx;
468   HCURSOR hcursor=SetCursor(LoadCursorA(0,IDC_WAITA));
469
470   SetWindowLongA(hDlg, DWL_USER, lParam); 
471   lpxx=lpcf->lpLogFont;
472   TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
473
474   if (lpcf->lStructSize != sizeof(CHOOSEFONTA))
475   {
476     ERR("structure size failure !!!\n");
477     EndDialog (hDlg, 0); 
478     return FALSE;
479   }
480   if (!hBitmapTT)
481     hBitmapTT = LoadBitmapA(0, MAKEINTRESOURCEA(OBM_TRTYPE));
482
483   /* This font will be deleted by WM_COMMAND */
484   SendDlgItemMessageA(hDlg,stc6,WM_SETFONT,
485      CreateFontA(0, 0, 1, 1, 400, 0, 0, 0, 0, 0, 0, 0, 0, NULL),FALSE);
486                          
487   if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow(lpcf->hwndOwner))
488     ShowWindow(GetDlgItem(hDlg,pshHelp),SW_HIDE);
489   if (!(lpcf->Flags & CF_APPLY))
490     ShowWindow(GetDlgItem(hDlg,psh3),SW_HIDE);
491   if (lpcf->Flags & CF_EFFECTS)
492   {
493     for (res=1,i=0;res && i<TEXT_COLORS;i++)
494     {
495       /* FIXME: load color name from resource:  res=LoadString(...,i+....,buffer,.....); */
496       char name[20];
497       strcpy( name, "[color name]" );
498       j=SendDlgItemMessageA(hDlg, cmb4, CB_ADDSTRING, 0, (LPARAM)name);
499       SendDlgItemMessageA(hDlg, cmb4, CB_SETITEMDATA16, j, textcolors[j]);
500       /* look for a fitting value in color combobox */
501       if (textcolors[j]==lpcf->rgbColors)
502         SendDlgItemMessageA(hDlg,cmb4, CB_SETCURSEL,j,0);
503     }
504   }
505   else
506   {
507     ShowWindow(GetDlgItem(hDlg,cmb4),SW_HIDE);
508     ShowWindow(GetDlgItem(hDlg,chx1),SW_HIDE);
509     ShowWindow(GetDlgItem(hDlg,chx2),SW_HIDE);
510     ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
511     ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
512   }
513   hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
514   if (hdc)
515   {
516     CFn_ENUMSTRUCT s;
517     s.hWnd1=GetDlgItem(hDlg,cmb1);
518     s.lpcf32a=lpcf;
519     if (!EnumFontFamiliesA(hdc, NULL, FontFamilyEnumProc, (LPARAM)&s))
520       TRACE("EnumFontFamilies returns 0\n");
521     if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
522     {
523       /* look for fitting font name in combobox1 */
524       j=SendDlgItemMessageA(hDlg,cmb1,CB_FINDSTRING,-1,(LONG)lpxx->lfFaceName);
525       if (j!=CB_ERR)
526       {
527         SendDlgItemMessageA(hDlg, cmb1, CB_SETCURSEL, j, 0);
528         SendMessageA(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
529                        GetDlgItem(hDlg,cmb1));
530         init=1;
531         /* look for fitting font style in combobox2 */
532         l=MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD:FW_NORMAL,lpxx->lfItalic !=0);
533         for (i=0;i<TEXT_EXTRAS;i++)
534         {
535           if (l==SendDlgItemMessageA(hDlg, cmb2, CB_GETITEMDATA, i, 0))
536             SendDlgItemMessageA(hDlg, cmb2, CB_SETCURSEL, i, 0);
537         }
538       
539         /* look for fitting font size in combobox3 */
540         j=SendDlgItemMessageA(hDlg, cmb3, CB_GETCOUNT, 0, 0);
541         for (i=0;i<j;i++)
542         {
543           if (lpxx->lfHeight==(int)SendDlgItemMessageA(hDlg,cmb3, CB_GETITEMDATA,i,0))
544             SendDlgItemMessageA(hDlg,cmb3,CB_SETCURSEL,i,0);
545         }
546       }
547     }
548     if (!init)
549     {
550       SendDlgItemMessageA(hDlg,cmb1,CB_SETCURSEL,0,0);
551       SendMessageA(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
552                        GetDlgItem(hDlg,cmb1));
553     }    
554     if (lpcf->Flags & CF_USESTYLE && lpcf->lpszStyle)
555     {
556       j=SendDlgItemMessageA(hDlg,cmb2,CB_FINDSTRING,-1,(LONG)lpcf->lpszStyle);
557       if (j!=CB_ERR)
558       {
559         j=SendDlgItemMessageA(hDlg,cmb2,CB_SETCURSEL,j,0);
560         SendMessageA(hDlg,WM_COMMAND,cmb2,
561                        MAKELONG(GetDlgItem(hDlg,cmb2),CBN_SELCHANGE));
562       }
563     }
564   }
565   else
566   {
567     WARN("HDC failure !!!\n");
568     EndDialog (hDlg, 0); 
569     return FALSE;
570   }
571
572   if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
573     ReleaseDC(hDlg,hdc);
574   SetCursor(hcursor);   
575   return TRUE;
576 }
577
578
579 /***********************************************************************
580  *           CFn_WMMeasureItem                           [internal]
581  */
582 static LRESULT CFn_WMMeasureItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
583 {
584   BITMAP bm;
585   LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam;
586   if (!hBitmapTT)
587     hBitmapTT = LoadBitmapA(0, MAKEINTRESOURCEA(OBM_TRTYPE));
588   GetObjectA( hBitmapTT, sizeof(bm), &bm );
589   lpmi->itemHeight=bm.bmHeight;
590   /* FIXME: use MAX of bm.bmHeight and tm.tmHeight .*/
591   return 0;
592 }
593
594
595 /***********************************************************************
596  *           CFn_WMDrawItem                              [internal]
597  */
598 static LRESULT CFn_WMDrawItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
599 {
600   HBRUSH hBrush;
601   char buffer[40];
602   BITMAP bm;
603   COLORREF cr, oldText=0, oldBk=0;
604   RECT rect;
605 #if 0  
606   HDC hMemDC;
607   int nFontType;
608   HBITMAP hBitmap; /* for later TT usage */
609 #endif  
610   LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam;
611
612   if (lpdi->itemID == 0xFFFF)                   /* got no items */
613     DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
614   else
615   {
616    if (lpdi->CtlType == ODT_COMBOBOX)
617    {
618      if (lpdi->itemState ==ODS_SELECTED)
619      {
620        hBrush=GetSysColorBrush(COLOR_HIGHLIGHT);
621        oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
622        oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT));
623      }  else
624      {
625        hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
626        SelectObject(lpdi->hDC, hBrush);
627      }
628      FillRect(lpdi->hDC, &lpdi->rcItem, hBrush);
629    }
630    else
631      return TRUE;       /* this should never happen */
632
633    rect=lpdi->rcItem;
634    switch (lpdi->CtlID)
635    {
636     case cmb1:  /* TRACE(commdlg,"WM_Drawitem cmb1\n"); */
637                 SendMessageA(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
638                                (LPARAM)buffer);           
639                 GetObjectA( hBitmapTT, sizeof(bm), &bm );
640                 TextOutA(lpdi->hDC, lpdi->rcItem.left + bm.bmWidth + 10,
641                            lpdi->rcItem.top, buffer, lstrlenA(buffer));
642 #if 0
643                 nFontType = SendMessageA(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
644                   /* FIXME: draw bitmap if truetype usage */
645                 if (nFontType&TRUETYPE_FONTTYPE)
646                 {
647                   hMemDC = CreateCompatibleDC(lpdi->hDC);
648                   hBitmap = SelectObject(hMemDC, hBitmapTT);
649                   BitBlt(lpdi->hDC, lpdi->rcItem.left, lpdi->rcItem.top,
650                            bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
651                   SelectObject(hMemDC, hBitmap);
652                   DeleteDC(hMemDC);
653                 }
654 #endif
655                 break;
656     case cmb2:
657     case cmb3:  /* TRACE(commdlg,"WM_DRAWITEN cmb2,cmb3\n"); */
658                 SendMessageA(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
659                                (LPARAM)buffer);
660                 TextOutA(lpdi->hDC, lpdi->rcItem.left,
661                            lpdi->rcItem.top, buffer, lstrlenA(buffer));
662                 break;
663
664     case cmb4:  /* TRACE(commdlg,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
665                 SendMessageA(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
666                                (LPARAM)buffer);
667                 TextOutA(lpdi->hDC, lpdi->rcItem.left +  25+5,
668                            lpdi->rcItem.top, buffer, lstrlenA(buffer));
669                 cr = SendMessageA(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
670                 hBrush = CreateSolidBrush(cr);
671                 if (hBrush)
672                 {
673                   hBrush = SelectObject (lpdi->hDC, hBrush) ;
674                   rect.right=rect.left+25;
675                   rect.top++;
676                   rect.left+=5;
677                   rect.bottom--;
678                   Rectangle( lpdi->hDC, rect.left, rect.top,
679                                rect.right, rect.bottom );
680                   DeleteObject( SelectObject (lpdi->hDC, hBrush)) ;
681                 }
682                 rect=lpdi->rcItem;
683                 rect.left+=25+5;
684                 break;
685
686     default:    return TRUE;    /* this should never happen */
687    }
688    if (lpdi->itemState == ODS_SELECTED)
689    {
690      SetTextColor(lpdi->hDC, oldText);
691      SetBkColor(lpdi->hDC, oldBk);
692    }
693  }
694  return TRUE;
695 }
696
697 /***********************************************************************
698  *           CFn_WMCtlColor                              [internal]
699  */
700 static LRESULT CFn_WMCtlColorStatic(HWND hDlg, WPARAM wParam, LPARAM lParam,
701                              LPCHOOSEFONTA lpcf)
702 {
703   if (lpcf->Flags & CF_EFFECTS)
704    if (GetDlgCtrlID(lParam)==stc6)
705    {
706      SetTextColor((HDC)wParam, lpcf->rgbColors);
707      return GetStockObject(WHITE_BRUSH);
708    }
709   return 0;
710 }
711
712 /***********************************************************************
713  *           CFn_WMCommand                               [internal]
714  */
715 static LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam,
716                       LPCHOOSEFONTA lpcf)
717 {
718   HFONT hFont;
719   int i,j;
720   long l;
721   HDC hdc;
722   LPLOGFONTA lpxx=lpcf->lpLogFont;
723   
724   TRACE("WM_COMMAND wParam=%08lX lParam=%08lX\n", (LONG)wParam, lParam);
725   switch (LOWORD(wParam))
726   {
727         case cmb1:if (HIWORD(wParam)==CBN_SELCHANGE)
728                   {
729                     hdc=(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
730                     if (hdc)
731                     {
732                       SendDlgItemMessageA(hDlg, cmb2, CB_RESETCONTENT16, 0, 0); 
733                       SendDlgItemMessageA(hDlg, cmb3, CB_RESETCONTENT16, 0, 0);
734                       i=SendDlgItemMessageA(hDlg, cmb1, CB_GETCURSEL16, 0, 0);
735                       if (i!=CB_ERR)
736                       {
737                         HCURSOR hcursor=SetCursor(LoadCursorA(0,IDC_WAITA));
738                         CFn_ENUMSTRUCT s;
739                         char str[256];
740                         SendDlgItemMessageA(hDlg, cmb1, CB_GETLBTEXT, i,
741                                               (LPARAM)str);
742                         TRACE("WM_COMMAND/cmb1 =>%s\n",str);
743                         s.hWnd1=GetDlgItem(hDlg, cmb2);
744                         s.hWnd2=GetDlgItem(hDlg, cmb3);
745                         s.lpcf32a=lpcf;
746                         EnumFontFamiliesA(hdc, str, FontStyleEnumProc, (LPARAM)&s);
747                         SetCursor(hcursor);
748                       }
749                       if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
750                         ReleaseDC(hDlg,hdc);
751                     }
752                     else
753                     {
754                       WARN("HDC failure !!!\n");
755                       EndDialog (hDlg, 0); 
756                       return TRUE;
757                     }
758                   }
759         case chx1:
760         case chx2:
761         case cmb2:
762         case cmb3:if (HIWORD(wParam)==CBN_SELCHANGE || HIWORD(wParam)== BN_CLICKED )
763                   {
764                     char str[256];
765                     TRACE("WM_COMMAND/cmb2,3 =%08lX\n", lParam);
766                     i=SendDlgItemMessageA(hDlg,cmb1,CB_GETCURSEL,0,0);
767                     if (i==CB_ERR)
768                       i=GetDlgItemTextA( hDlg, cmb1, str, 256 );
769                     else
770                     {
771                       SendDlgItemMessageA(hDlg,cmb1,CB_GETLBTEXT,i,
772                                             (LPARAM)str);
773                       l=SendDlgItemMessageA(hDlg,cmb1,CB_GETITEMDATA,i,0);
774                       j=HIWORD(l);
775                       lpcf->nFontType = LOWORD(l);
776                       /* FIXME:   lpcf->nFontType |= ....  SIMULATED_FONTTYPE and so */
777                       /* same value reported to the EnumFonts
778                        call back with the extra FONTTYPE_...  bits added */
779                       lpxx->lfPitchAndFamily=j&0xff;
780                       lpxx->lfCharSet=j>>8;
781                     }
782                     strcpy(lpxx->lfFaceName,str);
783                     i=SendDlgItemMessageA(hDlg, cmb2, CB_GETCURSEL, 0, 0);
784                     if (i!=CB_ERR)
785                     {
786                       l=SendDlgItemMessageA(hDlg, cmb2, CB_GETITEMDATA, i, 0);
787                       if (0!=(lpxx->lfItalic=HIWORD(l)))
788                         lpcf->nFontType |= ITALIC_FONTTYPE;
789                       if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
790                         lpcf->nFontType |= BOLD_FONTTYPE;
791                     }
792                     i=SendDlgItemMessageA(hDlg, cmb3, CB_GETCURSEL, 0, 0);
793                     if (i!=CB_ERR)
794                       lpxx->lfHeight=-LOWORD(SendDlgItemMessageA(hDlg, cmb3, CB_GETITEMDATA, i, 0));
795                     else
796                       lpxx->lfHeight=0;
797                     lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
798                     lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
799                     lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
800                     lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
801                     lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
802                     lpxx->lfQuality=DEFAULT_QUALITY;
803                     lpcf->iPointSize= -10*lpxx->lfHeight;
804
805                     hFont=CreateFontIndirectA(lpxx);
806                     if (hFont)
807                     {
808                       HFONT oldFont=SendDlgItemMessageA(hDlg, stc6, 
809                           WM_GETFONT, 0, 0);
810                       SendDlgItemMessageA(hDlg,stc6,WM_SETFONT,hFont,TRUE);
811                       DeleteObject(oldFont);
812                     }
813                   }
814                   break;
815
816         case cmb4:i=SendDlgItemMessageA(hDlg, cmb4, CB_GETCURSEL, 0, 0);
817                   if (i!=CB_ERR)
818                   {
819                    lpcf->rgbColors=textcolors[i];
820                    InvalidateRect( GetDlgItem(hDlg,stc6), NULL, 0 );
821                   }
822                   break;
823         
824         case psh15:i=RegisterWindowMessageA( HELPMSGSTRING );
825                   if (lpcf->hwndOwner)
826                     SendMessageA(lpcf->hwndOwner, i, 0, (LPARAM)GetWindowLongA(hDlg, DWL_USER));
827 /*                if (CFn_HookCallChk(lpcf))
828                     CallWindowProc16(lpcf->lpfnHook,hDlg,WM_COMMAND,psh15,(LPARAM)lpcf);*/
829                   break;
830
831         case IDOK:if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
832                      ( (lpcf->Flags & CF_LIMITSIZE) && 
833                       (-lpxx->lfHeight >= lpcf->nSizeMin) && 
834                       (-lpxx->lfHeight <= lpcf->nSizeMax)))
835                      EndDialog(hDlg, TRUE);
836                   else
837                   {
838                    char buffer[80];
839                    sprintf(buffer,"Select a font size between %d and %d points.",
840                            lpcf->nSizeMin,lpcf->nSizeMax);
841                    MessageBoxA(hDlg, buffer, NULL, MB_OK);
842                   } 
843                   return(TRUE);
844         case IDCANCEL:EndDialog(hDlg, FALSE);
845                   return(TRUE);
846         }
847       return(FALSE);
848 }
849
850 static LRESULT CFn_WMDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam)
851 {
852   DeleteObject(SendDlgItemMessageA(hwnd, stc6, WM_GETFONT, 0, 0));
853   return TRUE;
854 }
855
856
857 /***********************************************************************
858  *           FormatCharDlgProc16   (COMMDLG.16)
859              FIXME: 1. some strings are "hardcoded", but it's better load from sysres
860                     2. some CF_.. flags are not supported
861                     3. some TType extensions
862  */
863 LRESULT WINAPI FormatCharDlgProc16(HWND16 hDlg, UINT16 message, WPARAM16 wParam,
864                                    LPARAM lParam)
865 {
866   LPCHOOSEFONT16 lpcf;
867   LPCHOOSEFONTA lpcf32a;
868   UINT uMsg32;
869   WPARAM wParam32;
870   LRESULT res=0;  
871   if (message!=WM_INITDIALOG)
872   {
873    lpcf=(LPCHOOSEFONT16)GetWindowLongA(hDlg, DWL_USER);   
874    if (!lpcf)
875       return FALSE;
876    if (CFn_HookCallChk(lpcf))
877      res=CallWindowProc16((WNDPROC16)lpcf->lpfnHook,hDlg,message,wParam,lParam);
878    if (res)
879     return res;
880   }
881   else
882   {
883     lpcf=(LPCHOOSEFONT16)lParam;
884     lpcf32a=(LPCHOOSEFONTA)lpcf->lpTemplateName;
885     if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcf32a)) 
886     {
887       TRACE("CFn_WMInitDialog returned FALSE\n");
888       return FALSE;
889     }  
890     if (CFn_HookCallChk(lpcf))
891       return CallWindowProc16((WNDPROC16)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
892   }
893   WINPROC_MapMsg16To32A(message, wParam, &uMsg32, &wParam32, &lParam);
894   lpcf32a=(LPCHOOSEFONTA)lpcf->lpTemplateName;
895   switch (uMsg32)
896     {
897       case WM_MEASUREITEM:
898                         res=CFn_WMMeasureItem(hDlg, wParam32, lParam);
899                         break;
900       case WM_DRAWITEM:
901                         res=CFn_WMDrawItem(hDlg, wParam32, lParam);
902                         break;
903       case WM_CTLCOLORSTATIC:
904                         res=CFn_WMCtlColorStatic(hDlg, wParam32, lParam, lpcf32a);
905                         break;
906       case WM_COMMAND:
907                         res=CFn_WMCommand(hDlg, wParam32, lParam, lpcf32a);
908                         break;
909       case WM_DESTROY:
910                         res=CFn_WMDestroy(hDlg, wParam32, lParam);
911                         break;
912       case WM_CHOOSEFONT_GETLOGFONT: 
913                          TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n",
914                                       lParam);
915                          FIXME("current logfont back to caller\n");
916                         break;
917     }
918   WINPROC_UnmapMsg16To32A(hDlg,uMsg32, wParam32, lParam, res);    
919   return res;
920 }
921
922 /***********************************************************************
923  *           FormatCharDlgProc32A   [internal]
924  */
925 LRESULT WINAPI FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
926                                     LPARAM lParam)
927 {
928   LPCHOOSEFONTA lpcf;
929   LRESULT res=FALSE;
930   if (uMsg!=WM_INITDIALOG)
931   {
932    lpcf=(LPCHOOSEFONTA)GetWindowLongA(hDlg, DWL_USER);   
933    if (!lpcf)
934      return FALSE;
935    if (CFn_HookCallChk32(lpcf))
936      res=CallWindowProcA((WNDPROC)lpcf->lpfnHook, hDlg, uMsg, wParam, lParam);
937    if (res)
938      return res;
939   }
940   else
941   {
942     lpcf=(LPCHOOSEFONTA)lParam;
943     if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcf)) 
944     {
945       TRACE("CFn_WMInitDialog returned FALSE\n");
946       return FALSE;
947     }  
948     if (CFn_HookCallChk32(lpcf))
949       return CallWindowProcA((WNDPROC)lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
950   }
951   switch (uMsg)
952     {
953       case WM_MEASUREITEM:
954                         return CFn_WMMeasureItem(hDlg, wParam, lParam);
955       case WM_DRAWITEM:
956                         return CFn_WMDrawItem(hDlg, wParam, lParam);
957       case WM_CTLCOLORSTATIC:
958                         return CFn_WMCtlColorStatic(hDlg, wParam, lParam, lpcf);
959       case WM_COMMAND:
960                         return CFn_WMCommand(hDlg, wParam, lParam, lpcf);
961       case WM_DESTROY:
962                         return CFn_WMDestroy(hDlg, wParam, lParam);
963       case WM_CHOOSEFONT_GETLOGFONT:
964                          TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n",
965                                       lParam);
966                          FIXME("current logfont back to caller\n");
967                         break;
968     }
969   return res;
970 }
971
972 /***********************************************************************
973  *           FormatCharDlgProc32W   [internal]
974  */
975 LRESULT WINAPI FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam,
976                                     LPARAM lParam)
977 {
978   LPCHOOSEFONTW lpcf32w;
979   LPCHOOSEFONTA lpcf32a;
980   LRESULT res=FALSE;
981   if (uMsg!=WM_INITDIALOG)
982   {
983    lpcf32w=(LPCHOOSEFONTW)GetWindowLongA(hDlg, DWL_USER);   
984    if (!lpcf32w)
985      return FALSE;
986    if (CFn_HookCallChk32((LPCHOOSEFONTA)lpcf32w))
987      res=CallWindowProcW((WNDPROC)lpcf32w->lpfnHook, hDlg, uMsg, wParam, lParam);
988    if (res)
989      return res;
990   }
991   else
992   {
993     lpcf32w=(LPCHOOSEFONTW)lParam;
994     lpcf32a=(LPCHOOSEFONTA)lpcf32w->lpTemplateName;
995     if (!CFn_WMInitDialog(hDlg, wParam, lParam, lpcf32a)) 
996     {
997       TRACE("CFn_WMInitDialog returned FALSE\n");
998       return FALSE;
999     }  
1000     if (CFn_HookCallChk32((LPCHOOSEFONTA)lpcf32w))
1001       return CallWindowProcW((WNDPROC)lpcf32w->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1002   }
1003   lpcf32a=(LPCHOOSEFONTA)lpcf32w->lpTemplateName;
1004   switch (uMsg)
1005     {
1006       case WM_MEASUREITEM:
1007                         return CFn_WMMeasureItem(hDlg, wParam, lParam);
1008       case WM_DRAWITEM:
1009                         return CFn_WMDrawItem(hDlg, wParam, lParam);
1010       case WM_CTLCOLORSTATIC:
1011                         return CFn_WMCtlColorStatic(hDlg, wParam, lParam, lpcf32a);
1012       case WM_COMMAND:
1013                         return CFn_WMCommand(hDlg, wParam, lParam, lpcf32a);
1014       case WM_DESTROY:
1015                         return CFn_WMDestroy(hDlg, wParam, lParam);
1016       case WM_CHOOSEFONT_GETLOGFONT: 
1017                          TRACE("WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n",
1018                                       lParam);
1019                          FIXME("current logfont back to caller\n");
1020                         break;
1021     }
1022   return res;
1023 }
1024
1025