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