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