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