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