Release 960805
[wine] / misc / commdlg.c
1 /*
2  * COMMDLG functions
3  *
4  * Copyright 1994 Martin Ayotte
5  * Copyright 1996 Albrecht Kleine
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "win.h"
12 #include "user.h"
13 #include "message.h"
14 #include "commdlg.h"
15 #include "dlgs.h"
16 #include "module.h"
17 #include "resource.h"
18 #include "dos_fs.h"
19 #include "drive.h"
20 #include "stackframe.h"
21 #include "stddebug.h"
22 #include "debug.h"
23
24 static  DWORD           CommDlgLastError = 0;
25
26 static  HBITMAP         hFolder = 0;
27 static  HBITMAP         hFolder2 = 0;
28 static  HBITMAP         hFloppy = 0;
29 static  HBITMAP         hHDisk = 0;
30 static  HBITMAP         hCDRom = 0;
31 static  HBITMAP         hBitmapTT = 0;
32
33 /***********************************************************************
34  *                              FileDlg_Init                    [internal]
35  */
36 static BOOL FileDlg_Init()
37 {
38     static BOOL initialized = 0;
39     
40     if (!initialized) {
41         if (!hFolder) hFolder = LoadBitmap16(0, MAKEINTRESOURCE(OBM_FOLDER));
42         if (!hFolder2) hFolder2 = LoadBitmap16(0, MAKEINTRESOURCE(OBM_FOLDER2));
43         if (!hFloppy) hFloppy = LoadBitmap16(0, MAKEINTRESOURCE(OBM_FLOPPY));
44         if (!hHDisk) hHDisk = LoadBitmap16(0, MAKEINTRESOURCE(OBM_HDISK));
45         if (!hCDRom) hCDRom = LoadBitmap16(0, MAKEINTRESOURCE(OBM_CDROM));
46         if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 || 
47             hHDisk == 0 || hCDRom == 0)
48         {       
49             fprintf(stderr, "FileDlg_Init // Error loading bitmaps !");
50             return FALSE;
51         }
52         initialized = TRUE;
53     }
54     return TRUE;
55 }
56
57 /***********************************************************************
58  *           GetOpenFileName   (COMMDLG.1)
59  */
60 BOOL GetOpenFileName(LPOPENFILENAME lpofn)
61 {
62     HINSTANCE hInst;
63     HANDLE hDlgTmpl, hResInfo;
64     BOOL bRet;
65   
66     if (!lpofn || !FileDlg_Init()) return FALSE;
67
68     if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) hDlgTmpl = lpofn->hInstance;
69     else if (lpofn->Flags & OFN_ENABLETEMPLATE)
70     {
71         if (!(hResInfo = FindResource16(lpofn->hInstance,
72                                         lpofn->lpTemplateName, RT_DIALOG)))
73         {
74             CommDlgLastError = CDERR_FINDRESFAILURE;
75             return FALSE;
76         }
77         hDlgTmpl = LoadResource16( lpofn->hInstance, hResInfo );
78     }
79     else hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_OPEN_FILE );
80     if (!hDlgTmpl)
81     {
82         CommDlgLastError = CDERR_LOADRESFAILURE;
83         return FALSE;
84     }
85
86     hInst = WIN_GetWindowInstance( lpofn->hwndOwner );
87     bRet = DialogBoxIndirectParam16( hInst, hDlgTmpl, lpofn->hwndOwner,
88                         (DLGPROC16)MODULE_GetWndProcEntry16("FileOpenDlgProc"),
89                         (DWORD)lpofn );
90
91     if (!(lpofn->Flags & OFN_ENABLETEMPLATEHANDLE))
92     {
93         if (lpofn->Flags & OFN_ENABLETEMPLATE) FreeResource16( hDlgTmpl );
94         else SYSRES_FreeResource( hDlgTmpl );
95     }
96
97     dprintf_commdlg(stddeb,"GetOpenFileName // return lpstrFile='%s' !\n", 
98            (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
99     return bRet;
100 }
101
102
103 /***********************************************************************
104  *           GetSaveFileName   (COMMDLG.2)
105  */
106 BOOL GetSaveFileName(LPOPENFILENAME lpofn)
107 {
108     HINSTANCE hInst;
109     HANDLE hDlgTmpl, hResInfo;
110     BOOL bRet;
111   
112     if (!lpofn || !FileDlg_Init()) return FALSE;
113
114     if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) hDlgTmpl = lpofn->hInstance;
115     else if (lpofn->Flags & OFN_ENABLETEMPLATE)
116     {
117         hInst = lpofn->hInstance;
118         if (!(hResInfo = FindResource16(lpofn->hInstance,
119                                         lpofn->lpTemplateName, RT_DIALOG )))
120         {
121             CommDlgLastError = CDERR_FINDRESFAILURE;
122             return FALSE;
123         }
124         hDlgTmpl = LoadResource16( lpofn->hInstance, hResInfo );
125     }
126     else hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_SAVE_FILE );
127
128     hInst = WIN_GetWindowInstance( lpofn->hwndOwner );
129     bRet = DialogBoxIndirectParam16( hInst, hDlgTmpl, lpofn->hwndOwner,
130                         (DLGPROC16)MODULE_GetWndProcEntry16("FileSaveDlgProc"),
131                         (DWORD)lpofn); 
132     if (!(lpofn->Flags & OFN_ENABLETEMPLATEHANDLE))
133     {
134         if (lpofn->Flags & OFN_ENABLETEMPLATE) FreeResource16( hDlgTmpl );
135         else SYSRES_FreeResource( hDlgTmpl );
136     }
137
138     dprintf_commdlg(stddeb, "GetSaveFileName // return lpstrFile='%s' !\n", 
139             (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
140     return bRet;
141 }
142
143 /***********************************************************************
144  *                              FILEDLG_StripEditControl        [internal]
145  * Strip pathnames off the contents of the edit control.
146  */
147 static void FILEDLG_StripEditControl(HWND hwnd)
148 {
149     char temp[512], *cp;
150
151     GetDlgItemText32A( hwnd, edt1, temp, sizeof(temp) );
152     cp = strrchr(temp, '\\');
153     if (cp != NULL) {
154         strcpy(temp, cp+1);
155     }
156     cp = strrchr(temp, ':');
157     if (cp != NULL) {
158         strcpy(temp, cp+1);
159     }
160     /* FIXME: shouldn't we do something with the result here? ;-) */
161 }
162
163 /***********************************************************************
164  *                              FILEDLG_ScanDir                 [internal]
165  */
166 static BOOL FILEDLG_ScanDir(HWND hWnd, LPSTR newPath)
167 {
168   char str[512],str2[512];
169
170   strncpy(str,newPath,511); str[511]=0;
171   GetDlgItemText32A( hWnd, edt1, str2, sizeof(str2) );
172   strncat(str,str2,511-strlen(str)); str[511]=0;
173   if (!DlgDirList(hWnd, MAKE_SEGPTR(str), lst1, 0, 0x0000)) return FALSE;
174   strcpy( str, "*.*" );
175   DlgDirList(hWnd, MAKE_SEGPTR(str), lst2, stc1, 0x8010);
176   return TRUE;
177 }
178
179 /***********************************************************************
180  *                              FILEDLG_GetFileType             [internal]
181  */
182
183 static LPSTR FILEDLG_GetFileType(LPSTR cfptr, LPSTR fptr, WORD index)
184 {
185   int n, i;
186   i = 0;
187   if (cfptr)
188     for ( ;(n = strlen(cfptr)) != 0; i++) 
189       {
190         cfptr += n + 1;
191         if (i == index)
192           return cfptr;
193         cfptr += strlen(cfptr) + 1;
194       }
195   if (fptr)
196     for ( ;(n = strlen(fptr)) != 0; i++) 
197       {
198         fptr += n + 1;
199         if (i == index)
200           return fptr;
201         fptr += strlen(fptr) + 1;
202     }
203   return NULL;
204 }
205
206 /***********************************************************************
207  *                              FILEDLG_WMDrawItem              [internal]
208  */
209 static LONG FILEDLG_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam,int savedlg)
210 {
211     LPDRAWITEMSTRUCT16 lpdis = (LPDRAWITEMSTRUCT16)PTR_SEG_TO_LIN(lParam);
212     char str[512];
213     HBRUSH hBrush;
214     HBITMAP hBitmap, hPrevBitmap;
215     BITMAP16 bm;
216     HDC hMemDC;
217
218     str[0]=0;
219     if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1) {
220         hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
221         SelectObject(lpdis->hDC, hBrush);
222         FillRect16(lpdis->hDC, &lpdis->rcItem, hBrush);
223         SendMessage16(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, 
224                       (LPARAM)MAKE_SEGPTR(str));
225
226         if (savedlg)       /* use _gray_ text in FileSaveDlg */
227           if (!lpdis->itemState)
228             SetTextColor(lpdis->hDC,GetSysColor(COLOR_GRAYTEXT) );
229           else  
230             SetTextColor(lpdis->hDC,GetSysColor(COLOR_WINDOWTEXT) );
231             /* inversion of gray would be bad readable */                 
232
233         TextOut16(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
234                   str, strlen(str));
235         if (lpdis->itemState != 0) {
236             InvertRect16(lpdis->hDC, &lpdis->rcItem);
237         }
238         return TRUE;
239     }
240     
241     if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2) {
242         hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
243         SelectObject(lpdis->hDC, hBrush);
244         FillRect16(lpdis->hDC, &lpdis->rcItem, hBrush);
245         SendMessage16(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, 
246                       (LPARAM)MAKE_SEGPTR(str));
247
248         hBitmap = hFolder;
249         GetObject16( hBitmap, sizeof(bm), &bm );
250         TextOut16(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth, 
251                   lpdis->rcItem.top, str, strlen(str));
252         hMemDC = CreateCompatibleDC(lpdis->hDC);
253         hPrevBitmap = SelectObject(hMemDC, hBitmap);
254         BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
255                bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
256         SelectObject(hMemDC, hPrevBitmap);
257         DeleteDC(hMemDC);
258         if (lpdis->itemState != 0) {
259             InvertRect16(lpdis->hDC, &lpdis->rcItem);
260         }
261         return TRUE;
262     }
263     if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2) {
264         hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
265         SelectObject(lpdis->hDC, hBrush);
266         FillRect16(lpdis->hDC, &lpdis->rcItem, hBrush);
267         SendMessage16(lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID, 
268                       (LPARAM)MAKE_SEGPTR(str));
269         switch(DRIVE_GetType( str[2] - 'a' ))
270         {
271         case TYPE_FLOPPY:  hBitmap = hFloppy; break;
272         case TYPE_CDROM:   hBitmap = hCDRom; break;
273         case TYPE_HD:
274         case TYPE_NETWORK:
275         default:           hBitmap = hHDisk; break;
276         }
277         GetObject16( hBitmap, sizeof(bm), &bm );
278         TextOut16(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth, 
279                   lpdis->rcItem.top, str, strlen(str));
280         hMemDC = CreateCompatibleDC(lpdis->hDC);
281         hPrevBitmap = SelectObject(hMemDC, hBitmap);
282         BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
283                bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
284         SelectObject(hMemDC, hPrevBitmap);
285         DeleteDC(hMemDC);
286         if (lpdis->itemState != 0) {
287             InvertRect16(lpdis->hDC, &lpdis->rcItem);
288         }
289         return TRUE;
290     }
291     return FALSE;
292 }
293
294 /***********************************************************************
295  *                              FILEDLG_WMMeasureItem           [internal]
296  */
297 static LONG FILEDLG_WMMeasureItem(HWND hWnd, WPARAM wParam, LPARAM lParam) 
298 {
299     BITMAP16 bm;
300     LPMEASUREITEMSTRUCT16 lpmeasure;
301     
302     GetObject16( hFolder2, sizeof(bm), &bm );
303     lpmeasure = (LPMEASUREITEMSTRUCT16)PTR_SEG_TO_LIN(lParam);
304     lpmeasure->itemHeight = bm.bmHeight;
305     return TRUE;
306 }
307
308 /***********************************************************************
309  *                              FILEDLG_HookCallChk             [internal]
310  */
311 static int FILEDLG_HookCallChk(LPOPENFILENAME lpofn)
312 {
313  if (lpofn)
314   if (lpofn->Flags & OFN_ENABLEHOOK)
315    if (lpofn->lpfnHook)
316     return 1;
317  return 0;   
318
319
320 /***********************************************************************
321  *                              FILEDLG_WMInitDialog            [internal]
322  */
323
324 static LONG FILEDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam) 
325 {
326   int n;
327   int i;
328   LPOPENFILENAME lpofn;
329   char tmpstr[512];
330   LPSTR pstr;
331   SetWindowLong32A(hWnd, DWL_USER, lParam);
332   lpofn = (LPOPENFILENAME)lParam;
333   if (lpofn->lpstrTitle) SetWindowText16( hWnd, lpofn->lpstrTitle );
334   /* read custom filter information */
335   if (lpofn->lpstrCustomFilter)
336     {
337       pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter);
338       dprintf_commdlg(stddeb,"lpstrCustomFilter = %p\n", pstr);
339       while(*pstr)
340         {
341           n = strlen(pstr);
342           strncpy(tmpstr, pstr, 511); tmpstr[511]=0;
343           dprintf_commdlg(stddeb,"lpstrCustomFilter // add tmpstr='%s' ", tmpstr);
344           i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
345           pstr += n + 1;
346           n = strlen(pstr);
347           dprintf_commdlg(stddeb,"associated to '%s'\n", pstr);
348           SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
349           pstr += n + 1;
350         }
351     }
352   /* read filter information */
353   pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
354   while(*pstr)
355     {
356       n = strlen(pstr);
357       strncpy(tmpstr, pstr, 511); tmpstr[511]=0;
358       dprintf_commdlg(stddeb,"lpstrFilter // add tmpstr='%s' ", tmpstr);
359       i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
360       pstr += n + 1;
361       n = strlen(pstr);
362       dprintf_commdlg(stddeb,"associated to '%s'\n", pstr);
363       SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
364       pstr += n + 1;
365     }
366   /* set default filter */
367   if (lpofn->nFilterIndex == 0 && lpofn->lpstrCustomFilter == (SEGPTR)NULL)
368         lpofn->nFilterIndex = 1;
369   SendDlgItemMessage16(hWnd, cmb1, CB_SETCURSEL, lpofn->nFilterIndex - 1, 0);    
370   strncpy(tmpstr, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
371              PTR_SEG_TO_LIN(lpofn->lpstrFilter), lpofn->nFilterIndex - 1),511);
372   tmpstr[511]=0;
373   dprintf_commdlg(stddeb,"nFilterIndex = %ld // SetText of edt1 to '%s'\n", 
374                         lpofn->nFilterIndex, tmpstr);
375   SetDlgItemText32A( hWnd, edt1, tmpstr );
376   /* get drive list */
377   *tmpstr = 0;
378   DlgDirListComboBox16(hWnd, (LPSTR)MAKE_SEGPTR(tmpstr), cmb2, 0, 0xC000);
379   /* read initial directory */
380   if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL) 
381     {
382       strncpy(tmpstr, PTR_SEG_TO_LIN(lpofn->lpstrInitialDir), 510);
383       tmpstr[510]=0;
384       if (strlen(tmpstr) > 0 && tmpstr[strlen(tmpstr)-1] != '\\' 
385           && tmpstr[strlen(tmpstr)-1] != ':')
386         strcat(tmpstr,"\\");
387     }
388   else
389     *tmpstr = 0;
390   if (!FILEDLG_ScanDir(hWnd, tmpstr))
391     fprintf(stderr, "FileDlg: couldn't read initial directory %s!\n", tmpstr);
392   /* select current drive in combo 2 */
393   n = DRIVE_GetCurrentDrive();
394   SendDlgItemMessage16(hWnd, cmb2, CB_SETCURSEL, n, 0);
395   if (!(lpofn->Flags & OFN_SHOWHELP))
396     ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
397   if (lpofn->Flags & OFN_HIDEREADONLY)
398     ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE); 
399   if (FILEDLG_HookCallChk(lpofn))
400      return (BOOL)CallWindowProc16(lpofn->lpfnHook, 
401                hWnd,  WM_INITDIALOG, wParam,(LPARAM)MAKE_SEGPTR(lpofn));
402   else  
403      return TRUE;
404 }
405
406 /***********************************************************************
407  *                              FILEDLG_WMCommand               [internal]
408  */
409 static LRESULT FILEDLG_WMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) 
410 {
411   LONG lRet;
412   LPOPENFILENAME lpofn;
413   OPENFILENAME ofn2;
414   char tmpstr[512], tmpstr2[512];
415   LPSTR pstr, pstr2;
416   UINT control,notification;
417
418   /* Notifications are packaged differently in Win32 */
419   control = wParam;
420   notification = HIWORD(lParam);
421     
422   lpofn = (LPOPENFILENAME)GetWindowLong32A(hWnd, DWL_USER);
423   switch (control)
424     {
425     case lst1: /* file list */
426       FILEDLG_StripEditControl(hWnd);
427       if (notification == LBN_DBLCLK)
428         goto almost_ok;
429       lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL, 0, 0);
430       if (lRet == LB_ERR) return TRUE;
431       SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT, lRet,
432                          (LPARAM)MAKE_SEGPTR(tmpstr));
433       SetDlgItemText32A( hWnd, edt1, tmpstr );
434
435       if (FILEDLG_HookCallChk(lpofn))
436        CallWindowProc16(lpofn->lpfnHook, hWnd,
437                   RegisterWindowMessage32A( LBSELCHSTRING ),
438                   control, MAKELONG(lRet,CD_LBSELCHANGE));       
439       /* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD, CD_LBSELNOITEMS */                  
440       return TRUE;
441     case lst2: /* directory list */
442       FILEDLG_StripEditControl(hWnd);
443       if (notification == LBN_DBLCLK)
444         {
445           lRet = SendDlgItemMessage16(hWnd, lst2, LB_GETCURSEL, 0, 0);
446           if (lRet == LB_ERR) return TRUE;
447           SendDlgItemMessage16(hWnd, lst2, LB_GETTEXT, lRet,
448                              (LPARAM)MAKE_SEGPTR(tmpstr));
449           if (tmpstr[0] == '[')
450             {
451               tmpstr[strlen(tmpstr) - 1] = 0;
452               strcpy(tmpstr,tmpstr+1);
453             }
454           strcat(tmpstr, "\\");
455           goto reset_scan;
456         }
457       return TRUE;
458     case cmb1: /* file type drop list */
459       if (notification == CBN_SELCHANGE) 
460         {
461           *tmpstr = 0;
462           goto reset_scan;
463         }
464       return TRUE;
465     case cmb2: /* disk drop list */
466       FILEDLG_StripEditControl(hWnd);
467       lRet = SendDlgItemMessage16(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
468       if (lRet == LB_ERR) return 0;
469       SendDlgItemMessage16(hWnd, cmb2, CB_GETLBTEXT, lRet, (LPARAM)MAKE_SEGPTR(tmpstr));
470       sprintf(tmpstr, "%c:", tmpstr[2]);
471     reset_scan:
472       lRet = SendDlgItemMessage16(hWnd, cmb1, CB_GETCURSEL, 0, 0);
473       if (lRet == LB_ERR)
474         return TRUE;
475       pstr = (LPSTR)SendDlgItemMessage16(hWnd, cmb1, CB_GETITEMDATA, lRet, 0);
476       dprintf_commdlg(stddeb,"Selected filter : %s\n", pstr);
477       SetDlgItemText32A( hWnd, edt1, pstr );
478       FILEDLG_ScanDir(hWnd, tmpstr);
479       return TRUE;
480     case chx1:
481       return TRUE;
482     case pshHelp:
483       return TRUE;
484     case IDOK:
485     almost_ok:
486       ofn2=*lpofn; /* for later restoring */
487       GetDlgItemText32A( hWnd, edt1, tmpstr, sizeof(tmpstr) );
488       pstr = strrchr(tmpstr, '\\');
489       if (pstr == NULL)
490         pstr = strrchr(tmpstr, ':');
491       if (strchr(tmpstr,'*') != NULL || strchr(tmpstr,'?') != NULL)
492         {
493           /* edit control contains wildcards */
494           if (pstr != NULL)
495             {
496               strncpy(tmpstr2, pstr+1, 511); tmpstr2[511]=0;
497               *(pstr+1) = 0;
498             }
499           else
500             {
501               strcpy(tmpstr2, tmpstr);
502               *tmpstr=0;
503             }
504           dprintf_commdlg(stddeb,"commdlg: %s, %s\n", tmpstr, tmpstr2);
505           SetDlgItemText32A( hWnd, edt1, tmpstr2 );
506           FILEDLG_ScanDir(hWnd, tmpstr);
507           return TRUE;
508         }
509       /* no wildcards, we might have a directory or a filename */
510       /* try appending a wildcard and reading the directory */
511       pstr2 = tmpstr + strlen(tmpstr);
512       if (pstr == NULL || *(pstr+1) != 0)
513         strcat(tmpstr, "\\");
514       lRet = SendDlgItemMessage16(hWnd, cmb1, CB_GETCURSEL, 0, 0);
515       if (lRet == LB_ERR) return TRUE;
516       lpofn->nFilterIndex = lRet + 1;
517       dprintf_commdlg(stddeb,"commdlg: lpofn->nFilterIndex=%ld\n", lpofn->nFilterIndex);
518       lstrcpyn32A(tmpstr2, 
519              FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
520                                  PTR_SEG_TO_LIN(lpofn->lpstrFilter),
521                                  lRet), sizeof(tmpstr2));
522       SetDlgItemText32A( hWnd, edt1, tmpstr2 );
523       /* if ScanDir succeeds, we have changed the directory */
524       if (FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
525       /* if not, this must be a filename */
526       *pstr2 = 0;
527       if (pstr != NULL)
528         {
529           /* strip off the pathname */
530           *pstr = 0;
531           SetDlgItemText32A( hWnd, edt1, pstr + 1 );
532           lstrcpyn32A(tmpstr2, pstr+1, sizeof(tmpstr2) );
533           /* Should we MessageBox() if this fails? */
534           if (!FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
535           strcpy(tmpstr, tmpstr2);
536         }
537       else SetDlgItemText32A( hWnd, edt1, tmpstr );
538 #if 0
539       ShowWindow(hWnd, SW_HIDE);   /* this should not be necessary ?! (%%%) */
540 #endif
541       {
542         int drive = DRIVE_GetCurrentDrive();
543         tmpstr2[0] = 'A'+ drive;
544         tmpstr2[1] = ':';
545         tmpstr2[2] = '\\';
546         strncpy(tmpstr2 + 3, DRIVE_GetDosCwd(drive), 507); tmpstr2[510]=0;
547         if (strlen(tmpstr2) > 3)
548            strcat(tmpstr2, "\\");
549         strncat(tmpstr2, tmpstr, 511-strlen(tmpstr2)); tmpstr2[511]=0;
550         strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFile), tmpstr2);
551       }
552       lpofn->nFileOffset = 0;
553       lpofn->nFileExtension = 0;
554       while(tmpstr2[lpofn->nFileExtension] != '.' && tmpstr2[lpofn->nFileExtension] != '\0')
555         lpofn->nFileExtension++;
556       if (lpofn->nFileExtension == '\0')
557         lpofn->nFileExtension = 0;
558       else
559         lpofn->nFileExtension++;
560       if (PTR_SEG_TO_LIN(lpofn->lpstrFileTitle) != NULL) 
561         {
562           lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL, 0, 0);
563           SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT, lRet,
564                              (LPARAM)MAKE_SEGPTR(tmpstr));
565           dprintf_commdlg(stddeb,"strcpy'ing '%s'\n",tmpstr); fflush(stdout);
566           strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFileTitle), tmpstr);
567         }
568       if (FILEDLG_HookCallChk(lpofn))
569       {
570        lRet= (BOOL)CallWindowProc16(lpofn->lpfnHook,
571                hWnd, RegisterWindowMessage32A( FILEOKSTRING ),
572                0, (LPARAM)MAKE_SEGPTR(lpofn));                        
573        if (lRet)       
574        {
575          *lpofn=ofn2; /* restore old state */
576 #if 0
577          ShowWindow(hWnd, SW_SHOW);               /* only if above (%%%) SW_HIDE used */
578 #endif         
579          break;
580        }
581       }
582       EndDialog(hWnd, TRUE);
583       return TRUE;
584     case IDCANCEL:
585       EndDialog(hWnd, FALSE);
586       return TRUE;
587     }
588   return FALSE;
589 }
590
591
592 /***********************************************************************
593  *           FileOpenDlgProc   (COMMDLG.6)
594  */
595 LRESULT FileOpenDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
596 {  
597  LPOPENFILENAME lpofn = (LPOPENFILENAME)GetWindowLong32A(hWnd, DWL_USER);
598  
599  if (wMsg!=WM_INITDIALOG)
600   if (FILEDLG_HookCallChk(lpofn))
601   {
602    LRESULT  lRet=(BOOL)CallWindowProc16(lpofn->lpfnHook, hWnd, wMsg, wParam, lParam);
603    if (lRet)   
604     return lRet;         /* else continue message processing */
605   }             
606   switch (wMsg)
607     {
608     case WM_INITDIALOG:
609       return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
610     case WM_MEASUREITEM:
611       return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
612     case WM_DRAWITEM:
613       return FILEDLG_WMDrawItem(hWnd, wParam, lParam, FALSE);
614     case WM_COMMAND:
615       return FILEDLG_WMCommand(hWnd, wParam, lParam);
616 #if 0
617     case WM_CTLCOLOR:
618       SetBkColor((HDC)wParam, 0x00C0C0C0);
619       switch (HIWORD(lParam))
620         {
621         case CTLCOLOR_BTN:
622           SetTextColor((HDC)wParam, 0x00000000);
623           return hGRAYBrush;
624         case CTLCOLOR_STATIC:
625           SetTextColor((HDC)wParam, 0x00000000);
626           return hGRAYBrush;
627         }
628       break;
629 #endif
630     }
631   return FALSE;
632 }
633
634
635 /***********************************************************************
636  *           FileSaveDlgProc   (COMMDLG.7)
637  */
638 LRESULT FileSaveDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
639 {
640  LPOPENFILENAME lpofn = (LPOPENFILENAME)GetWindowLong32A(hWnd, DWL_USER);
641  
642  if (wMsg!=WM_INITDIALOG)
643   if (FILEDLG_HookCallChk(lpofn))
644   {
645    LRESULT  lRet=(BOOL)CallWindowProc16(lpofn->lpfnHook, hWnd, wMsg, wParam, lParam);
646    if (lRet)   
647     return lRet;         /* else continue message processing */
648   }             
649   switch (wMsg) {
650    case WM_INITDIALOG:
651       return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
652       
653    case WM_MEASUREITEM:
654       return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
655     
656    case WM_DRAWITEM:
657       return FILEDLG_WMDrawItem(hWnd, wParam, lParam, TRUE);
658
659    case WM_COMMAND:
660       return FILEDLG_WMCommand(hWnd, wParam, lParam);
661   }
662   
663   /*
664   case WM_CTLCOLOR:
665    SetBkColor((HDC)wParam, 0x00C0C0C0);
666    switch (HIWORD(lParam))
667    {
668     case CTLCOLOR_BTN:
669      SetTextColor((HDC)wParam, 0x00000000);
670      return hGRAYBrush;
671     case CTLCOLOR_STATIC:
672      SetTextColor((HDC)wParam, 0x00000000);
673      return hGRAYBrush;
674    }
675    return FALSE;
676    
677    */
678   return FALSE;
679 }
680
681
682 /***********************************************************************
683  *           FindTextDlg   (COMMDLG.11)
684  */
685 BOOL FindText(LPFINDREPLACE lpFind)
686 {
687     HANDLE hInst, hDlgTmpl;
688     BOOL bRet;
689     LPCVOID ptr;
690
691     /*
692      * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
693      * For now, only the standard dialog works.
694      */
695     /*
696      * FIXME : We should do error checking on the lpFind structure here
697      * and make CommDlgExtendedError() return the error condition.
698      */
699     hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_FIND_TEXT );
700     hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
701     if (!(ptr = GlobalLock16( hDlgTmpl ))) return -1;
702     bRet = CreateDialogIndirectParam16( hInst, ptr, lpFind->hwndOwner,
703                         (DLGPROC16)MODULE_GetWndProcEntry16("FindTextDlgProc"),
704                         (DWORD)lpFind );
705     GlobalUnlock16( hDlgTmpl );
706     SYSRES_FreeResource( hDlgTmpl );
707     return bRet;
708 }
709
710
711 /***********************************************************************
712  *           ReplaceTextDlg   (COMMDLG.12)
713  */
714 BOOL ReplaceText(LPFINDREPLACE lpFind)
715 {
716     HANDLE hInst, hDlgTmpl;
717     BOOL bRet;
718     LPCVOID ptr;
719
720     /*
721      * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
722      * For now, only the standard dialog works.
723      */
724     /*
725      * FIXME : We should do error checking on the lpFind structure here
726      * and make CommDlgExtendedError() return the error condition.
727      */
728     hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_REPLACE_TEXT );
729     hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
730     if (!(ptr = GlobalLock16( hDlgTmpl ))) return -1;
731     bRet = CreateDialogIndirectParam16( hInst, ptr, lpFind->hwndOwner,
732                      (DLGPROC16)MODULE_GetWndProcEntry16("ReplaceTextDlgProc"),
733                      (DWORD)lpFind );
734     GlobalUnlock16( hDlgTmpl );
735     SYSRES_FreeResource( hDlgTmpl );
736     return bRet;
737 }
738
739
740 /***********************************************************************
741  *                              FINDDLG_WMInitDialog            [internal]
742  */
743 static LRESULT FINDDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
744 {
745     LPFINDREPLACE lpfr;
746
747     SetWindowLong32A(hWnd, DWL_USER, lParam);
748     lpfr = (LPFINDREPLACE)lParam;
749     lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
750     /*
751      * FIXME : If the initial FindWhat string is empty, we should disable the
752      * FindNext (IDOK) button.  Only after typing some text, the button should be
753      * enabled.
754      */
755     SetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat);
756     CheckRadioButton(hWnd, rad1, rad2, (lpfr->Flags & FR_DOWN) ? rad2 : rad1);
757     if (lpfr->Flags & (FR_HIDEUPDOWN | FR_NOUPDOWN)) {
758         EnableWindow(GetDlgItem(hWnd, rad1), FALSE);
759         EnableWindow(GetDlgItem(hWnd, rad2), FALSE);
760     }
761     if (lpfr->Flags & FR_HIDEUPDOWN) {
762         ShowWindow(GetDlgItem(hWnd, rad1), SW_HIDE);
763         ShowWindow(GetDlgItem(hWnd, rad2), SW_HIDE);
764         ShowWindow(GetDlgItem(hWnd, grp1), SW_HIDE);
765     }
766     CheckDlgButton(hWnd, chx1, (lpfr->Flags & FR_WHOLEWORD) ? 1 : 0);
767     if (lpfr->Flags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
768         EnableWindow(GetDlgItem(hWnd, chx1), FALSE);
769     if (lpfr->Flags & FR_HIDEWHOLEWORD)
770         ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
771     CheckDlgButton(hWnd, chx2, (lpfr->Flags & FR_MATCHCASE) ? 1 : 0);
772     if (lpfr->Flags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
773         EnableWindow(GetDlgItem(hWnd, chx2), FALSE);
774     if (lpfr->Flags & FR_HIDEMATCHCASE)
775         ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE);
776     if (!(lpfr->Flags & FR_SHOWHELP)) {
777         EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE);
778         ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
779     }
780     ShowWindow(hWnd, SW_SHOWNORMAL);
781     return TRUE;
782 }    
783
784
785 /***********************************************************************
786  *                              FINDDLG_WMCommand               [internal]
787  */
788 static LRESULT FINDDLG_WMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
789 {
790     LPFINDREPLACE lpfr;
791     int uFindReplaceMessage = RegisterWindowMessage32A( FINDMSGSTRING );
792     int uHelpMessage = RegisterWindowMessage32A( HELPMSGSTRING );
793
794     lpfr = (LPFINDREPLACE)GetWindowLong32A(hWnd, DWL_USER);
795     switch (wParam) {
796         case IDOK:
797             GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
798             if (IsDlgButtonChecked(hWnd, rad2))
799                 lpfr->Flags |= FR_DOWN;
800                 else lpfr->Flags &= ~FR_DOWN;
801             if (IsDlgButtonChecked(hWnd, chx1))
802                 lpfr->Flags |= FR_WHOLEWORD; 
803                 else lpfr->Flags &= ~FR_WHOLEWORD;
804             if (IsDlgButtonChecked(hWnd, chx2))
805                 lpfr->Flags |= FR_MATCHCASE; 
806                 else lpfr->Flags &= ~FR_MATCHCASE;
807             lpfr->Flags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
808             lpfr->Flags |= FR_FINDNEXT;
809             SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
810             return TRUE;
811         case IDCANCEL:
812             lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
813             lpfr->Flags |= FR_DIALOGTERM;
814             SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
815             DestroyWindow(hWnd);
816             return TRUE;
817         case pshHelp:
818             /* FIXME : should lpfr structure be passed as an argument ??? */
819             SendMessage16(lpfr->hwndOwner, uHelpMessage, 0, 0);
820             return TRUE;
821     }
822     return FALSE;
823 }    
824
825
826 /***********************************************************************
827  *           FindTextDlgProc   (COMMDLG.13)
828  */
829 LRESULT FindTextDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
830 {
831     switch (wMsg) {
832         case WM_INITDIALOG:
833             return FINDDLG_WMInitDialog(hWnd, wParam, lParam);
834         case WM_COMMAND:
835             return FINDDLG_WMCommand(hWnd, wParam, lParam);
836     }
837     return FALSE;
838 }
839
840
841 /***********************************************************************
842  *                              REPLACEDLG_WMInitDialog         [internal]
843  */
844 static LRESULT REPLACEDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
845 {
846     LPFINDREPLACE lpfr;
847
848     SetWindowLong32A(hWnd, DWL_USER, lParam);
849     lpfr = (LPFINDREPLACE)lParam;
850     lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
851     /*
852      * FIXME : If the initial FindWhat string is empty, we should disable the FinNext /
853      * Replace / ReplaceAll buttons.  Only after typing some text, the buttons should be
854      * enabled.
855      */
856     SetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat);
857     SetDlgItemText16(hWnd, edt2, lpfr->lpstrReplaceWith);
858     CheckDlgButton(hWnd, chx1, (lpfr->Flags & FR_WHOLEWORD) ? 1 : 0);
859     if (lpfr->Flags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
860         EnableWindow(GetDlgItem(hWnd, chx1), FALSE);
861     if (lpfr->Flags & FR_HIDEWHOLEWORD)
862         ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
863     CheckDlgButton(hWnd, chx2, (lpfr->Flags & FR_MATCHCASE) ? 1 : 0);
864     if (lpfr->Flags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
865         EnableWindow(GetDlgItem(hWnd, chx2), FALSE);
866     if (lpfr->Flags & FR_HIDEMATCHCASE)
867         ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE);
868     if (!(lpfr->Flags & FR_SHOWHELP)) {
869         EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE);
870         ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
871     }
872     ShowWindow(hWnd, SW_SHOWNORMAL);
873     return TRUE;
874 }    
875
876
877 /***********************************************************************
878  *                              REPLACEDLG_WMCommand            [internal]
879  */
880 static LRESULT REPLACEDLG_WMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
881 {
882     LPFINDREPLACE lpfr;
883     int uFindReplaceMessage = RegisterWindowMessage32A( FINDMSGSTRING );
884     int uHelpMessage = RegisterWindowMessage32A( HELPMSGSTRING );
885
886     lpfr = (LPFINDREPLACE)GetWindowLong32A(hWnd, DWL_USER);
887     switch (wParam) {
888         case IDOK:
889             GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
890             GetDlgItemText16(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
891             if (IsDlgButtonChecked(hWnd, chx1))
892                 lpfr->Flags |= FR_WHOLEWORD; 
893                 else lpfr->Flags &= ~FR_WHOLEWORD;
894             if (IsDlgButtonChecked(hWnd, chx2))
895                 lpfr->Flags |= FR_MATCHCASE; 
896                 else lpfr->Flags &= ~FR_MATCHCASE;
897             lpfr->Flags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
898             lpfr->Flags |= FR_FINDNEXT;
899             SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
900             return TRUE;
901         case IDCANCEL:
902             lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
903             lpfr->Flags |= FR_DIALOGTERM;
904             SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
905             DestroyWindow(hWnd);
906             return TRUE;
907         case psh1:
908             GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
909             GetDlgItemText16(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
910             if (IsDlgButtonChecked(hWnd, chx1))
911                 lpfr->Flags |= FR_WHOLEWORD; 
912                 else lpfr->Flags &= ~FR_WHOLEWORD;
913             if (IsDlgButtonChecked(hWnd, chx2))
914                 lpfr->Flags |= FR_MATCHCASE; 
915                 else lpfr->Flags &= ~FR_MATCHCASE;
916             lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACEALL | FR_DIALOGTERM);
917             lpfr->Flags |= FR_REPLACE;
918             SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
919             return TRUE;
920         case psh2:
921             GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
922             GetDlgItemText16(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
923             if (IsDlgButtonChecked(hWnd, chx1))
924                 lpfr->Flags |= FR_WHOLEWORD; 
925                 else lpfr->Flags &= ~FR_WHOLEWORD;
926             if (IsDlgButtonChecked(hWnd, chx2))
927                 lpfr->Flags |= FR_MATCHCASE; 
928                 else lpfr->Flags &= ~FR_MATCHCASE;
929             lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_DIALOGTERM);
930             lpfr->Flags |= FR_REPLACEALL;
931             SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
932             return TRUE;
933         case pshHelp:
934             /* FIXME : should lpfr structure be passed as an argument ??? */
935             SendMessage16(lpfr->hwndOwner, uHelpMessage, 0, 0);
936             return TRUE;
937     }
938     return FALSE;
939 }    
940
941
942 /***********************************************************************
943  *           ReplaceTextDlgProc   (COMMDLG.14)
944  */
945 LRESULT ReplaceTextDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
946 {
947     switch (wMsg) {
948         case WM_INITDIALOG:
949             return REPLACEDLG_WMInitDialog(hWnd, wParam, lParam);
950         case WM_COMMAND:
951             return REPLACEDLG_WMCommand(hWnd, wParam, lParam);
952     }
953     return FALSE;
954 }
955
956
957 /***********************************************************************
958  *           PrintDlg   (COMMDLG.20)
959  */
960 BOOL PrintDlg(LPPRINTDLG lpPrint)
961 {
962     HANDLE hInst, hDlgTmpl;
963     BOOL bRet;
964
965     dprintf_commdlg(stddeb,"PrintDlg(%p) // Flags=%08lX\n", lpPrint, lpPrint->Flags );
966
967     if (lpPrint->Flags & PD_RETURNDEFAULT)
968         /* FIXME: should fill lpPrint->hDevMode and lpPrint->hDevNames here */
969         return TRUE;
970
971     if (lpPrint->Flags & PD_PRINTSETUP)
972         hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_PRINT_SETUP );
973     else
974         hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_PRINT );
975
976     hInst = WIN_GetWindowInstance( lpPrint->hwndOwner );
977     bRet = DialogBoxIndirectParam16( hInst, hDlgTmpl, lpPrint->hwndOwner,
978                                (DLGPROC16)((lpPrint->Flags & PD_PRINTSETUP) ?
979                                 MODULE_GetWndProcEntry16("PrintSetupDlgProc") :
980                                 MODULE_GetWndProcEntry16("PrintDlgProc")),
981                                (DWORD)lpPrint );
982     SYSRES_FreeResource( hDlgTmpl );
983     return bRet;
984 }
985
986
987 /***********************************************************************
988  *           PrintDlgProc   (COMMDLG.21)
989  */
990 LRESULT PrintDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
991 {
992   switch (wMsg)
993     {
994     case WM_INITDIALOG:
995       dprintf_commdlg(stddeb,"PrintDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
996       ShowWindow(hWnd, SW_SHOWNORMAL);
997       return (TRUE);
998     case WM_COMMAND:
999       switch (wParam)
1000         {
1001         case IDOK:
1002           EndDialog(hWnd, TRUE);
1003           return(TRUE);
1004         case IDCANCEL:
1005           EndDialog(hWnd, FALSE);
1006           return(TRUE);
1007         }
1008       return(FALSE);
1009     }
1010   return FALSE;
1011 }
1012
1013
1014 /***********************************************************************
1015  *           PrintSetupDlgProc   (COMMDLG.22)
1016  */
1017 LRESULT PrintSetupDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
1018 {
1019   switch (wMsg)
1020     {
1021     case WM_INITDIALOG:
1022       dprintf_commdlg(stddeb,"PrintSetupDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
1023       ShowWindow(hWnd, SW_SHOWNORMAL);
1024       return (TRUE);
1025     case WM_COMMAND:
1026       switch (wParam) {
1027       case IDOK:
1028         EndDialog(hWnd, TRUE);
1029         return(TRUE);
1030       case IDCANCEL:
1031         EndDialog(hWnd, FALSE);
1032         return(TRUE);
1033       }
1034       return(FALSE);
1035     }
1036   return FALSE;
1037 }
1038
1039
1040 /***********************************************************************
1041  *           CommDlgExtendedError   (COMMDLG.26)
1042  */
1043 DWORD CommDlgExtendedError(void)
1044 {
1045   return CommDlgLastError;
1046 }
1047
1048
1049 /***********************************************************************
1050  *           GetFileTitle   (COMMDLG.27)
1051  */
1052 short GetFileTitle(LPCSTR lpFile, LPSTR lpTitle, UINT cbBuf)
1053 {
1054     int i, len;
1055     dprintf_commdlg(stddeb,"GetFileTitle(%p %p %d); \n", lpFile, lpTitle, cbBuf);
1056     if (lpFile == NULL || lpTitle == NULL)
1057         return -1;
1058     len = strlen(lpFile);
1059     if (len == 0)
1060         return -1;
1061     if (strpbrk(lpFile, "*[]"))
1062         return -1;
1063     len--;
1064     if (lpFile[len] == '/' || lpFile[len] == '\\' || lpFile[len] == ':')
1065         return -1;
1066     for (i = len; i >= 0; i--)
1067         if (lpFile[i] == '/' ||  lpFile[i] == '\\' ||  lpFile[i] == ':')
1068     {
1069         i++;
1070         break;
1071     }
1072     dprintf_commdlg(stddeb,"\n---> '%s' ", &lpFile[i]);
1073     
1074     len = strlen(lpFile+i)+1;
1075     if (cbBuf < len)
1076         return len;
1077
1078     strncpy(lpTitle, &lpFile[i], len);
1079     return 0;
1080 }
1081
1082
1083 /* ------------------------ Choose Color Dialog --------------------------- */
1084
1085 /***********************************************************************
1086  *           ChooseColor   (COMMDLG.5)
1087  */
1088 BOOL ChooseColor(LPCHOOSECOLOR lpChCol)
1089 {
1090     HINSTANCE hInst;
1091     HANDLE hDlgTmpl, hResInfo;
1092     BOOL bRet;
1093
1094     dprintf_commdlg(stddeb,"ChooseColor\n");
1095     if (!lpChCol) return FALSE;    
1096     if (lpChCol->Flags & CC_ENABLETEMPLATEHANDLE) hDlgTmpl = lpChCol->hInstance;
1097     else if (lpChCol->Flags & CC_ENABLETEMPLATE)
1098     {
1099         if (!(hResInfo = FindResource16(lpChCol->hInstance,
1100                                         lpChCol->lpTemplateName, RT_DIALOG)))
1101         {
1102             CommDlgLastError = CDERR_FINDRESFAILURE;
1103             return FALSE;
1104         }
1105         hDlgTmpl = LoadResource16( lpChCol->hInstance, hResInfo );
1106     }
1107     else hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_CHOOSE_COLOR );
1108     if (!hDlgTmpl)
1109     {
1110         CommDlgLastError = CDERR_LOADRESFAILURE;
1111         return FALSE;
1112     }
1113     hInst = WIN_GetWindowInstance( lpChCol->hwndOwner );
1114     bRet = DialogBoxIndirectParam16( hInst, hDlgTmpl, lpChCol->hwndOwner,
1115                            (DLGPROC16)MODULE_GetWndProcEntry16("ColorDlgProc"),
1116                            (DWORD)lpChCol );
1117     if (!(lpChCol->Flags & CC_ENABLETEMPLATEHANDLE))
1118     {
1119         if (lpChCol->Flags & CC_ENABLETEMPLATE) FreeResource16( hDlgTmpl );
1120         else SYSRES_FreeResource( hDlgTmpl );
1121     }
1122     return bRet;
1123 }
1124
1125
1126 static const COLORREF predefcolors[6][8]=
1127 {
1128  { 0x008080FFL, 0x0080FFFFL, 0x0080FF80L, 0x0080FF00L,
1129    0x00FFFF80L, 0x00FF8000L, 0x00C080FFL, 0x00FF80FFL },
1130  { 0x000000FFL, 0x0000FFFFL, 0x0000FF80L, 0x0040FF00L,
1131    0x00FFFF00L, 0x00C08000L, 0x00C08080L, 0x00FF00FFL },
1132
1133  { 0x00404080L, 0x004080FFL, 0x0000FF00L, 0x00808000L,
1134    0x00804000L, 0x00FF8080L, 0x00400080L, 0x008000FFL },
1135  { 0x00000080L, 0x000080FFL, 0x00008000L, 0x00408000L,
1136    0x00FF0000L, 0x00A00000L, 0x00800080L, 0x00FF0080L },
1137
1138  { 0x00000040L, 0x00004080L, 0x00004000L, 0x00404000L,
1139    0x00800000L, 0x00400000L, 0x00400040L, 0x00800040L },
1140  { 0x00000000L, 0x00008080L, 0x00408080L, 0x00808080L,
1141    0x00808040L, 0x00C0C0C0L, 0x00400040L, 0x00FFFFFFL },
1142 };
1143
1144 struct CCPRIVATE
1145 {
1146  LPCHOOSECOLOR lpcc;  /* points to public known data structure */
1147  int nextuserdef;     /* next free place in user defined color array */
1148  HDC hdcMem;          /* color graph used for BitBlt() */
1149  HBITMAP hbmMem;      /* color graph bitmap */    
1150  RECT16 fullsize;     /* original dialog window size */
1151  UINT msetrgb;        /* # of SETRGBSTRING message (today not used)  */
1152  RECT16 old3angle;    /* last position of l-marker */
1153  RECT16 oldcross;     /* last position of color/satuation marker */
1154  BOOL updating;       /* to prevent recursive WM_COMMAND/EN_UPDATE procesing */
1155  int h;
1156  int s;
1157  int l;               /* for temporary storing of hue,sat,lum */
1158 };
1159
1160 /***********************************************************************
1161  *                             CC_HSLtoRGB                    [internal]
1162  */
1163 static int CC_HSLtoRGB(char c,int hue,int sat,int lum)
1164 {
1165  int res=0,maxrgb;
1166
1167  /* hue */
1168  switch(c)
1169  {
1170   case 'R':if (hue>80)  hue-=80;  else hue+=160; break;
1171   case 'G':if (hue>160) hue-=160; else hue+=80;  break;
1172   case 'B':break;
1173  }
1174
1175  /* l below 120 */
1176  maxrgb=(256*MIN(120,lum))/120;  /* 0 .. 256 */
1177  if (hue< 80)
1178   res=0;
1179  else
1180   if (hue< 120)
1181   {
1182    res=(hue-80)* maxrgb;           /* 0...10240 */
1183    res/=40;                        /* 0...256 */
1184   }
1185   else
1186    if (hue< 200)
1187     res=maxrgb;
1188    else
1189     {
1190      res=(240-hue)* maxrgb;
1191      res/=40;
1192     }
1193  res=res-maxrgb/2;                 /* -128...128 */
1194
1195  /* saturation */
1196  res=maxrgb/2 + (sat*res) /240;    /* 0..256 */
1197
1198  /* lum above 120 */
1199  if (lum>120 && res<256)
1200   res+=((lum-120) * (256-res))/120;
1201
1202  return MIN(res,255);
1203 }
1204
1205 /***********************************************************************
1206  *                             CC_RGBtoHSL                    [internal]
1207  */
1208 static int CC_RGBtoHSL(char c,int r,int g,int b)
1209 {
1210  WORD maxi,mini,mmsum,mmdif,result=0;
1211  int iresult=0;
1212
1213  maxi=MAX(r,b);
1214  maxi=MAX(maxi,g);
1215  mini=MIN(r,b);
1216  mini=MIN(mini,g);
1217
1218  mmsum=maxi+mini;
1219  mmdif=maxi-mini;
1220
1221  switch(c)
1222  {
1223   /* lum */
1224   case 'L':mmsum*=120;              /* 0...61200=(255+255)*120 */
1225            result=mmsum/255;        /* 0...240 */
1226            break;
1227   /* saturation */
1228   case 'S':if (!mmsum)
1229             result=0;
1230            else
1231             if (!mini || maxi==255)
1232              result=240;
1233            else
1234            {
1235             result=mmdif*240;       /* 0...61200=255*240 */
1236             result/= (mmsum>255 ? mmsum=510-mmsum : mmsum); /* 0..255 */
1237            }
1238            break;
1239   /* hue */
1240   case 'H':if (!mmdif)
1241             result=160;
1242            else
1243            {
1244             if (maxi==r)
1245             {
1246              iresult=40*(g-b);       /* -10200 ... 10200 */
1247              iresult/=(int)mmdif;    /* -40 .. 40 */
1248              if (iresult<0)
1249               iresult+=240;          /* 0..40 and 200..240 */
1250             }
1251             else
1252              if (maxi==g)
1253              {
1254               iresult=40*(b-r);
1255               iresult/=(int)mmdif;
1256               iresult+=80;           /* 40 .. 120 */
1257              }
1258              else
1259               if (maxi==b)
1260               {
1261                iresult=40*(r-g);
1262                iresult/=(int)mmdif;
1263                iresult+=160;         /* 120 .. 200 */
1264               }
1265             result=iresult;
1266            }
1267            break;
1268  }
1269  return result;    /* is this integer arithmetic precise enough ? */
1270 }
1271
1272 #define DISTANCE 4
1273
1274 /***********************************************************************
1275  *                CC_MouseCheckPredefColorArray               [internal]
1276  */
1277 static int CC_MouseCheckPredefColorArray(HWND hDlg,int dlgitem,int rows,int cols,
1278             LPARAM lParam,COLORREF *cr)
1279 {
1280  HWND hwnd;
1281  POINT16 point = MAKEPOINT16(lParam);
1282  RECT16 rect;
1283  int dx,dy,x,y;
1284
1285  ClientToScreen16(hDlg,&point);
1286  hwnd=GetDlgItem(hDlg,dlgitem);
1287  GetWindowRect16(hwnd,&rect);
1288  if (PtInRect16(&rect,point))
1289  {
1290   dx=(rect.right-rect.left)/cols;
1291   dy=(rect.bottom-rect.top)/rows;
1292   ScreenToClient16(hwnd,&point);
1293
1294   if (point.x % dx < (dx-DISTANCE) && point.y % dy < (dy-DISTANCE))
1295   {
1296    x=point.x/dx;
1297    y=point.y/dy;
1298    *cr=predefcolors[y][x];
1299    /* FIXME: Draw_a_Focus_Rect() */
1300    return 1;
1301   }
1302  }
1303  return 0;
1304 }
1305
1306 /***********************************************************************
1307  *                  CC_MouseCheckUserColorArray               [internal]
1308  */
1309 static int CC_MouseCheckUserColorArray(HWND hDlg,int dlgitem,int rows,int cols,
1310             LPARAM lParam,COLORREF *cr,COLORREF*crarr)
1311 {
1312  HWND hwnd;
1313  POINT16 point = MAKEPOINT16(lParam);
1314  RECT16 rect;
1315  int dx,dy,x,y;
1316
1317  ClientToScreen16(hDlg,&point);
1318  hwnd=GetDlgItem(hDlg,dlgitem);
1319  GetWindowRect16(hwnd,&rect);
1320  if (PtInRect16(&rect,point))
1321  {
1322   dx=(rect.right-rect.left)/cols;
1323   dy=(rect.bottom-rect.top)/rows;
1324   ScreenToClient16(hwnd,&point);
1325
1326   if (point.x % dx < (dx-DISTANCE) && point.y % dy < (dy-DISTANCE))
1327   {
1328    x=point.x/dx;
1329    y=point.y/dy;
1330    *cr=crarr[x+cols*y];
1331    /* FIXME: Draw_a_Focus_Rect() */
1332    return 1;
1333   }
1334  }
1335  return 0;
1336 }
1337
1338 #define MAXVERT  240
1339 #define MAXHORI  239
1340
1341 /*  240  ^......        ^^ 240
1342          |     .        ||
1343     SAT  |     .        || LUM
1344          |     .        ||
1345          +-----> 239   ----
1346            HUE
1347 */
1348 /***********************************************************************
1349  *                  CC_MouseCheckColorGraph                   [internal]
1350  */
1351 static int CC_MouseCheckColorGraph(HWND hDlg,int dlgitem,int *hori,int *vert,LPARAM lParam)
1352 {
1353  HWND hwnd;
1354  POINT16 point = MAKEPOINT16(lParam);
1355  RECT16 rect;
1356  long x,y;
1357
1358  ClientToScreen16(hDlg,&point);
1359  hwnd=GetDlgItem(hDlg,dlgitem);
1360  GetWindowRect16(hwnd,&rect);
1361  if (PtInRect16(&rect,point))
1362  {
1363   GetClientRect16(hwnd,&rect);
1364   ScreenToClient16(hwnd,&point);
1365
1366   x=(long)point.x*MAXHORI;
1367   x/=rect.right;
1368   y=(long)(rect.bottom-point.y)*MAXVERT;
1369   y/=rect.bottom;
1370
1371   if (hori)
1372    *hori=x;
1373   if (vert)
1374    *vert=y;
1375   return 1;
1376  }
1377  else
1378   return 0;
1379 }
1380 /***********************************************************************
1381  *                  CC_MouseCheckResultWindow                 [internal]
1382  */
1383 static int CC_MouseCheckResultWindow(HWND hDlg,LPARAM lParam)
1384 {
1385  HWND hwnd;
1386  POINT16 point = MAKEPOINT16(lParam);
1387  RECT16 rect;
1388
1389  ClientToScreen16(hDlg,&point);
1390  hwnd=GetDlgItem(hDlg,0x2c5);
1391  GetWindowRect16(hwnd,&rect);
1392  if (PtInRect16(&rect,point))
1393  {
1394   PostMessage(hDlg,WM_COMMAND,0x2c9,0);
1395   return 1;
1396  }
1397  return 0;
1398 }
1399
1400 /***********************************************************************
1401  *                       CC_CheckDigitsInEdit                 [internal]
1402  */
1403 static int CC_CheckDigitsInEdit(HWND hwnd,int maxval)
1404 {
1405  int i,k,m,result,value;
1406  long editpos;
1407  char buffer[30];
1408  GetWindowText32A(hwnd,buffer,sizeof(buffer));
1409  m=strlen(buffer);
1410  result=0;
1411
1412  for (i=0;i<m;i++)
1413   if (buffer[i]<'0' || buffer[i]>'9')
1414   {
1415    for (k=i+1;k<=m;k++)   /* delete bad character */
1416    {
1417     buffer[i]=buffer[k];
1418     m--;
1419    }
1420    buffer[m]=0;
1421    result=1;
1422   }
1423
1424  value=atoi(buffer);
1425  if (value>maxval)       /* build a new string */
1426  {
1427   sprintf(buffer,"%d",maxval);
1428   result=2;
1429  }
1430  if (result)
1431  {
1432   editpos=SendMessage16(hwnd,EM_GETSEL,0,0);
1433   SetWindowText32A(hwnd,buffer);
1434   SendMessage16(hwnd,EM_SETSEL,0,editpos);
1435  }
1436  return value;
1437 }
1438
1439
1440
1441 /***********************************************************************
1442  *                    CC_PaintSelectedColor                   [internal]
1443  */
1444 static void CC_PaintSelectedColor(HWND hDlg,COLORREF cr)
1445 {
1446  RECT16 rect;
1447  HDC  hdc;
1448  HBRUSH hBrush;
1449  HWND hwnd=GetDlgItem(hDlg,0x2c5);
1450  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
1451  {
1452   hdc=GetDC(hwnd);
1453   GetClientRect16 (hwnd, &rect) ;
1454   hBrush = CreateSolidBrush(cr);
1455   if (hBrush)
1456   {
1457    hBrush = SelectObject (hdc, hBrush) ;
1458    Rectangle (hdc, rect.left,rect.top,rect.right/2,rect.bottom);
1459    DeleteObject (SelectObject (hdc,hBrush)) ;
1460    hBrush=CreateSolidBrush(GetNearestColor(hdc,cr));
1461    if (hBrush)
1462    {
1463     hBrush= SelectObject (hdc, hBrush) ;
1464     Rectangle (hdc, rect.right/2-1,rect.top,rect.right,rect.bottom);
1465     DeleteObject (SelectObject (hdc, hBrush)) ;
1466    }
1467   }
1468   ReleaseDC(hwnd,hdc);
1469  }
1470 }
1471
1472 /***********************************************************************
1473  *                    CC_PaintTriangle                        [internal]
1474  */
1475 static void CC_PaintTriangle(HWND hDlg,int y)
1476 {
1477  HDC hDC;
1478  long temp;
1479  int w=GetDialogBaseUnits();
1480  POINT16 points[3];
1481  int height;
1482  int oben;
1483  RECT16 rect;
1484  HWND hwnd=GetDlgItem(hDlg,0x2be);
1485  struct CCPRIVATE *lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
1486
1487  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
1488  {
1489    GetClientRect16(hwnd,&rect);
1490    height=rect.bottom;
1491    hDC=GetDC(hDlg);
1492
1493    points[0].y=rect.top;
1494    points[0].x=rect.right;           /*  |  /|  */
1495    ClientToScreen16(hwnd,points);    /*  | / |  */
1496    ScreenToClient16(hDlg,points);    /*  |<  |  */
1497    oben=points[0].y;                 /*  | \ |  */
1498                                      /*  |  \|  */
1499    temp=(long)height*(long)y;
1500    points[0].y=oben+height -temp/(long)MAXVERT;
1501    points[1].y=points[0].y+w;
1502    points[2].y=points[0].y-w;
1503    points[2].x=points[1].x=points[0].x + w;
1504
1505    if (lpp->old3angle.left)
1506     FillRect16(hDC,&lpp->old3angle,GetStockObject(WHITE_BRUSH));
1507    lpp->old3angle.left  =points[0].x;
1508    lpp->old3angle.right =points[1].x+1;
1509    lpp->old3angle.top   =points[2].y-1;
1510    lpp->old3angle.bottom=points[1].y+1;
1511    Polygon16(hDC,points,3);
1512    ReleaseDC(hDlg,hDC);
1513  }
1514 }
1515
1516
1517 /***********************************************************************
1518  *                    CC_PaintCross                           [internal]
1519  */
1520 static void CC_PaintCross(HWND hDlg,int x,int y)
1521 {
1522  HDC hDC;
1523  int w=GetDialogBaseUnits();
1524  HWND hwnd=GetDlgItem(hDlg,0x2c6);
1525  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
1526  RECT16 rect;
1527  POINT16 point;
1528  HPEN16 hPen;
1529
1530  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
1531  {
1532    GetClientRect16(hwnd,&rect);
1533    hDC=GetDC(hwnd);
1534    SelectClipRgn(hDC,CreateRectRgnIndirect16(&rect));   
1535    hPen=CreatePen(PS_SOLID,2,0);
1536    hPen=SelectObject(hDC,hPen);
1537    point.x=((long)rect.right*(long)x)/(long)MAXHORI;
1538    point.y=rect.bottom-((long)rect.bottom*(long)y)/(long)MAXVERT;
1539    if (lpp->oldcross.left!=lpp->oldcross.right)
1540      BitBlt(hDC,lpp->oldcross.left,lpp->oldcross.top,
1541              lpp->oldcross.right-lpp->oldcross.left,
1542              lpp->oldcross.bottom-lpp->oldcross.top,
1543              lpp->hdcMem,lpp->oldcross.left,lpp->oldcross.top,SRCCOPY);
1544    lpp->oldcross.left  =point.x-w-1;
1545    lpp->oldcross.right =point.x+w+1;
1546    lpp->oldcross.top   =point.y-w-1;
1547    lpp->oldcross.bottom=point.y+w+1; 
1548
1549    MoveTo(hDC,point.x-w,point.y); 
1550    LineTo(hDC,point.x+w,point.y);
1551    MoveTo(hDC,point.x,point.y-w); 
1552    LineTo(hDC,point.x,point.y+w);
1553    DeleteObject(SelectObject(hDC,hPen));
1554    ReleaseDC(hwnd,hDC);
1555  }
1556 }
1557
1558
1559 #define XSTEPS 48
1560 #define YSTEPS 24
1561
1562
1563 /***********************************************************************
1564  *                    CC_PrepareColorGraph                    [internal]
1565  */
1566 static void CC_PrepareColorGraph(HWND hDlg)    
1567 {
1568  int sdif,hdif,xdif,ydif,r,g,b,hue,sat;
1569  HWND hwnd=GetDlgItem(hDlg,0x2c6);
1570  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER);  
1571  HBRUSH hbrush;
1572  HDC hdc ;
1573  RECT16 rect,client;
1574  HCURSOR hcursor=SetCursor(LoadCursor16(0,IDC_WAIT));
1575
1576  GetClientRect16(hwnd,&client);
1577  hdc=GetDC(hwnd);
1578  lpp->hdcMem = CreateCompatibleDC(hdc);
1579  lpp->hbmMem = CreateCompatibleBitmap(hdc,client.right,client.bottom);
1580  SelectObject(lpp->hdcMem,lpp->hbmMem);
1581
1582  xdif=client.right /XSTEPS;
1583  ydif=client.bottom/YSTEPS+1;
1584  hdif=239/XSTEPS;
1585  sdif=240/YSTEPS;
1586  for(rect.left=hue=0;hue<239+hdif;hue+=hdif)
1587  {
1588   rect.right=rect.left+xdif;
1589   rect.bottom=client.bottom;
1590   for(sat=0;sat<240+sdif;sat+=sdif)
1591   {
1592    rect.top=rect.bottom-ydif;
1593    r=CC_HSLtoRGB('R',hue,sat,120);
1594    g=CC_HSLtoRGB('G',hue,sat,120);
1595    b=CC_HSLtoRGB('B',hue,sat,120);
1596    hbrush=CreateSolidBrush(RGB(r,g,b));
1597    FillRect16(lpp->hdcMem,&rect,hbrush);
1598    DeleteObject(hbrush);
1599    rect.bottom=rect.top;
1600   }
1601   rect.left=rect.right;
1602  }
1603  ReleaseDC(hwnd,hdc);
1604  SetCursor(hcursor);
1605 }
1606
1607 /***********************************************************************
1608  *                          CC_PaintColorGraph                [internal]
1609  */
1610 static void CC_PaintColorGraph(HWND hDlg)
1611 {
1612  HWND hwnd=GetDlgItem(hDlg,0x2c6);
1613  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
1614  HDC  hDC;
1615  RECT16 rect;
1616  if (IsWindowVisible(hwnd))   /* if full size */
1617  {
1618   if (!lpp->hdcMem)
1619    CC_PrepareColorGraph(hDlg);   /* should not be necessary */
1620
1621   hDC=GetDC(hwnd);
1622   GetClientRect16(hwnd,&rect);
1623   if (lpp->hdcMem)
1624     BitBlt(hDC,0,0,rect.right,rect.bottom,lpp->hdcMem,0,0,SRCCOPY);
1625   else
1626     fprintf(stderr,"choose color: hdcMem is not defined\n");
1627   ReleaseDC(hwnd,hDC);
1628  }
1629 }
1630 /***********************************************************************
1631  *                           CC_PaintLumBar                   [internal]
1632  */
1633 static void CC_PaintLumBar(HWND hDlg,int hue,int sat)
1634 {
1635  HWND hwnd=GetDlgItem(hDlg,0x2be);
1636  RECT16 rect,client;
1637  int lum,ldif,ydif,r,g,b;
1638  HBRUSH hbrush;
1639  HDC hDC;
1640
1641  if (IsWindowVisible(hwnd))
1642  {
1643   hDC=GetDC(hwnd);
1644   GetClientRect16(hwnd,&client);
1645   rect=client;
1646
1647   ldif=240/YSTEPS;
1648   ydif=client.bottom/YSTEPS+1;
1649   for(lum=0;lum<240+ldif;lum+=ldif)
1650   {
1651    rect.top=MAX(0,rect.bottom-ydif);
1652    r=CC_HSLtoRGB('R',hue,sat,lum);
1653    g=CC_HSLtoRGB('G',hue,sat,lum);
1654    b=CC_HSLtoRGB('B',hue,sat,lum);
1655    hbrush=CreateSolidBrush(RGB(r,g,b));
1656    FillRect16(hDC,&rect,hbrush);
1657    DeleteObject(hbrush);
1658    rect.bottom=rect.top;
1659   }
1660   GetClientRect16(hwnd,&rect);
1661   FrameRect16(hDC,&rect,GetStockObject(BLACK_BRUSH));
1662   ReleaseDC(hwnd,hDC);
1663  }
1664 }
1665
1666 /***********************************************************************
1667  *                             CC_EditSetRGB                  [internal]
1668  */
1669 static void CC_EditSetRGB(HWND hDlg,COLORREF cr)
1670 {
1671  char buffer[10];
1672  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
1673  int r=GetRValue(cr);
1674  int g=GetGValue(cr);
1675  int b=GetBValue(cr);
1676  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
1677  {
1678    lpp->updating=TRUE;
1679    sprintf(buffer,"%d",r);
1680    SetWindowText32A(GetDlgItem(hDlg,0x2c2),buffer);
1681    sprintf(buffer,"%d",g);
1682    SetWindowText32A(GetDlgItem(hDlg,0x2c3),buffer);
1683    sprintf(buffer,"%d",b);
1684    SetWindowText32A(GetDlgItem(hDlg,0x2c4),buffer);
1685    lpp->updating=FALSE;
1686  }
1687 }
1688
1689 /***********************************************************************
1690  *                             CC_EditSetHSL                  [internal]
1691  */
1692 static void CC_EditSetHSL(HWND hDlg,int h,int s,int l)
1693 {
1694  char buffer[10];
1695  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
1696  lpp->updating=TRUE;
1697  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
1698  {
1699    lpp->updating=TRUE;
1700    sprintf(buffer,"%d",h);
1701    SetWindowText32A(GetDlgItem(hDlg,0x2bf),buffer);
1702    sprintf(buffer,"%d",s);
1703    SetWindowText32A(GetDlgItem(hDlg,0x2c0),buffer);
1704    sprintf(buffer,"%d",l);
1705    SetWindowText32A(GetDlgItem(hDlg,0x2c1),buffer);
1706    lpp->updating=FALSE;
1707  }
1708  CC_PaintLumBar(hDlg,h,s);
1709 }
1710
1711 /***********************************************************************
1712  *                       CC_SwitchToFullSize                  [internal]
1713  */
1714 static void CC_SwitchToFullSize(HWND hDlg,COLORREF result,LPRECT16 lprect)
1715 {
1716  int i;
1717  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
1718  
1719  EnableWindow(GetDlgItem(hDlg,0x2cf),FALSE);
1720  CC_PrepareColorGraph(hDlg);
1721  for (i=0x2bf;i<0x2c5;i++)
1722    EnableWindow(GetDlgItem(hDlg,i),TRUE);
1723  for (i=0x2d3;i<0x2d9;i++)
1724    EnableWindow(GetDlgItem(hDlg,i),TRUE);
1725  EnableWindow(GetDlgItem(hDlg,0x2c9),TRUE);
1726  EnableWindow(GetDlgItem(hDlg,0x2c8),TRUE);
1727
1728  if (lprect)
1729   SetWindowPos(hDlg,NULL,0,0,lprect->right-lprect->left,
1730    lprect->bottom-lprect->top, SWP_NOMOVE|SWP_NOZORDER);
1731
1732  ShowWindow(GetDlgItem(hDlg,0x2c6),SW_SHOW);
1733  ShowWindow(GetDlgItem(hDlg,0x2be),SW_SHOW);
1734  ShowWindow(GetDlgItem(hDlg,0x2c5),SW_SHOW);
1735
1736  CC_EditSetRGB(hDlg,result);
1737  CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
1738 }
1739
1740 /***********************************************************************
1741  *                           CC_PaintPredefColorArray         [internal]
1742  */
1743 static void CC_PaintPredefColorArray(HWND hDlg,int rows,int cols)
1744 {
1745  HWND hwnd=GetDlgItem(hDlg,0x2d0);
1746  RECT16 rect;
1747  HDC  hdc;
1748  HBRUSH hBrush;
1749  int dx,dy,i,j,k;
1750
1751  GetClientRect16(hwnd,&rect);
1752  dx=rect.right/cols;
1753  dy=rect.bottom/rows;
1754  k=rect.left;
1755
1756  hdc=GetDC(hwnd);
1757  GetClientRect16 (hwnd, &rect) ;
1758
1759  for (j=0;j<rows;j++)
1760  {
1761   for (i=0;i<cols;i++)
1762   {
1763    hBrush = CreateSolidBrush(predefcolors[j][i]);
1764    if (hBrush)
1765    {
1766     hBrush = SelectObject (hdc, hBrush) ;
1767     Rectangle (hdc, rect.left,     rect.top,
1768                     rect.left+dx-DISTANCE,rect.top+dy-DISTANCE);
1769     rect.left=rect.left+dx;
1770     DeleteObject (SelectObject (hdc, hBrush)) ;
1771    }
1772   }
1773   rect.top=rect.top+dy;
1774   rect.left=k;
1775  }
1776  ReleaseDC(hwnd,hdc);
1777  /* FIXME: draw_a_focus_rect */
1778 }
1779 /***********************************************************************
1780  *                             CC_PaintUserColorArray         [internal]
1781  */
1782 static void CC_PaintUserColorArray(HWND hDlg,int rows,int cols,COLORREF* lpcr)
1783 {
1784  HWND hwnd=GetDlgItem(hDlg,0x2d1);
1785  RECT16 rect;
1786  HDC  hdc;
1787  HBRUSH hBrush;
1788  int dx,dy,i,j,k;
1789
1790  GetClientRect16(hwnd,&rect);
1791
1792  dx=rect.right/cols;
1793  dy=rect.bottom/rows;
1794  k=rect.left;
1795
1796  hdc=GetDC(hwnd);
1797  if (hdc)
1798  {
1799   for (j=0;j<rows;j++)
1800   {
1801    for (i=0;i<cols;i++)
1802    {
1803     hBrush = CreateSolidBrush(lpcr[i+j*cols]);
1804     if (hBrush)
1805     {
1806      hBrush = SelectObject (hdc, hBrush) ;
1807      Rectangle (hdc, rect.left,     rect.top,
1808                     rect.left+dx-DISTANCE,rect.top+dy-DISTANCE);
1809      rect.left=rect.left+dx;
1810      DeleteObject (SelectObject (hdc, hBrush)) ;
1811     }
1812    }
1813    rect.top=rect.top+dy;
1814    rect.left=k;
1815   }
1816   ReleaseDC(hwnd,hdc);
1817  }
1818  /* FIXME: draw_a_focus_rect */
1819 }
1820
1821
1822
1823 /***********************************************************************
1824  *                             CC_HookCallChk                 [internal]
1825  */
1826 static BOOL CC_HookCallChk(LPCHOOSECOLOR lpcc)
1827 {
1828  if (lpcc)
1829   if(lpcc->Flags & CC_ENABLEHOOK)
1830    if (lpcc->lpfnHook)
1831     return TRUE;
1832  return FALSE;
1833 }
1834
1835 /***********************************************************************
1836  *                            CC_WMInitDialog                 [internal]
1837  */
1838 static LONG CC_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam) 
1839 {
1840    int i,res;
1841    HWND hwnd;
1842    RECT16 rect;
1843    POINT16 point;
1844    struct CCPRIVATE * lpp; 
1845    
1846    dprintf_commdlg(stddeb,"ColorDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
1847    lpp=calloc(1,sizeof(struct CCPRIVATE));
1848    lpp->lpcc=(LPCHOOSECOLOR)lParam;
1849    if (lpp->lpcc->lStructSize != sizeof(CHOOSECOLOR))
1850    {
1851       EndDialog (hDlg, 0) ;
1852       return FALSE;
1853    }
1854    SetWindowLong32A(hDlg, DWL_USER, (LONG)lpp); 
1855
1856    if (!(lpp->lpcc->Flags & CC_SHOWHELP))
1857       ShowWindow(GetDlgItem(hDlg,0x40e),SW_HIDE);
1858    lpp->msetrgb=RegisterWindowMessage32A( SETRGBSTRING );
1859 #if 0
1860    cpos=MAKELONG(5,7); /* init */
1861    if (lpp->lpcc->Flags & CC_RGBINIT)
1862    {
1863      for (i=0;i<6;i++)
1864        for (j=0;j<8;j++)
1865         if (predefcolors[i][j]==lpp->lpcc->rgbResult)
1866         {
1867           cpos=MAKELONG(i,j);
1868           goto found;
1869         }
1870    }
1871    found:
1872    /* FIXME: Draw_a_focus_rect & set_init_values */
1873 #endif
1874    GetWindowRect16(hDlg,&lpp->fullsize);
1875    if (lpp->lpcc->Flags & CC_FULLOPEN || lpp->lpcc->Flags & CC_PREVENTFULLOPEN)
1876    {
1877       hwnd=GetDlgItem(hDlg,0x2cf);
1878       EnableWindow(hwnd,FALSE);
1879    }
1880    if (!(lpp->lpcc->Flags & CC_FULLOPEN) || lpp->lpcc->Flags & CC_PREVENTFULLOPEN)
1881    {
1882       rect=lpp->fullsize;
1883       res=rect.bottom-rect.top;
1884       hwnd=GetDlgItem(hDlg,0x2c6); /* cut at left border */
1885       point.x=point.y=0;
1886       ClientToScreen16(hwnd,&point);
1887       ScreenToClient16(hDlg,&point);
1888       GetClientRect16(hDlg,&rect);
1889       point.x+=GetSystemMetrics(SM_CXDLGFRAME);
1890       SetWindowPos(hDlg,NULL,0,0,point.x,res,SWP_NOMOVE|SWP_NOZORDER);
1891
1892       ShowWindow(GetDlgItem(hDlg,0x2c6),SW_HIDE);
1893       ShowWindow(GetDlgItem(hDlg,0x2c5),SW_HIDE);
1894    }
1895    else
1896       CC_SwitchToFullSize(hDlg,lpp->lpcc->rgbResult,NULL);
1897    res=TRUE;
1898    for (i=0x2bf;i<0x2c5;i++)
1899      SendMessage16(GetDlgItem(hDlg,i),EM_LIMITTEXT,3,0);      /* max 3 digits:  xyz  */
1900    if (CC_HookCallChk(lpp->lpcc))
1901       res=CallWindowProc16(lpp->lpcc->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
1902    return res;
1903 }
1904
1905 /***********************************************************************
1906  *                              CC_WMCommand                  [internal]
1907  */
1908 static LRESULT CC_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam) 
1909 {
1910     int r,g,b,i,xx;
1911     UINT cokmsg;
1912     HDC hdc;
1913     COLORREF *cr;
1914     struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
1915     dprintf_commdlg(stddeb,"CC_WMCommand wParam=%x lParam=%lx\n",wParam,lParam);
1916     switch (wParam)
1917     {
1918           case 0x2c2:  /* edit notify RGB */
1919           case 0x2c3:
1920           case 0x2c4:
1921                if (HIWORD(lParam)==EN_UPDATE && !lpp->updating)
1922                          {
1923                            i=CC_CheckDigitsInEdit(LOWORD(lParam),255);
1924                            r=GetRValue(lpp->lpcc->rgbResult);
1925                            g=GetGValue(lpp->lpcc->rgbResult);
1926                            b=GetBValue(lpp->lpcc->rgbResult);
1927                            xx=0;
1928                            switch (wParam)
1929                            {
1930                             case 0x2c2:if ((xx=(i!=r))) r=i;break;
1931                             case 0x2c3:if ((xx=(i!=g))) g=i;break;
1932                             case 0x2c4:if ((xx=(i!=b))) b=i;break;
1933                            }
1934                            if (xx) /* something has changed */
1935                            {
1936                             lpp->lpcc->rgbResult=RGB(r,g,b);
1937                             CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
1938                             lpp->h=CC_RGBtoHSL('H',r,g,b);
1939                             lpp->s=CC_RGBtoHSL('S',r,g,b);
1940                             lpp->l=CC_RGBtoHSL('L',r,g,b);
1941                             CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
1942                             CC_PaintCross(hDlg,lpp->h,lpp->s);
1943                             CC_PaintTriangle(hDlg,lpp->l);
1944                            }
1945                          }
1946                  break;
1947                  
1948           case 0x2bf:  /* edit notify HSL */
1949           case 0x2c0:
1950           case 0x2c1:
1951                if (HIWORD(lParam)==EN_UPDATE && !lpp->updating)
1952                          {
1953                            i=CC_CheckDigitsInEdit(LOWORD(lParam),wParam==0x2bf?239:240);
1954                            xx=0;
1955                            switch (wParam)
1956                            {
1957                             case 0x2bf:if ((xx=(i!=lpp->h))) lpp->h=i;break;
1958                             case 0x2c0:if ((xx=(i!=lpp->s))) lpp->s=i;break;
1959                             case 0x2c1:if ((xx=(i!=lpp->l))) lpp->l=i;break;
1960                            }
1961                            if (xx) /* something has changed */
1962                            {
1963                             r=CC_HSLtoRGB('R',lpp->h,lpp->s,lpp->l);
1964                             g=CC_HSLtoRGB('G',lpp->h,lpp->s,lpp->l);
1965                             b=CC_HSLtoRGB('B',lpp->h,lpp->s,lpp->l);
1966                             lpp->lpcc->rgbResult=RGB(r,g,b);
1967                             CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
1968                             CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
1969                             CC_PaintCross(hDlg,lpp->h,lpp->s);
1970                             CC_PaintTriangle(hDlg,lpp->l);
1971                            }
1972                          }
1973                break;
1974                
1975           case 0x2cf:
1976                CC_SwitchToFullSize(hDlg,lpp->lpcc->rgbResult,&lpp->fullsize);
1977                InvalidateRect32( hDlg, NULL, TRUE );
1978                SetFocus(GetDlgItem(hDlg,0x2bf));
1979                break;
1980
1981           case 0x2c8:    /* add colors ... column by column */
1982                cr=PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors);
1983                cr[(lpp->nextuserdef%2)*8 + lpp->nextuserdef/2]=lpp->lpcc->rgbResult;
1984                if (++lpp->nextuserdef==16)
1985                    lpp->nextuserdef=0;
1986                CC_PaintUserColorArray(hDlg,2,8,PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors));
1987                break;
1988
1989           case 0x2c9:              /* resulting color */
1990                hdc=GetDC(hDlg);
1991                lpp->lpcc->rgbResult=GetNearestColor(hdc,lpp->lpcc->rgbResult);
1992                ReleaseDC(hDlg,hdc);
1993                CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
1994                CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
1995                r=GetRValue(lpp->lpcc->rgbResult);
1996                g=GetGValue(lpp->lpcc->rgbResult);
1997                b=GetBValue(lpp->lpcc->rgbResult);
1998                lpp->h=CC_RGBtoHSL('H',r,g,b);
1999                lpp->s=CC_RGBtoHSL('S',r,g,b);
2000                lpp->l=CC_RGBtoHSL('L',r,g,b);
2001                CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
2002                CC_PaintCross(hDlg,lpp->h,lpp->s);
2003                CC_PaintTriangle(hDlg,lpp->l);
2004                break;
2005
2006           case 0x40e:           /* Help! */ /* The Beatles, 1965  ;-) */
2007                i=RegisterWindowMessage32A( HELPMSGSTRING );
2008                if (lpp->lpcc->hwndOwner)
2009                    SendMessage16(lpp->lpcc->hwndOwner,i,0,(LPARAM)lpp->lpcc);
2010                if (CC_HookCallChk(lpp->lpcc))
2011                    CallWindowProc16(lpp->lpcc->lpfnHook,hDlg,
2012                       WM_COMMAND,psh15,(LPARAM)lpp->lpcc);
2013                break;
2014
2015           case IDOK :
2016                 cokmsg=RegisterWindowMessage32A( COLOROKSTRING );
2017                 if (lpp->lpcc->hwndOwner)
2018                         if (SendMessage16(lpp->lpcc->hwndOwner,cokmsg,0,(LPARAM)lpp->lpcc))
2019                            break;    /* do NOT close */
2020
2021                 EndDialog (hDlg, 1) ;
2022                 return TRUE ;
2023         
2024           case IDCANCEL :
2025                 EndDialog (hDlg, 0) ;
2026                 return TRUE ;
2027
2028        }
2029        return FALSE;
2030 }
2031
2032 /***********************************************************************
2033  *                              CC_WMPaint                    [internal]
2034  */
2035 static LRESULT CC_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam) 
2036 {
2037     struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
2038     /* we have to paint dialog children except text and buttons */
2039  
2040     CC_PaintPredefColorArray(hDlg,6,8);
2041     CC_PaintUserColorArray(hDlg,2,8,PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors));
2042     CC_PaintColorGraph(hDlg);
2043     CC_PaintLumBar(hDlg,lpp->h,lpp->s);
2044     CC_PaintCross(hDlg,lpp->h,lpp->s);
2045     CC_PaintTriangle(hDlg,lpp->l);
2046     CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
2047
2048     /* special necessary for Wine */
2049     ValidateRect32(GetDlgItem(hDlg,0x2d0),NULL);
2050     ValidateRect32(GetDlgItem(hDlg,0x2d1),NULL);
2051     ValidateRect32(GetDlgItem(hDlg,0x2c6),NULL);
2052     ValidateRect32(GetDlgItem(hDlg,0x2be),NULL);
2053     ValidateRect32(GetDlgItem(hDlg,0x2c5),NULL);
2054     /* hope we can remove it later -->FIXME */
2055  return 0;
2056 }
2057
2058
2059 /***********************************************************************
2060  *                              CC_WMLButtonDown              [internal]
2061  */
2062 static LRESULT CC_WMLButtonDown(HWND hDlg, WPARAM wParam, LPARAM lParam) 
2063 {
2064    struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
2065    int r,g,b,i;
2066    i=0;
2067    if (CC_MouseCheckPredefColorArray(hDlg,0x2d0,6,8,lParam,&lpp->lpcc->rgbResult))
2068       i=1;
2069    else
2070       if (CC_MouseCheckUserColorArray(hDlg,0x2d1,2,8,lParam,&lpp->lpcc->rgbResult,
2071               PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors)))
2072          i=1;
2073       else
2074          if (CC_MouseCheckColorGraph(hDlg,0x2c6,&lpp->h,&lpp->s,lParam))
2075             i=2;
2076          else
2077             if (CC_MouseCheckColorGraph(hDlg,0x2be,NULL,&lpp->l,lParam))
2078                i=2;
2079    if (i==2)
2080    {
2081       r=CC_HSLtoRGB('R',lpp->h,lpp->s,lpp->l);
2082       g=CC_HSLtoRGB('G',lpp->h,lpp->s,lpp->l);
2083       b=CC_HSLtoRGB('B',lpp->h,lpp->s,lpp->l);
2084       lpp->lpcc->rgbResult=RGB(r,g,b);
2085    }
2086    if (i==1)
2087    {
2088       r=GetRValue(lpp->lpcc->rgbResult);
2089       g=GetGValue(lpp->lpcc->rgbResult);
2090       b=GetBValue(lpp->lpcc->rgbResult);
2091       lpp->h=CC_RGBtoHSL('H',r,g,b);
2092       lpp->s=CC_RGBtoHSL('S',r,g,b);
2093       lpp->l=CC_RGBtoHSL('L',r,g,b);
2094    }
2095    if (i)
2096    {
2097       CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
2098       CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
2099       CC_PaintCross(hDlg,lpp->h,lpp->s);
2100       CC_PaintTriangle(hDlg,lpp->l);
2101       CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
2102       return TRUE;
2103    }
2104    return FALSE;
2105 }
2106
2107 /***********************************************************************
2108  *           ColorDlgProc   (COMMDLG.8)
2109  */
2110 LRESULT ColorDlgProc(HWND hDlg, UINT message,
2111                          UINT wParam, LONG lParam)
2112 {
2113  int res;
2114  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
2115  if (message!=WM_INITDIALOG)
2116  {
2117   if (!lpp)
2118      return FALSE;
2119   res=0;
2120   if (CC_HookCallChk(lpp->lpcc))
2121      res=CallWindowProc16(lpp->lpcc->lpfnHook,hDlg,message,wParam,lParam);
2122   if (res)
2123      return res;
2124  }
2125
2126  /* FIXME: SetRGB message
2127  if (message && message==msetrgb)
2128     return HandleSetRGB(hDlg,lParam);
2129  */
2130
2131  switch (message)
2132         {
2133           case WM_INITDIALOG:
2134                         return CC_WMInitDialog(hDlg,wParam,lParam);
2135           case WM_NCDESTROY:
2136                         DeleteDC(lpp->hdcMem); 
2137                         DeleteObject(lpp->hbmMem); 
2138                         free(lpp);
2139                         SetWindowLong32A(hDlg, DWL_USER, 0L); /* we don't need it anymore */
2140                         break;
2141           case WM_COMMAND:
2142                         if (CC_WMCommand(hDlg, wParam, lParam))
2143                            return TRUE;
2144                         break;     
2145           case WM_PAINT:
2146                         CC_WMPaint(hDlg, wParam, lParam);
2147                         break;
2148           case WM_LBUTTONDBLCLK:
2149                         if (CC_MouseCheckResultWindow(hDlg,lParam))
2150                           return TRUE;
2151                         break;
2152           case WM_MOUSEMOVE:  /* FIXME: calculate new hue,sat,lum (if in color graph) */
2153                         break;
2154           case WM_LBUTTONUP:  /* FIXME: ClipCursor off (if in color graph)*/
2155                         break;
2156           case WM_LBUTTONDOWN:/* FIXME: ClipCursor on  (if in color graph)*/
2157                         if (CC_WMLButtonDown(hDlg, wParam, lParam))
2158                            return TRUE;
2159                         break;     
2160         }
2161      return FALSE ;
2162 }
2163
2164
2165
2166 /***********************************************************************
2167  *                        ChooseFont   (COMMDLG.15)     
2168  */
2169 BOOL ChooseFont(LPCHOOSEFONT lpChFont)
2170 {
2171     HINSTANCE hInst;
2172     HANDLE hDlgTmpl, hResInfo;
2173     BOOL bRet;
2174
2175     dprintf_commdlg(stddeb,"ChooseFont\n");
2176     if (!lpChFont) return FALSE;    
2177     if (lpChFont->Flags & CF_ENABLETEMPLATEHANDLE) hDlgTmpl = lpChFont->hInstance;
2178     else if (lpChFont->Flags & CF_ENABLETEMPLATE)
2179     {
2180         if (!(hResInfo = FindResource16(lpChFont->hInstance,
2181                                         lpChFont->lpTemplateName, RT_DIALOG)))
2182         {
2183             CommDlgLastError = CDERR_FINDRESFAILURE;
2184             return FALSE;
2185         }
2186         hDlgTmpl = LoadResource16( lpChFont->hInstance, hResInfo );
2187     }
2188     else hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_CHOOSE_FONT );
2189     if (!hDlgTmpl)
2190     {
2191         CommDlgLastError = CDERR_LOADRESFAILURE;
2192         return FALSE;
2193     }
2194     hInst = WIN_GetWindowInstance( lpChFont->hwndOwner );
2195     bRet = DialogBoxIndirectParam16( hInst, hDlgTmpl, lpChFont->hwndOwner,
2196                       (DLGPROC16)MODULE_GetWndProcEntry16("FormatCharDlgProc"),
2197                       (DWORD)lpChFont );
2198     if (!(lpChFont->Flags & CF_ENABLETEMPLATEHANDLE))
2199     {
2200         if (lpChFont->Flags & CF_ENABLETEMPLATE) FreeResource16( hDlgTmpl );
2201         else SYSRES_FreeResource( hDlgTmpl );
2202     }
2203     return bRet;
2204 }
2205
2206
2207 #define TEXT_EXTRAS 4
2208 #define TEXT_COLORS 16
2209
2210 static const COLORREF textcolors[TEXT_COLORS]=
2211 {
2212  0x00000000L,0x00000080L,0x00008000L,0x00008080L,
2213  0x00800000L,0x00800080L,0x00808000L,0x00808080L,
2214  0x00c0c0c0L,0x000000ffL,0x0000ff00L,0x0000ffffL,
2215  0x00ff0000L,0x00ff00ffL,0x00ffff00L,0x00FFFFFFL
2216 };
2217
2218 /***********************************************************************
2219  *                          CFn_HookCallChk                 [internal]
2220  */
2221 static BOOL CFn_HookCallChk(LPCHOOSEFONT lpcf)
2222 {
2223  if (lpcf)
2224   if(lpcf->Flags & CF_ENABLEHOOK)
2225    if (lpcf->lpfnHook)
2226     return TRUE;
2227  return FALSE;
2228 }
2229
2230
2231 /***********************************************************************
2232  *                FontFamilyEnumProc                       (COMMDLG.19)
2233  */
2234 INT16 FontFamilyEnumProc( SEGPTR logfont, SEGPTR metrics,
2235                           UINT16 nFontType, LPARAM lParam )
2236 {
2237   int i;
2238   WORD w;
2239   HWND hwnd=LOWORD(lParam);
2240   HWND hDlg=GetParent(hwnd);
2241   LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong32A(hDlg, DWL_USER); 
2242   LOGFONT16 *lplf = (LOGFONT16 *)PTR_SEG_TO_LIN( logfont );
2243
2244   dprintf_commdlg(stddeb,"FontFamilyEnumProc: font=%s (nFontType=%d)\n",
2245                         lplf->lfFaceName,nFontType);
2246
2247   if (lpcf->Flags & CF_FIXEDPITCHONLY)
2248    if (!(lplf->lfPitchAndFamily & FIXED_PITCH))
2249      return 1;
2250   if (lpcf->Flags & CF_ANSIONLY)
2251    if (lplf->lfCharSet != ANSI_CHARSET)
2252      return 1;
2253   if (lpcf->Flags & CF_TTONLY)
2254    if (!(nFontType & 0x0004))   /* this means 'TRUETYPE_FONTTYPE' */
2255      return 1;   
2256
2257   i=SendMessage16(hwnd,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(lplf->lfFaceName));
2258   if (i!=CB_ERR)
2259   {
2260     w=(lplf->lfCharSet << 8) | lplf->lfPitchAndFamily;
2261     SendMessage16(hwnd, CB_SETITEMDATA,i,MAKELONG(nFontType,w));
2262     return 1 ;        /* store some important font information */
2263   }
2264   else
2265     return 0;
2266 }
2267
2268 /*************************************************************************
2269  *              SetFontStylesToCombo2                           [internal]
2270  *
2271  * Fill font style information into combobox  (without using font.c directly)
2272  */
2273 static int SetFontStylesToCombo2(HWND hwnd, HDC hdc, LPLOGFONT16 lplf,
2274                                  LPTEXTMETRIC16 lptm)
2275 {
2276    #define FSTYLES 4
2277    struct FONTSTYLE
2278           { int italic; 
2279             int weight;
2280             char stname[20]; };
2281    static struct FONTSTYLE fontstyles[FSTYLES]={ 
2282           { 0,FW_NORMAL,"Regular"},{0,FW_BOLD,"Bold"},
2283           { 1,FW_NORMAL,"Italic"}, {1,FW_BOLD,"Bold Italic"}};
2284    HFONT hf;                      
2285    int i,j;
2286
2287    for (i=0;i<FSTYLES;i++)
2288    {
2289      lplf->lfItalic=fontstyles[i].italic;
2290      lplf->lfWeight=fontstyles[i].weight;
2291      hf=CreateFontIndirect16(lplf);
2292      hf=SelectObject(hdc,hf);
2293      GetTextMetrics16(hdc,lptm);
2294      hf=SelectObject(hdc,hf);
2295      DeleteObject(hf);
2296
2297      if (lptm->tmWeight==fontstyles[i].weight &&
2298          lptm->tmItalic==fontstyles[i].italic)    /* font successful created ? */
2299      {
2300        j=SendMessage16(hwnd,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(fontstyles[i].stname));
2301        if (j==CB_ERR) return 1;
2302        j=SendMessage16(hwnd, CB_SETITEMDATA, j, 
2303                                  MAKELONG(fontstyles[i].weight,fontstyles[i].italic));
2304        if (j==CB_ERR) return 1;                                 
2305      }
2306    }  
2307   return 0;
2308  }
2309
2310 /*************************************************************************
2311  *              SetFontSizesToCombo3                           [internal]
2312  */
2313 static int SetFontSizesToCombo3(HWND hwnd, LPLOGFONT16 lplf, LPCHOOSEFONT lpcf)
2314 {
2315   int sizes[]={8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72,0};
2316   int h,i,j;
2317   char buffer[20];
2318   
2319   for (i=0;sizes[i] && !lplf->lfHeight;i++)
2320   {
2321    h=lplf->lfHeight ? lplf->lfHeight : sizes[i];
2322
2323    if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
2324            ((lpcf->Flags & CF_LIMITSIZE) && (h >= lpcf->nSizeMin) && (h <= lpcf->nSizeMax)))
2325    {
2326       sprintf(buffer,"%2d",h);
2327       j=SendMessage16(hwnd,CB_FINDSTRING,-1,(LPARAM)MAKE_SEGPTR(buffer));
2328       if (j==CB_ERR)
2329       {
2330         j=SendMessage16(hwnd,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
2331         if (j==CB_ERR) return 1;
2332         j=SendMessage16(hwnd, CB_SETITEMDATA, j, h); 
2333         if (j==CB_ERR) return 1;
2334       }
2335    }  
2336   }  
2337  return 0;
2338 }
2339
2340
2341 /***********************************************************************
2342  *                 FontStyleEnumProc                     (COMMDLG.18)
2343  */
2344 INT16 FontStyleEnumProc( SEGPTR logfont, SEGPTR metrics,
2345                          UINT16 nFontType, LPARAM lParam )
2346 {
2347   HWND hcmb2=LOWORD(lParam);
2348   HWND hcmb3=HIWORD(lParam);
2349   HWND hDlg=GetParent(hcmb3);
2350   LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong32A(hDlg, DWL_USER); 
2351   LOGFONT16 *lplf = (LOGFONT16 *)PTR_SEG_TO_LIN(logfont);
2352   TEXTMETRIC16 *lptm = (TEXTMETRIC16 *)PTR_SEG_TO_LIN(metrics);
2353   int i;
2354   
2355   dprintf_commdlg(stddeb,"FontStyleEnumProc: (nFontType=%d)\n",nFontType);
2356   dprintf_commdlg(stddeb,"  %s h=%d w=%d e=%d o=%d wg=%d i=%d u=%d s=%d ch=%d op=%d cp=%d q=%d pf=%xh\n",
2357         lplf->lfFaceName,lplf->lfHeight,lplf->lfWidth,lplf->lfEscapement,lplf->lfOrientation,
2358         lplf->lfWeight,lplf->lfItalic,lplf->lfUnderline,lplf->lfStrikeOut,lplf->lfCharSet,
2359         lplf->lfOutPrecision,lplf->lfClipPrecision,lplf->lfQuality,lplf->lfPitchAndFamily);
2360
2361   if (SetFontSizesToCombo3(hcmb3, lplf ,lpcf))
2362    return 0;
2363
2364   if (!SendMessage16(hcmb2,CB_GETCOUNT,0,0))
2365   {
2366        HDC hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
2367        i=SetFontStylesToCombo2(hcmb2,hdc,lplf,lptm);
2368        if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
2369          ReleaseDC(hDlg,hdc);
2370        if (i)
2371         return 0;  
2372   }
2373   return 1 ;
2374 }
2375
2376
2377 /***********************************************************************
2378  *           CFn_WMInitDialog                            [internal]
2379  */
2380 LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
2381 {
2382   HDC hdc;
2383   int i,j,res,init=0;
2384   long l;
2385   LPLOGFONT16 lpxx;
2386   HCURSOR hcursor=SetCursor(LoadCursor16(0,IDC_WAIT));
2387   LPCHOOSEFONT lpcf;
2388
2389   SetWindowLong32A(hDlg, DWL_USER, lParam); 
2390   lpcf=(LPCHOOSEFONT)lParam;
2391   lpxx=PTR_SEG_TO_LIN(lpcf->lpLogFont);
2392   dprintf_commdlg(stddeb,"FormatCharDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
2393
2394   if (lpcf->lStructSize != sizeof(CHOOSEFONT))
2395   {
2396     dprintf_commdlg(stddeb,"WM_INITDIALOG: structure size failure !!!\n");
2397     EndDialog (hDlg, 0); 
2398     return FALSE;
2399   }
2400   if (!hBitmapTT)
2401     hBitmapTT = LoadBitmap16(0, MAKEINTRESOURCE(OBM_TRTYPE));
2402                          
2403   if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow(lpcf->hwndOwner))
2404     ShowWindow(GetDlgItem(hDlg,pshHelp),SW_HIDE);
2405   if (!(lpcf->Flags & CF_APPLY))
2406     ShowWindow(GetDlgItem(hDlg,psh3),SW_HIDE);
2407   if (lpcf->Flags & CF_EFFECTS)
2408   {
2409     for (res=1,i=0;res && i<TEXT_COLORS;i++)
2410     {
2411       /* FIXME: load color name from resource:  res=LoadString(...,i+....,buffer,.....); */
2412       j=SendDlgItemMessage16(hDlg,cmb4,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR("[color name]"));
2413       SendDlgItemMessage16(hDlg,cmb4, CB_SETITEMDATA,j,textcolors[j]);
2414       /* look for a fitting value in color combobox */
2415       if (textcolors[j]==lpcf->rgbColors)
2416         SendDlgItemMessage16(hDlg,cmb4, CB_SETCURSEL,j,0);
2417     }
2418   }
2419   else
2420   {
2421     ShowWindow(GetDlgItem(hDlg,cmb4),SW_HIDE);
2422     ShowWindow(GetDlgItem(hDlg,chx1),SW_HIDE);
2423     ShowWindow(GetDlgItem(hDlg,chx2),SW_HIDE);
2424     ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
2425     ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
2426   }
2427   hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
2428   if (hdc)
2429   {
2430     if (!EnumFontFamilies (hdc, NULL,FontFamilyEnumProc,(LPARAM)GetDlgItem(hDlg,cmb1)))
2431       dprintf_commdlg(stddeb,"WM_INITDIALOG: EnumFontFamilies returns 0\n");
2432     if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
2433     {
2434       /* look for fitting font name in combobox1 */
2435       j=SendDlgItemMessage16(hDlg,cmb1,CB_FINDSTRING,-1,(LONG)lpxx->lfFaceName);
2436       if (j!=CB_ERR)
2437       {
2438         SendDlgItemMessage16(hDlg,cmb1,CB_SETCURSEL,j,0);
2439         SendMessage16(hDlg,WM_COMMAND,cmb1,MAKELONG(GetDlgItem(hDlg,cmb1),CBN_SELCHANGE));
2440         init=1;
2441         /* look for fitting font style in combobox2 */
2442         l=MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD:FW_NORMAL,lpxx->lfItalic !=0);
2443         for (i=0;i<TEXT_EXTRAS;i++)
2444         {
2445           if (l==SendDlgItemMessage16(hDlg,cmb2, CB_GETITEMDATA,i,0))
2446             SendDlgItemMessage16(hDlg,cmb2,CB_SETCURSEL,i,0);
2447         }
2448       
2449         /* look for fitting font size in combobox3 */
2450         j=SendDlgItemMessage16(hDlg,cmb3,CB_GETCOUNT,0,0);
2451         for (i=0;i<j;i++)
2452         {
2453           if (lpxx->lfHeight==(int)SendDlgItemMessage16(hDlg,cmb3, CB_GETITEMDATA,i,0))
2454             SendDlgItemMessage16(hDlg,cmb3,CB_SETCURSEL,i,0);
2455         }
2456       }
2457       if (!init)
2458       {
2459         SendDlgItemMessage16(hDlg,cmb1,CB_SETCURSEL,0,0);
2460         SendMessage16(hDlg,WM_COMMAND,cmb1,MAKELONG(GetDlgItem(hDlg,cmb1),CBN_SELCHANGE));      
2461       }
2462     }
2463     if (lpcf->Flags & CF_USESTYLE && lpcf->lpszStyle)
2464     {
2465       j=SendDlgItemMessage16(hDlg,cmb2,CB_FINDSTRING,-1,(LONG)lpcf->lpszStyle);
2466       if (j!=CB_ERR)
2467       {
2468         j=SendDlgItemMessage16(hDlg,cmb2,CB_SETCURSEL,j,0);
2469         SendMessage16(hDlg,WM_COMMAND,cmb2,MAKELONG(GetDlgItem(hDlg,cmb2),CBN_SELCHANGE));
2470       }
2471     }
2472   }
2473   else
2474   {
2475     dprintf_commdlg(stddeb,"WM_INITDIALOG: HDC failure !!!\n");
2476     EndDialog (hDlg, 0); 
2477     return FALSE;
2478   }
2479
2480   if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
2481     ReleaseDC(hDlg,hdc);
2482   res=TRUE;
2483   if (CFn_HookCallChk(lpcf))
2484     res=CallWindowProc16(lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
2485   SetCursor(hcursor);   
2486   return res;
2487 }
2488
2489
2490 /***********************************************************************
2491  *           CFn_WMMeasureItem                           [internal]
2492  */
2493 LRESULT CFn_WMMeasureItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
2494 {
2495   BITMAP16 bm;
2496   LPMEASUREITEMSTRUCT16 lpmi=PTR_SEG_TO_LIN((LPMEASUREITEMSTRUCT16)lParam);
2497   if (!hBitmapTT)
2498     hBitmapTT = LoadBitmap16(0, MAKEINTRESOURCE(OBM_TRTYPE));
2499   GetObject16( hBitmapTT, sizeof(bm), &bm );
2500   lpmi->itemHeight=bm.bmHeight;
2501   /* FIXME: use MAX of bm.bmHeight and tm.tmHeight .*/
2502   return 0;
2503 }
2504
2505
2506 /***********************************************************************
2507  *           CFn_WMDrawItem                              [internal]
2508  */
2509 LRESULT CFn_WMDrawItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
2510 {
2511   HBRUSH hBrush;
2512   char buffer[40];
2513   BITMAP16 bm;
2514   COLORREF cr;
2515   RECT16 rect;
2516 #if 0  
2517   HDC hMemDC;
2518   int nFontType;
2519   HBITMAP hBitmap; /* for later TT usage */
2520 #endif  
2521   LPDRAWITEMSTRUCT16 lpdi = (LPDRAWITEMSTRUCT16)PTR_SEG_TO_LIN(lParam);
2522
2523   if (lpdi->itemID == 0xFFFF)                   /* got no items */
2524     DrawFocusRect16(lpdi->hDC, &lpdi->rcItem);
2525   else
2526   {
2527    if (lpdi->CtlType == ODT_COMBOBOX)
2528    {
2529      hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
2530      SelectObject(lpdi->hDC, hBrush);
2531      FillRect16(lpdi->hDC, &lpdi->rcItem, hBrush);
2532    }
2533    else
2534      return TRUE;       /* this should never happen */
2535
2536    rect=lpdi->rcItem;
2537    switch (lpdi->CtlID)
2538    {
2539     case cmb1:  /* dprintf_commdlg(stddeb,"WM_Drawitem cmb1\n"); */
2540                 SendMessage16(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
2541                         (LPARAM)MAKE_SEGPTR(buffer));             
2542                 GetObject16( hBitmapTT, sizeof(bm), &bm );
2543                 TextOut16(lpdi->hDC, lpdi->rcItem.left + bm.bmWidth + 10,
2544                           lpdi->rcItem.top, buffer, lstrlen16(buffer));
2545 #if 0
2546                 nFontType = SendMessage16(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
2547                   /* FIXME: draw bitmap if truetype usage */
2548                 if (nFontType&TRUETYPE_FONTTYPE)
2549                 {
2550                   hMemDC = CreateCompatibleDC(lpdi->hDC);
2551                   hBitmap = SelectObject(hMemDC, hBitmapTT);
2552                   BitBlt(lpdi->hDC, lpdi->rcItem.left, lpdi->rcItem.top,
2553                         bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
2554                   SelectObject(hMemDC, hBitmap);
2555                   DeleteDC(hMemDC);
2556                 }
2557 #endif
2558                 break;
2559     case cmb2:
2560     case cmb3:  /* dprintf_commdlg(stddeb,"WM_DRAWITEN cmb2,cmb3\n"); */
2561                 SendMessage16(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
2562                         (LPARAM)MAKE_SEGPTR(buffer));
2563                 TextOut16(lpdi->hDC, lpdi->rcItem.left,
2564                           lpdi->rcItem.top, buffer, lstrlen16(buffer));
2565                 break;
2566
2567     case cmb4:  /* dprintf_commdlg(stddeb,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
2568                 SendMessage16(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
2569                     (LPARAM)MAKE_SEGPTR(buffer));
2570                 TextOut16(lpdi->hDC, lpdi->rcItem.left +  25+5,
2571                           lpdi->rcItem.top, buffer, lstrlen16(buffer));
2572                 cr = SendMessage16(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
2573                 hBrush = CreateSolidBrush(cr);
2574                 if (hBrush)
2575                 {
2576                   hBrush = SelectObject (lpdi->hDC, hBrush) ;
2577                   rect.right=rect.left+25;
2578                   rect.top++;
2579                   rect.left+=5;
2580                   rect.bottom--;
2581                   Rectangle(lpdi->hDC,rect.left,rect.top,rect.right,rect.bottom);
2582                   DeleteObject (SelectObject (lpdi->hDC, hBrush)) ;
2583                 }
2584                 rect=lpdi->rcItem;
2585                 rect.left+=25+5;
2586                 break;
2587
2588     default:    return TRUE;    /* this should never happen */
2589    }
2590    if (lpdi->itemState ==ODS_SELECTED)
2591      InvertRect16(lpdi->hDC, &rect);
2592  }
2593  return TRUE;
2594 }
2595
2596 /***********************************************************************
2597  *           CFn_WMCtlColor                              [internal]
2598  */
2599 LRESULT CFn_WMCtlColor(HWND hDlg, WPARAM wParam, LPARAM lParam)
2600 {
2601   LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong32A(hDlg, DWL_USER); 
2602
2603   if (lpcf->Flags & CF_EFFECTS)
2604    if (HIWORD(lParam)==CTLCOLOR_STATIC && GetDlgCtrlID(LOWORD(lParam))==stc6)
2605    {
2606      SetTextColor(wParam,lpcf->rgbColors);
2607      return GetStockObject(WHITE_BRUSH);
2608    }
2609   return 0;
2610 }
2611
2612 /***********************************************************************
2613  *           CFn_WMCommand                               [internal]
2614  */
2615 LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
2616 {
2617   char buffer[200];
2618   HFONT hFont/*,hFontOld*/;
2619   int i,j;
2620   long l;
2621   HDC hdc;
2622   LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong32A(hDlg, DWL_USER); 
2623   LPLOGFONT16 lpxx=PTR_SEG_TO_LIN(lpcf->lpLogFont);
2624   
2625   dprintf_commdlg(stddeb,"FormatCharDlgProc // WM_COMMAND lParam=%08lX\n", lParam);
2626   switch (wParam)
2627   {
2628         case cmb1:if (HIWORD(lParam)==CBN_SELCHANGE)
2629                   {
2630                     hdc=(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
2631                     if (hdc)
2632                     {
2633                       SendDlgItemMessage16(hDlg,cmb2,CB_RESETCONTENT,0,0); 
2634                       SendDlgItemMessage16(hDlg,cmb3,CB_RESETCONTENT,0,0);
2635                       i=SendDlgItemMessage16(hDlg,cmb1,CB_GETCURSEL,0,0);
2636                       if (i!=CB_ERR)
2637                       {
2638                         HCURSOR hcursor=SetCursor(LoadCursor16(0,IDC_WAIT));
2639                         SendDlgItemMessage16(hDlg,cmb1,CB_GETLBTEXT,i,(LPARAM)MAKE_SEGPTR(buffer));
2640                         dprintf_commdlg(stddeb,"WM_COMMAND/cmb1 =>%s\n",buffer);
2641                         EnumFontFamilies(hdc,buffer,FontStyleEnumProc,
2642                              MAKELONG(GetDlgItem(hDlg,cmb2),GetDlgItem(hDlg,cmb3)));
2643                         SetCursor(hcursor);        
2644                       }
2645                       if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
2646                         ReleaseDC(hDlg,hdc);
2647                     }
2648                     else
2649                     {
2650                       dprintf_commdlg(stddeb,"WM_COMMAND: HDC failure !!!\n");
2651                       EndDialog (hDlg, 0); 
2652                       return TRUE;
2653                     }
2654                   }
2655         case chx1:
2656         case chx2:
2657         case cmb2:
2658         case cmb3:if (HIWORD(lParam)==CBN_SELCHANGE || HIWORD(lParam)== BN_CLICKED )
2659                   {
2660                     dprintf_commdlg(stddeb,"WM_COMMAND/cmb2,3 =%08lX\n", lParam);
2661                     i=SendDlgItemMessage16(hDlg,cmb1,CB_GETCURSEL,0,0);
2662                     if (i==CB_ERR)
2663                       i=GetDlgItemText32A( hDlg, cmb1, buffer, sizeof(buffer) );
2664                     else
2665                     {
2666                       SendDlgItemMessage16(hDlg,cmb1,CB_GETLBTEXT,i,(LPARAM)MAKE_SEGPTR(buffer));
2667                       l=SendDlgItemMessage16(hDlg,cmb1,CB_GETITEMDATA,i,0);
2668                       j=HIWORD(l);
2669                       lpcf->nFontType = LOWORD(l);
2670                       /* FIXME:   lpcf->nFontType |= ....  SIMULATED_FONTTYPE and so */
2671                       /* same value reported to the EnumFonts
2672                        call back with the extra FONTTYPE_...  bits added */
2673                       lpxx->lfPitchAndFamily=j&0xff;
2674                       lpxx->lfCharSet=j>>8;
2675                     }
2676                     strcpy(lpxx->lfFaceName,buffer);
2677                     i=SendDlgItemMessage16(hDlg,cmb2,CB_GETCURSEL,0,0);
2678                     if (i!=CB_ERR)
2679                     {
2680                       l=SendDlgItemMessage16(hDlg,cmb2,CB_GETITEMDATA,i,0);
2681                       if (0!=(lpxx->lfItalic=HIWORD(l)))
2682                         lpcf->nFontType |= ITALIC_FONTTYPE;
2683                       if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
2684                         lpcf->nFontType |= BOLD_FONTTYPE;
2685                     }
2686                     i=SendDlgItemMessage16(hDlg,cmb3,CB_GETCURSEL,0,0);
2687                     if (i!=CB_ERR)
2688                       lpxx->lfHeight=-LOWORD(SendDlgItemMessage16(hDlg,cmb3,CB_GETITEMDATA,i,0));
2689                     else
2690                       lpxx->lfHeight=0;
2691                     lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
2692                     lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
2693                     lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
2694                     lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
2695                     lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
2696                     lpxx->lfQuality=DEFAULT_QUALITY;
2697                     lpcf->iPointSize= -10*lpxx->lfHeight;
2698
2699                     hFont=CreateFontIndirect16(lpxx);
2700                     if (hFont)
2701                       SendDlgItemMessage16(hDlg,stc6,WM_SETFONT,hFont,TRUE);
2702                     /* FIXME: Delete old font ...? */  
2703                   }
2704                   break;
2705
2706         case cmb4:i=SendDlgItemMessage16(hDlg,cmb4,CB_GETCURSEL,0,0);
2707                   if (i!=CB_ERR)
2708                   {
2709                    lpcf->rgbColors=textcolors[i];
2710                    InvalidateRect32( GetDlgItem(hDlg,stc6), NULL, 0 );
2711                   }
2712                   break;
2713         
2714         case psh15:i=RegisterWindowMessage32A( HELPMSGSTRING );
2715                   if (lpcf->hwndOwner)
2716                     SendMessage16(lpcf->hwndOwner,i,0,(LPARAM)lpcf);
2717                   if (CFn_HookCallChk(lpcf))
2718                     CallWindowProc16(lpcf->lpfnHook,hDlg,WM_COMMAND,psh15,(LPARAM)lpcf);
2719                   break;
2720
2721         case IDOK:if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
2722                      ( (lpcf->Flags & CF_LIMITSIZE) && 
2723                       (-lpxx->lfHeight >= lpcf->nSizeMin) && 
2724                       (-lpxx->lfHeight <= lpcf->nSizeMax)))
2725                      EndDialog(hDlg, TRUE);
2726                   else
2727                   {
2728                    sprintf(buffer,"Select a font size among %d and %d points.",lpcf->nSizeMin,lpcf->nSizeMax);
2729                    MessageBox(hDlg,buffer,NULL,MB_OK);
2730                   } 
2731                   return(TRUE);
2732         case IDCANCEL:EndDialog(hDlg, FALSE);
2733                   return(TRUE);
2734         }
2735       return(FALSE);
2736 }
2737
2738
2739 /***********************************************************************
2740  *           FormatCharDlgProc   (COMMDLG.16)
2741              FIXME: 1. some strings are "hardcoded", but it's better load from sysres
2742                     2. some CF_.. flags are not supported
2743                     3. some TType extensions
2744  */
2745 LRESULT FormatCharDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
2746 {
2747   LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong32A(hDlg, DWL_USER);  
2748   if (message!=WM_INITDIALOG)
2749   {
2750    int res=0;
2751    if (!lpcf)
2752       return FALSE;
2753    if (CFn_HookCallChk(lpcf))
2754      res=CallWindowProc16(lpcf->lpfnHook,hDlg,message,wParam,lParam);
2755    if (res)
2756     return res;
2757   }
2758   else
2759     return CFn_WMInitDialog(hDlg,wParam,lParam);
2760   switch (message)
2761     {
2762       case WM_MEASUREITEM:
2763                         return CFn_WMMeasureItem(hDlg,wParam,lParam);
2764       case WM_DRAWITEM:
2765                         return CFn_WMDrawItem(hDlg,wParam,lParam);
2766       case WM_CTLCOLOR:
2767                         return CFn_WMCtlColor(hDlg,wParam,lParam);
2768       case WM_COMMAND:
2769                         return CFn_WMCommand(hDlg,wParam,lParam);
2770       case WM_CHOOSEFONT_GETLOGFONT: 
2771                          dprintf_commdlg(stddeb,
2772                           "FormatCharDlgProc // WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
2773                         /* FIXME:  current logfont back to caller */
2774                         break;
2775     }
2776   return FALSE;
2777 }