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