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