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