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