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