Fixed GetOpenFileName when called with both OFN_ALLOWMULTISELECT and
[wine] / dlls / commdlg / colordlg.c
1 /*
2  * COMMDLG - File Dialog
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 "ldt.h"
15 #include "heap.h"
16 #include "commdlg.h"
17 #include "resource.h"
18 #include "dialog.h"
19 #include "dlgs.h"
20 #include "module.h"
21 #include "debugtools.h"
22 #include "winproc.h"
23 #include "cderr.h"
24
25 DEFAULT_DEBUG_CHANNEL(commdlg)
26
27 #include "cdlg.h"
28
29 /***********************************************************************
30  *           ChooseColor   (COMMDLG.5)
31  */
32 BOOL16 WINAPI ChooseColor16(LPCHOOSECOLOR16 lpChCol)
33 {
34     HINSTANCE16 hInst;
35     HANDLE16 hDlgTmpl = 0;
36     BOOL16 bRet = FALSE, win32Format = FALSE;
37     LPCVOID template;
38     HWND hwndDialog;
39
40     TRACE("ChooseColor\n");
41     if (!lpChCol) return FALSE;    
42
43     if (lpChCol->Flags & CC_ENABLETEMPLATEHANDLE)
44     {
45         if (!(template = LockResource16( lpChCol->hInstance )))
46         {
47             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
48             return FALSE;
49         }
50     }
51     else if (lpChCol->Flags & CC_ENABLETEMPLATE)
52     {
53         HANDLE16 hResInfo;
54         if (!(hResInfo = FindResource16(lpChCol->hInstance,
55                                         lpChCol->lpTemplateName,
56                                         RT_DIALOG16)))
57         {
58             COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
59             return FALSE;
60         }
61         if (!(hDlgTmpl = LoadResource16( lpChCol->hInstance, hResInfo )) ||
62             !(template = LockResource16( hDlgTmpl )))
63         {
64             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
65             return FALSE;
66         }
67     }
68     else
69     {
70         HANDLE hResInfo, hDlgTmpl;
71         if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "CHOOSE_COLOR", RT_DIALOGA)))
72         {
73             COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
74             return FALSE;
75         }
76         if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
77             !(template = LockResource( hDlgTmpl )))
78         {
79             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
80             return FALSE;
81         }
82         win32Format = TRUE;
83     }
84
85     hInst = GetWindowLongA( lpChCol->hwndOwner, GWL_HINSTANCE );
86     hwndDialog = DIALOG_CreateIndirect( hInst, template, win32Format,
87                                         lpChCol->hwndOwner,
88                            (DLGPROC16)MODULE_GetWndProcEntry16("ColorDlgProc"),
89                                         (DWORD)lpChCol, WIN_PROC_16 );
90     if (hwndDialog) bRet = DIALOG_DoDialogBox( hwndDialog, lpChCol->hwndOwner);
91     if (hDlgTmpl) FreeResource16( hDlgTmpl );
92
93     return bRet;
94 }
95
96
97 static const COLORREF predefcolors[6][8]=
98 {
99  { 0x008080FFL, 0x0080FFFFL, 0x0080FF80L, 0x0080FF00L,
100    0x00FFFF80L, 0x00FF8000L, 0x00C080FFL, 0x00FF80FFL },
101  { 0x000000FFL, 0x0000FFFFL, 0x0000FF80L, 0x0040FF00L,
102    0x00FFFF00L, 0x00C08000L, 0x00C08080L, 0x00FF00FFL },
103
104  { 0x00404080L, 0x004080FFL, 0x0000FF00L, 0x00808000L,
105    0x00804000L, 0x00FF8080L, 0x00400080L, 0x008000FFL },
106  { 0x00000080L, 0x000080FFL, 0x00008000L, 0x00408000L,
107    0x00FF0000L, 0x00A00000L, 0x00800080L, 0x00FF0080L },
108
109  { 0x00000040L, 0x00004080L, 0x00004000L, 0x00404000L,
110    0x00800000L, 0x00400000L, 0x00400040L, 0x00800040L },
111  { 0x00000000L, 0x00008080L, 0x00408080L, 0x00808080L,
112    0x00808040L, 0x00C0C0C0L, 0x00400040L, 0x00FFFFFFL },
113 };
114
115 struct CCPRIVATE
116 {
117  LPCHOOSECOLOR16 lpcc;  /* points to public known data structure */
118  int nextuserdef;     /* next free place in user defined color array */
119  HDC16 hdcMem;        /* color graph used for BitBlt() */
120  HBITMAP16 hbmMem;    /* color graph bitmap */    
121  RECT16 fullsize;     /* original dialog window size */
122  UINT16 msetrgb;        /* # of SETRGBSTRING message (today not used)  */
123  RECT16 old3angle;    /* last position of l-marker */
124  RECT16 oldcross;     /* last position of color/satuation marker */
125  BOOL updating;     /* to prevent recursive WM_COMMAND/EN_UPDATE procesing */
126  int h;
127  int s;
128  int l;               /* for temporary storing of hue,sat,lum */
129 };
130
131 /***********************************************************************
132  *                             CC_HSLtoRGB                    [internal]
133  */
134 static int CC_HSLtoRGB(char c,int hue,int sat,int lum)
135 {
136  int res=0,maxrgb;
137
138  /* hue */
139  switch(c)
140  {
141   case 'R':if (hue>80)  hue-=80;  else hue+=160; break;
142   case 'G':if (hue>160) hue-=160; else hue+=80;  break;
143   case 'B':break;
144  }
145
146  /* l below 120 */
147  maxrgb=(256*MIN(120,lum))/120;  /* 0 .. 256 */
148  if (hue< 80)
149   res=0;
150  else
151   if (hue< 120)
152   {
153    res=(hue-80)* maxrgb;           /* 0...10240 */
154    res/=40;                        /* 0...256 */
155   }
156   else
157    if (hue< 200)
158     res=maxrgb;
159    else
160     {
161      res=(240-hue)* maxrgb;
162      res/=40;
163     }
164  res=res-maxrgb/2;                 /* -128...128 */
165
166  /* saturation */
167  res=maxrgb/2 + (sat*res) /240;    /* 0..256 */
168
169  /* lum above 120 */
170  if (lum>120 && res<256)
171   res+=((lum-120) * (256-res))/120;
172
173  return MIN(res,255);
174 }
175
176 /***********************************************************************
177  *                             CC_RGBtoHSL                    [internal]
178  */
179 static int CC_RGBtoHSL(char c,int r,int g,int b)
180 {
181  WORD maxi,mini,mmsum,mmdif,result=0;
182  int iresult=0;
183
184  maxi=MAX(r,b);
185  maxi=MAX(maxi,g);
186  mini=MIN(r,b);
187  mini=MIN(mini,g);
188
189  mmsum=maxi+mini;
190  mmdif=maxi-mini;
191
192  switch(c)
193  {
194   /* lum */
195   case 'L':mmsum*=120;              /* 0...61200=(255+255)*120 */
196            result=mmsum/255;        /* 0...240 */
197            break;
198   /* saturation */
199   case 'S':if (!mmsum)
200             result=0;
201            else
202             if (!mini || maxi==255)
203              result=240;
204            else
205            {
206             result=mmdif*240;       /* 0...61200=255*240 */
207             result/= (mmsum>255 ? mmsum=510-mmsum : mmsum); /* 0..255 */
208            }
209            break;
210   /* hue */
211   case 'H':if (!mmdif)
212             result=160;
213            else
214            {
215             if (maxi==r)
216             {
217              iresult=40*(g-b);       /* -10200 ... 10200 */
218              iresult/=(int)mmdif;    /* -40 .. 40 */
219              if (iresult<0)
220               iresult+=240;          /* 0..40 and 200..240 */
221             }
222             else
223              if (maxi==g)
224              {
225               iresult=40*(b-r);
226               iresult/=(int)mmdif;
227               iresult+=80;           /* 40 .. 120 */
228              }
229              else
230               if (maxi==b)
231               {
232                iresult=40*(r-g);
233                iresult/=(int)mmdif;
234                iresult+=160;         /* 120 .. 200 */
235               }
236             result=iresult;
237            }
238            break;
239  }
240  return result;    /* is this integer arithmetic precise enough ? */
241 }
242
243 #define DISTANCE 4
244
245 /***********************************************************************
246  *                CC_MouseCheckPredefColorArray               [internal]
247  */
248 static int CC_MouseCheckPredefColorArray(HWND16 hDlg,int dlgitem,int rows,int cols,
249             LPARAM lParam,COLORREF *cr)
250 {
251  HWND16 hwnd;
252  POINT16 point = MAKEPOINT16(lParam);
253  RECT16 rect;
254  int dx,dy,x,y;
255
256  ClientToScreen16(hDlg,&point);
257  hwnd=GetDlgItem(hDlg,dlgitem);
258  GetWindowRect16(hwnd,&rect);
259  if (PtInRect16(&rect,point))
260  {
261   dx=(rect.right-rect.left)/cols;
262   dy=(rect.bottom-rect.top)/rows;
263   ScreenToClient16(hwnd,&point);
264
265   if (point.x % dx < (dx-DISTANCE) && point.y % dy < (dy-DISTANCE))
266   {
267    x=point.x/dx;
268    y=point.y/dy;
269    *cr=predefcolors[y][x];
270    /* FIXME: Draw_a_Focus_Rect() */
271    return 1;
272   }
273  }
274  return 0;
275 }
276
277 /***********************************************************************
278  *                  CC_MouseCheckUserColorArray               [internal]
279  */
280 static int CC_MouseCheckUserColorArray(HWND16 hDlg,int dlgitem,int rows,int cols,
281             LPARAM lParam,COLORREF *cr,COLORREF*crarr)
282 {
283  HWND16 hwnd;
284  POINT16 point = MAKEPOINT16(lParam);
285  RECT16 rect;
286  int dx,dy,x,y;
287
288  ClientToScreen16(hDlg,&point);
289  hwnd=GetDlgItem(hDlg,dlgitem);
290  GetWindowRect16(hwnd,&rect);
291  if (PtInRect16(&rect,point))
292  {
293   dx=(rect.right-rect.left)/cols;
294   dy=(rect.bottom-rect.top)/rows;
295   ScreenToClient16(hwnd,&point);
296
297   if (point.x % dx < (dx-DISTANCE) && point.y % dy < (dy-DISTANCE))
298   {
299    x=point.x/dx;
300    y=point.y/dy;
301    *cr=crarr[x+cols*y];
302    /* FIXME: Draw_a_Focus_Rect() */
303    return 1;
304   }
305  }
306  return 0;
307 }
308
309 #define MAXVERT  240
310 #define MAXHORI  239
311
312 /*  240  ^......        ^^ 240
313          |     .        ||
314     SAT  |     .        || LUM
315          |     .        ||
316          +-----> 239   ----
317            HUE
318 */
319 /***********************************************************************
320  *                  CC_MouseCheckColorGraph                   [internal]
321  */
322 static int CC_MouseCheckColorGraph(HWND16 hDlg,int dlgitem,int *hori,int *vert,LPARAM lParam)
323 {
324  HWND hwnd;
325  POINT16 point = MAKEPOINT16(lParam);
326  RECT16 rect;
327  long x,y;
328
329  ClientToScreen16(hDlg,&point);
330  hwnd=GetDlgItem(hDlg,dlgitem);
331  GetWindowRect16(hwnd,&rect);
332  if (PtInRect16(&rect,point))
333  {
334   GetClientRect16(hwnd,&rect);
335   ScreenToClient16(hwnd,&point);
336
337   x=(long)point.x*MAXHORI;
338   x/=rect.right;
339   y=(long)(rect.bottom-point.y)*MAXVERT;
340   y/=rect.bottom;
341
342   if (hori)
343    *hori=x;
344   if (vert)
345    *vert=y;
346   return 1;
347  }
348  else
349   return 0;
350 }
351 /***********************************************************************
352  *                  CC_MouseCheckResultWindow                 [internal]
353  */
354 static int CC_MouseCheckResultWindow(HWND16 hDlg,LPARAM lParam)
355 {
356  HWND16 hwnd;
357  POINT16 point = MAKEPOINT16(lParam);
358  RECT16 rect;
359
360  ClientToScreen16(hDlg,&point);
361  hwnd=GetDlgItem(hDlg,0x2c5);
362  GetWindowRect16(hwnd,&rect);
363  if (PtInRect16(&rect,point))
364  {
365   PostMessage16(hDlg,WM_COMMAND,0x2c9,0);
366   return 1;
367  }
368  return 0;
369 }
370
371 /***********************************************************************
372  *                       CC_CheckDigitsInEdit                 [internal]
373  */
374 static int CC_CheckDigitsInEdit(HWND16 hwnd,int maxval)
375 {
376  int i,k,m,result,value;
377  long editpos;
378  char buffer[30];
379  GetWindowTextA(hwnd,buffer,sizeof(buffer));
380  m=strlen(buffer);
381  result=0;
382
383  for (i=0;i<m;i++)
384   if (buffer[i]<'0' || buffer[i]>'9')
385   {
386    for (k=i+1;k<=m;k++)   /* delete bad character */
387    {
388     buffer[i]=buffer[k];
389     m--;
390    }
391    buffer[m]=0;
392    result=1;
393   }
394
395  value=atoi(buffer);
396  if (value>maxval)       /* build a new string */
397  {
398   sprintf(buffer,"%d",maxval);
399   result=2;
400  }
401  if (result)
402  {
403   editpos=SendMessage16(hwnd,EM_GETSEL16,0,0);
404   SetWindowTextA(hwnd,buffer);
405   SendMessage16(hwnd,EM_SETSEL16,0,editpos);
406  }
407  return value;
408 }
409
410
411
412 /***********************************************************************
413  *                    CC_PaintSelectedColor                   [internal]
414  */
415 static void CC_PaintSelectedColor(HWND16 hDlg,COLORREF cr)
416 {
417  RECT16 rect;
418  HDC  hdc;
419  HBRUSH hBrush;
420  HWND hwnd=GetDlgItem(hDlg,0x2c5);
421  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
422  {
423   hdc=GetDC(hwnd);
424   GetClientRect16 (hwnd, &rect) ;
425   hBrush = CreateSolidBrush(cr);
426   if (hBrush)
427   {
428    hBrush = SelectObject (hdc, hBrush) ;
429    Rectangle(hdc, rect.left,rect.top,rect.right/2,rect.bottom);
430    DeleteObject (SelectObject (hdc,hBrush)) ;
431    hBrush=CreateSolidBrush(GetNearestColor(hdc,cr));
432    if (hBrush)
433    {
434     hBrush= SelectObject (hdc, hBrush) ;
435     Rectangle( hdc, rect.right/2-1,rect.top,rect.right,rect.bottom);
436     DeleteObject( SelectObject (hdc, hBrush)) ;
437    }
438   }
439   ReleaseDC(hwnd,hdc);
440  }
441 }
442
443 /***********************************************************************
444  *                    CC_PaintTriangle                        [internal]
445  */
446 static void CC_PaintTriangle(HWND16 hDlg,int y)
447 {
448  HDC hDC;
449  long temp;
450  int w=GetDialogBaseUnits();
451  POINT16 points[3];
452  int height;
453  int oben;
454  RECT16 rect;
455  HWND16 hwnd=GetDlgItem(hDlg,0x2be);
456  struct CCPRIVATE *lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER); 
457
458  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
459  {
460    GetClientRect16(hwnd,&rect);
461    height=rect.bottom;
462    hDC=GetDC(hDlg);
463
464    points[0].y=rect.top;
465    points[0].x=rect.right;           /*  |  /|  */
466    ClientToScreen16(hwnd,points);    /*  | / |  */
467    ScreenToClient16(hDlg,points);    /*  |<  |  */
468    oben=points[0].y;                 /*  | \ |  */
469                                      /*  |  \|  */
470    temp=(long)height*(long)y;
471    points[0].y=oben+height -temp/(long)MAXVERT;
472    points[1].y=points[0].y+w;
473    points[2].y=points[0].y-w;
474    points[2].x=points[1].x=points[0].x + w;
475
476    if (lpp->old3angle.left)
477     FillRect16(hDC,&lpp->old3angle,GetStockObject(WHITE_BRUSH));
478    lpp->old3angle.left  =points[0].x;
479    lpp->old3angle.right =points[1].x+1;
480    lpp->old3angle.top   =points[2].y-1;
481    lpp->old3angle.bottom=points[1].y+1;
482    Polygon16(hDC,points,3);
483    ReleaseDC(hDlg,hDC);
484  }
485 }
486
487
488 /***********************************************************************
489  *                    CC_PaintCross                           [internal]
490  */
491 static void CC_PaintCross(HWND16 hDlg,int x,int y)
492 {
493  HDC hDC;
494  int w=GetDialogBaseUnits();
495  HWND16 hwnd=GetDlgItem(hDlg,0x2c6);
496  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER); 
497  RECT16 rect;
498  POINT16 point;
499  HPEN hPen;
500
501  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
502  {
503    GetClientRect16(hwnd,&rect);
504    hDC=GetDC(hwnd);
505    SelectClipRgn(hDC,CreateRectRgnIndirect16(&rect));
506    hPen=CreatePen(PS_SOLID,2,0);
507    hPen=SelectObject(hDC,hPen);
508    point.x=((long)rect.right*(long)x)/(long)MAXHORI;
509    point.y=rect.bottom-((long)rect.bottom*(long)y)/(long)MAXVERT;
510    if (lpp->oldcross.left!=lpp->oldcross.right)
511      BitBlt(hDC,lpp->oldcross.left,lpp->oldcross.top,
512               lpp->oldcross.right-lpp->oldcross.left,
513               lpp->oldcross.bottom-lpp->oldcross.top,
514               lpp->hdcMem,lpp->oldcross.left,lpp->oldcross.top,SRCCOPY);
515    lpp->oldcross.left  =point.x-w-1;
516    lpp->oldcross.right =point.x+w+1;
517    lpp->oldcross.top   =point.y-w-1;
518    lpp->oldcross.bottom=point.y+w+1; 
519
520    MoveTo16(hDC,point.x-w,point.y); 
521    LineTo(hDC,point.x+w,point.y);
522    MoveTo16(hDC,point.x,point.y-w); 
523    LineTo(hDC,point.x,point.y+w);
524    DeleteObject(SelectObject(hDC,hPen));
525    ReleaseDC(hwnd,hDC);
526  }
527 }
528
529
530 #define XSTEPS 48
531 #define YSTEPS 24
532
533
534 /***********************************************************************
535  *                    CC_PrepareColorGraph                    [internal]
536  */
537 static void CC_PrepareColorGraph(HWND16 hDlg)    
538 {
539  int sdif,hdif,xdif,ydif,r,g,b,hue,sat;
540  HWND hwnd=GetDlgItem(hDlg,0x2c6);
541  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);  
542  HBRUSH hbrush;
543  HDC hdc ;
544  RECT16 rect,client;
545  HCURSOR16 hcursor=SetCursor16(LoadCursor16(0,IDC_WAIT16));
546
547  GetClientRect16(hwnd,&client);
548  hdc=GetDC(hwnd);
549  lpp->hdcMem = CreateCompatibleDC(hdc);
550  lpp->hbmMem = CreateCompatibleBitmap(hdc,client.right,client.bottom);
551  SelectObject(lpp->hdcMem,lpp->hbmMem);
552
553  xdif=client.right /XSTEPS;
554  ydif=client.bottom/YSTEPS+1;
555  hdif=239/XSTEPS;
556  sdif=240/YSTEPS;
557  for(rect.left=hue=0;hue<239+hdif;hue+=hdif)
558  {
559   rect.right=rect.left+xdif;
560   rect.bottom=client.bottom;
561   for(sat=0;sat<240+sdif;sat+=sdif)
562   {
563    rect.top=rect.bottom-ydif;
564    r=CC_HSLtoRGB('R',hue,sat,120);
565    g=CC_HSLtoRGB('G',hue,sat,120);
566    b=CC_HSLtoRGB('B',hue,sat,120);
567    hbrush=CreateSolidBrush(RGB(r,g,b));
568    FillRect16(lpp->hdcMem,&rect,hbrush);
569    DeleteObject(hbrush);
570    rect.bottom=rect.top;
571   }
572   rect.left=rect.right;
573  }
574  ReleaseDC(hwnd,hdc);
575  SetCursor16(hcursor);
576 }
577
578 /***********************************************************************
579  *                          CC_PaintColorGraph                [internal]
580  */
581 static void CC_PaintColorGraph(HWND16 hDlg)
582 {
583  HWND hwnd=GetDlgItem(hDlg,0x2c6);
584  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER); 
585  HDC  hDC;
586  RECT16 rect;
587  if (IsWindowVisible(hwnd))   /* if full size */
588  {
589   if (!lpp->hdcMem)
590    CC_PrepareColorGraph(hDlg);   /* should not be necessary */
591
592   hDC=GetDC(hwnd);
593   GetClientRect16(hwnd,&rect);
594   if (lpp->hdcMem)
595       BitBlt(hDC,0,0,rect.right,rect.bottom,lpp->hdcMem,0,0,SRCCOPY);
596   else
597     WARN("choose color: hdcMem is not defined\n");
598   ReleaseDC(hwnd,hDC);
599  }
600 }
601 /***********************************************************************
602  *                           CC_PaintLumBar                   [internal]
603  */
604 static void CC_PaintLumBar(HWND16 hDlg,int hue,int sat)
605 {
606  HWND hwnd=GetDlgItem(hDlg,0x2be);
607  RECT16 rect,client;
608  int lum,ldif,ydif,r,g,b;
609  HBRUSH hbrush;
610  HDC hDC;
611
612  if (IsWindowVisible(hwnd))
613  {
614   hDC=GetDC(hwnd);
615   GetClientRect16(hwnd,&client);
616   rect=client;
617
618   ldif=240/YSTEPS;
619   ydif=client.bottom/YSTEPS+1;
620   for(lum=0;lum<240+ldif;lum+=ldif)
621   {
622    rect.top=MAX(0,rect.bottom-ydif);
623    r=CC_HSLtoRGB('R',hue,sat,lum);
624    g=CC_HSLtoRGB('G',hue,sat,lum);
625    b=CC_HSLtoRGB('B',hue,sat,lum);
626    hbrush=CreateSolidBrush(RGB(r,g,b));
627    FillRect16(hDC,&rect,hbrush);
628    DeleteObject(hbrush);
629    rect.bottom=rect.top;
630   }
631   GetClientRect16(hwnd,&rect);
632   FrameRect16(hDC,&rect,GetStockObject(BLACK_BRUSH));
633   ReleaseDC(hwnd,hDC);
634  }
635 }
636
637 /***********************************************************************
638  *                             CC_EditSetRGB                  [internal]
639  */
640 static void CC_EditSetRGB(HWND16 hDlg,COLORREF cr)
641 {
642  char buffer[10];
643  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER); 
644  int r=GetRValue(cr);
645  int g=GetGValue(cr);
646  int b=GetBValue(cr);
647  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
648  {
649    lpp->updating=TRUE;
650    sprintf(buffer,"%d",r);
651    SetWindowTextA(GetDlgItem(hDlg,0x2c2),buffer);
652    sprintf(buffer,"%d",g);
653    SetWindowTextA(GetDlgItem(hDlg,0x2c3),buffer);
654    sprintf(buffer,"%d",b);
655    SetWindowTextA(GetDlgItem(hDlg,0x2c4),buffer);
656    lpp->updating=FALSE;
657  }
658 }
659
660 /***********************************************************************
661  *                             CC_EditSetHSL                  [internal]
662  */
663 static void CC_EditSetHSL(HWND16 hDlg,int h,int s,int l)
664 {
665  char buffer[10];
666  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER); 
667  lpp->updating=TRUE;
668  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
669  {
670    lpp->updating=TRUE;
671    sprintf(buffer,"%d",h);
672    SetWindowTextA(GetDlgItem(hDlg,0x2bf),buffer);
673    sprintf(buffer,"%d",s);
674    SetWindowTextA(GetDlgItem(hDlg,0x2c0),buffer);
675    sprintf(buffer,"%d",l);
676    SetWindowTextA(GetDlgItem(hDlg,0x2c1),buffer);
677    lpp->updating=FALSE;
678  }
679  CC_PaintLumBar(hDlg,h,s);
680 }
681
682 /***********************************************************************
683  *                       CC_SwitchToFullSize                  [internal]
684  */
685 static void CC_SwitchToFullSize(HWND16 hDlg,COLORREF result,LPRECT16 lprect)
686 {
687  int i;
688  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER); 
689  
690  EnableWindow(GetDlgItem(hDlg,0x2cf),FALSE);
691  CC_PrepareColorGraph(hDlg);
692  for (i=0x2bf;i<0x2c5;i++)
693    EnableWindow(GetDlgItem(hDlg,i),TRUE);
694  for (i=0x2d3;i<0x2d9;i++)
695    EnableWindow(GetDlgItem(hDlg,i),TRUE);
696  EnableWindow(GetDlgItem(hDlg,0x2c9),TRUE);
697  EnableWindow(GetDlgItem(hDlg,0x2c8),TRUE);
698
699  if (lprect)
700   SetWindowPos(hDlg,0,0,0,lprect->right-lprect->left,
701    lprect->bottom-lprect->top, SWP_NOMOVE|SWP_NOZORDER);
702
703  ShowWindow(GetDlgItem(hDlg,0x2c6),SW_SHOW);
704  ShowWindow(GetDlgItem(hDlg,0x2be),SW_SHOW);
705  ShowWindow(GetDlgItem(hDlg,0x2c5),SW_SHOW);
706
707  CC_EditSetRGB(hDlg,result);
708  CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
709 }
710
711 /***********************************************************************
712  *                           CC_PaintPredefColorArray         [internal]
713  */
714 static void CC_PaintPredefColorArray(HWND16 hDlg,int rows,int cols)
715 {
716  HWND hwnd=GetDlgItem(hDlg,0x2d0);
717  RECT16 rect;
718  HDC  hdc;
719  HBRUSH hBrush;
720  int dx,dy,i,j,k;
721
722  GetClientRect16(hwnd,&rect);
723  dx=rect.right/cols;
724  dy=rect.bottom/rows;
725  k=rect.left;
726
727  hdc=GetDC(hwnd);
728  GetClientRect16 (hwnd, &rect) ;
729
730  for (j=0;j<rows;j++)
731  {
732   for (i=0;i<cols;i++)
733   {
734    hBrush = CreateSolidBrush(predefcolors[j][i]);
735    if (hBrush)
736    {
737     hBrush = SelectObject (hdc, hBrush) ;
738     Rectangle(hdc, rect.left, rect.top,
739                 rect.left+dx-DISTANCE, rect.top+dy-DISTANCE);
740     rect.left=rect.left+dx;
741     DeleteObject( SelectObject (hdc, hBrush)) ;
742    }
743   }
744   rect.top=rect.top+dy;
745   rect.left=k;
746  }
747  ReleaseDC(hwnd,hdc);
748  /* FIXME: draw_a_focus_rect */
749 }
750 /***********************************************************************
751  *                             CC_PaintUserColorArray         [internal]
752  */
753 static void CC_PaintUserColorArray(HWND16 hDlg,int rows,int cols,COLORREF* lpcr)
754 {
755  HWND hwnd=GetDlgItem(hDlg,0x2d1);
756  RECT16 rect;
757  HDC  hdc;
758  HBRUSH hBrush;
759  int dx,dy,i,j,k;
760
761  GetClientRect16(hwnd,&rect);
762
763  dx=rect.right/cols;
764  dy=rect.bottom/rows;
765  k=rect.left;
766
767  hdc=GetDC(hwnd);
768  if (hdc)
769  {
770   for (j=0;j<rows;j++)
771   {
772    for (i=0;i<cols;i++)
773    {
774     hBrush = CreateSolidBrush(lpcr[i+j*cols]);
775     if (hBrush)
776     {
777      hBrush = SelectObject (hdc, hBrush) ;
778      Rectangle( hdc, rect.left, rect.top,
779                   rect.left+dx-DISTANCE, rect.top+dy-DISTANCE);
780      rect.left=rect.left+dx;
781      DeleteObject( SelectObject (hdc, hBrush)) ;
782     }
783    }
784    rect.top=rect.top+dy;
785    rect.left=k;
786   }
787   ReleaseDC(hwnd,hdc);
788  }
789  /* FIXME: draw_a_focus_rect */
790 }
791
792
793
794 /***********************************************************************
795  *                             CC_HookCallChk                 [internal]
796  */
797 static BOOL CC_HookCallChk(LPCHOOSECOLOR16 lpcc)
798 {
799  if (lpcc)
800   if(lpcc->Flags & CC_ENABLEHOOK)
801    if (lpcc->lpfnHook)
802     return TRUE;
803  return FALSE;
804 }
805
806 /***********************************************************************
807  *                            CC_WMInitDialog                 [internal]
808  */
809 static LONG CC_WMInitDialog(HWND16 hDlg, WPARAM16 wParam, LPARAM lParam) 
810 {
811    int i,res;
812    int r, g, b;
813    HWND16 hwnd;
814    RECT16 rect;
815    POINT16 point;
816    struct CCPRIVATE * lpp; 
817    
818    TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
819    lpp=calloc(1,sizeof(struct CCPRIVATE));
820    lpp->lpcc=(LPCHOOSECOLOR16)lParam;
821
822    if (lpp->lpcc->lStructSize != sizeof(CHOOSECOLOR16))
823    {
824       EndDialog (hDlg, 0) ;
825       return FALSE;
826    }
827    SetWindowLongA(hDlg, DWL_USER, (LONG)lpp); 
828
829    if (!(lpp->lpcc->Flags & CC_SHOWHELP))
830       ShowWindow(GetDlgItem(hDlg,0x40e),SW_HIDE);
831    lpp->msetrgb=RegisterWindowMessageA( SETRGBSTRING );
832
833 #if 0
834    cpos=MAKELONG(5,7); /* init */
835    if (lpp->lpcc->Flags & CC_RGBINIT)
836    {
837      for (i=0;i<6;i++)
838        for (j=0;j<8;j++)
839         if (predefcolors[i][j]==lpp->lpcc->rgbResult)
840         {
841           cpos=MAKELONG(i,j);
842           goto found;
843         }
844    }
845    found:
846    /* FIXME: Draw_a_focus_rect & set_init_values */
847 #endif
848
849    GetWindowRect16(hDlg,&lpp->fullsize);
850    if (lpp->lpcc->Flags & CC_FULLOPEN || lpp->lpcc->Flags & CC_PREVENTFULLOPEN)
851    {
852       hwnd=GetDlgItem(hDlg,0x2cf);
853       EnableWindow(hwnd,FALSE);
854    }
855    if (!(lpp->lpcc->Flags & CC_FULLOPEN) || lpp->lpcc->Flags & CC_PREVENTFULLOPEN)
856    {
857       rect=lpp->fullsize;
858       res=rect.bottom-rect.top;
859       hwnd=GetDlgItem(hDlg,0x2c6); /* cut at left border */
860       point.x=point.y=0;
861       ClientToScreen16(hwnd,&point);
862       ScreenToClient16(hDlg,&point);
863       GetClientRect16(hDlg,&rect);
864       point.x+=GetSystemMetrics(SM_CXDLGFRAME);
865       SetWindowPos(hDlg,0,0,0,point.x,res,SWP_NOMOVE|SWP_NOZORDER);
866
867       ShowWindow(GetDlgItem(hDlg,0x2c6),SW_HIDE);
868       ShowWindow(GetDlgItem(hDlg,0x2c5),SW_HIDE);
869    }
870    else
871       CC_SwitchToFullSize(hDlg,lpp->lpcc->rgbResult,NULL);
872    res=TRUE;
873    for (i=0x2bf;i<0x2c5;i++)
874      SendMessage16(GetDlgItem(hDlg,i),EM_LIMITTEXT16,3,0);      /* max 3 digits:  xyz  */
875    if (CC_HookCallChk(lpp->lpcc))
876       res=CallWindowProc16((WNDPROC16)lpp->lpcc->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
877
878    
879    /* Set the initial values of the color chooser dialog */
880    r = GetRValue(lpp->lpcc->rgbResult);
881    g = GetGValue(lpp->lpcc->rgbResult);
882    b = GetBValue(lpp->lpcc->rgbResult);
883
884    CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
885    lpp->h=CC_RGBtoHSL('H',r,g,b);
886    lpp->s=CC_RGBtoHSL('S',r,g,b);
887    lpp->l=CC_RGBtoHSL('L',r,g,b);
888
889    /* Doing it the long way becaus CC_EditSetRGB/HSL doesn'nt seem to work */
890    SetDlgItemInt(hDlg, 703, lpp->h, TRUE);
891    SetDlgItemInt(hDlg, 704, lpp->s, TRUE);
892    SetDlgItemInt(hDlg, 705, lpp->l, TRUE);
893    SetDlgItemInt(hDlg, 706, r, TRUE);
894    SetDlgItemInt(hDlg, 707, g, TRUE);
895    SetDlgItemInt(hDlg, 708, b, TRUE);
896
897    CC_PaintCross(hDlg,lpp->h,lpp->s);
898    CC_PaintTriangle(hDlg,lpp->l);
899
900    return res;
901 }
902
903 /***********************************************************************
904  *                              CC_WMCommand                  [internal]
905  */
906 static LRESULT CC_WMCommand(HWND16 hDlg, WPARAM16 wParam, LPARAM lParam) 
907 {
908     int r,g,b,i,xx;
909     UINT16 cokmsg;
910     HDC hdc;
911     COLORREF *cr;
912     struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER); 
913     TRACE("CC_WMCommand wParam=%x lParam=%lx\n",wParam,lParam);
914     switch (wParam)
915     {
916           case 0x2c2:  /* edit notify RGB */
917           case 0x2c3:
918           case 0x2c4:
919                if (HIWORD(lParam)==EN_UPDATE && !lpp->updating)
920                          {
921                            i=CC_CheckDigitsInEdit(LOWORD(lParam),255);
922                            r=GetRValue(lpp->lpcc->rgbResult);
923                            g=GetGValue(lpp->lpcc->rgbResult);
924                            b=GetBValue(lpp->lpcc->rgbResult);
925                            xx=0;
926                            switch (wParam)
927                            {
928                             case 0x2c2:if ((xx=(i!=r))) r=i;break;
929                             case 0x2c3:if ((xx=(i!=g))) g=i;break;
930                             case 0x2c4:if ((xx=(i!=b))) b=i;break;
931                            }
932                            if (xx) /* something has changed */
933                            {
934                             lpp->lpcc->rgbResult=RGB(r,g,b);
935                             CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
936                             lpp->h=CC_RGBtoHSL('H',r,g,b);
937                             lpp->s=CC_RGBtoHSL('S',r,g,b);
938                             lpp->l=CC_RGBtoHSL('L',r,g,b);
939                             CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
940                             CC_PaintCross(hDlg,lpp->h,lpp->s);
941                             CC_PaintTriangle(hDlg,lpp->l);
942                            }
943                          }
944                  break;
945                  
946           case 0x2bf:  /* edit notify HSL */
947           case 0x2c0:
948           case 0x2c1:
949                if (HIWORD(lParam)==EN_UPDATE && !lpp->updating)
950                          {
951                            i=CC_CheckDigitsInEdit(LOWORD(lParam),wParam==0x2bf?239:240);
952                            xx=0;
953                            switch (wParam)
954                            {
955                             case 0x2bf:if ((xx=(i!=lpp->h))) lpp->h=i;break;
956                             case 0x2c0:if ((xx=(i!=lpp->s))) lpp->s=i;break;
957                             case 0x2c1:if ((xx=(i!=lpp->l))) lpp->l=i;break;
958                            }
959                            if (xx) /* something has changed */
960                            {
961                             r=CC_HSLtoRGB('R',lpp->h,lpp->s,lpp->l);
962                             g=CC_HSLtoRGB('G',lpp->h,lpp->s,lpp->l);
963                             b=CC_HSLtoRGB('B',lpp->h,lpp->s,lpp->l);
964                             lpp->lpcc->rgbResult=RGB(r,g,b);
965                             CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
966                             CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
967                             CC_PaintCross(hDlg,lpp->h,lpp->s);
968                             CC_PaintTriangle(hDlg,lpp->l);
969                            }
970                          }
971                break;
972                
973           case 0x2cf:
974                CC_SwitchToFullSize(hDlg,lpp->lpcc->rgbResult,&lpp->fullsize);
975                InvalidateRect( hDlg, NULL, TRUE );
976                SetFocus(GetDlgItem(hDlg,0x2bf));
977                break;
978
979           case 0x2c8:    /* add colors ... column by column */
980                cr=PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors);
981                cr[(lpp->nextuserdef%2)*8 + lpp->nextuserdef/2]=lpp->lpcc->rgbResult;
982                if (++lpp->nextuserdef==16)
983                    lpp->nextuserdef=0;
984                CC_PaintUserColorArray(hDlg,2,8,PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors));
985                break;
986
987           case 0x2c9:              /* resulting color */
988                hdc=GetDC(hDlg);
989                lpp->lpcc->rgbResult=GetNearestColor(hdc,lpp->lpcc->rgbResult);
990                ReleaseDC(hDlg,hdc);
991                CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
992                CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
993                r=GetRValue(lpp->lpcc->rgbResult);
994                g=GetGValue(lpp->lpcc->rgbResult);
995                b=GetBValue(lpp->lpcc->rgbResult);
996                lpp->h=CC_RGBtoHSL('H',r,g,b);
997                lpp->s=CC_RGBtoHSL('S',r,g,b);
998                lpp->l=CC_RGBtoHSL('L',r,g,b);
999                CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
1000                CC_PaintCross(hDlg,lpp->h,lpp->s);
1001                CC_PaintTriangle(hDlg,lpp->l);
1002                break;
1003
1004           case 0x40e:           /* Help! */ /* The Beatles, 1965  ;-) */
1005                i=RegisterWindowMessageA( HELPMSGSTRING );
1006                if (lpp->lpcc->hwndOwner)
1007                    SendMessage16(lpp->lpcc->hwndOwner,i,0,(LPARAM)lpp->lpcc);
1008                if (CC_HookCallChk(lpp->lpcc))
1009                    CallWindowProc16((WNDPROC16)lpp->lpcc->lpfnHook,hDlg,
1010                       WM_COMMAND,psh15,(LPARAM)lpp->lpcc);
1011                break;
1012
1013           case IDOK :
1014                 cokmsg=RegisterWindowMessageA( COLOROKSTRING );
1015                 if (lpp->lpcc->hwndOwner)
1016                         if (SendMessage16(lpp->lpcc->hwndOwner,cokmsg,0,(LPARAM)lpp->lpcc))
1017                            break;    /* do NOT close */
1018
1019                 EndDialog (hDlg, 1) ;
1020                 return TRUE ;
1021         
1022           case IDCANCEL :
1023                 EndDialog (hDlg, 0) ;
1024                 return TRUE ;
1025
1026        }
1027        return FALSE;
1028 }
1029
1030 /***********************************************************************
1031  *                              CC_WMPaint                    [internal]
1032  */
1033 static LRESULT CC_WMPaint(HWND16 hDlg, WPARAM16 wParam, LPARAM lParam) 
1034 {
1035     HDC hdc;
1036     PAINTSTRUCT ps;
1037     struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER); 
1038
1039     hdc=BeginPaint(hDlg,&ps);
1040     EndPaint(hDlg,&ps);
1041     /* we have to paint dialog children except text and buttons */
1042  
1043     CC_PaintPredefColorArray(hDlg,6,8);
1044     CC_PaintUserColorArray(hDlg,2,8,PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors));
1045     CC_PaintColorGraph(hDlg);
1046     CC_PaintLumBar(hDlg,lpp->h,lpp->s);
1047     CC_PaintCross(hDlg,lpp->h,lpp->s);
1048     CC_PaintTriangle(hDlg,lpp->l);
1049     CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
1050
1051     /* special necessary for Wine */
1052     ValidateRect(GetDlgItem(hDlg,0x2d0),NULL);
1053     ValidateRect(GetDlgItem(hDlg,0x2d1),NULL);
1054     ValidateRect(GetDlgItem(hDlg,0x2c6),NULL);
1055     ValidateRect(GetDlgItem(hDlg,0x2be),NULL);
1056     ValidateRect(GetDlgItem(hDlg,0x2c5),NULL);
1057     /* hope we can remove it later -->FIXME */
1058  return TRUE;
1059 }
1060
1061
1062 /***********************************************************************
1063  *                              CC_WMLButtonDown              [internal]
1064  */
1065 static LRESULT CC_WMLButtonDown(HWND16 hDlg, WPARAM16 wParam, LPARAM lParam) 
1066 {
1067    struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER); 
1068    int r,g,b,i;
1069    i=0;
1070    if (CC_MouseCheckPredefColorArray(hDlg,0x2d0,6,8,lParam,&lpp->lpcc->rgbResult))
1071       i=1;
1072    else
1073       if (CC_MouseCheckUserColorArray(hDlg,0x2d1,2,8,lParam,&lpp->lpcc->rgbResult,
1074               PTR_SEG_TO_LIN(lpp->lpcc->lpCustColors)))
1075          i=1;
1076       else
1077          if (CC_MouseCheckColorGraph(hDlg,0x2c6,&lpp->h,&lpp->s,lParam))
1078             i=2;
1079          else
1080             if (CC_MouseCheckColorGraph(hDlg,0x2be,NULL,&lpp->l,lParam))
1081                i=2;
1082    if (i==2)
1083    {
1084       r=CC_HSLtoRGB('R',lpp->h,lpp->s,lpp->l);
1085       g=CC_HSLtoRGB('G',lpp->h,lpp->s,lpp->l);
1086       b=CC_HSLtoRGB('B',lpp->h,lpp->s,lpp->l);
1087       lpp->lpcc->rgbResult=RGB(r,g,b);
1088    }
1089    if (i==1)
1090    {
1091       r=GetRValue(lpp->lpcc->rgbResult);
1092       g=GetGValue(lpp->lpcc->rgbResult);
1093       b=GetBValue(lpp->lpcc->rgbResult);
1094       lpp->h=CC_RGBtoHSL('H',r,g,b);
1095       lpp->s=CC_RGBtoHSL('S',r,g,b);
1096       lpp->l=CC_RGBtoHSL('L',r,g,b);
1097    }
1098    if (i)
1099    {
1100       CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
1101       CC_EditSetHSL(hDlg,lpp->h,lpp->s,lpp->l);
1102       CC_PaintCross(hDlg,lpp->h,lpp->s);
1103       CC_PaintTriangle(hDlg,lpp->l);
1104       CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
1105       return TRUE;
1106    }
1107    return FALSE;
1108 }
1109
1110 /***********************************************************************
1111  *           ColorDlgProc   (COMMDLG.8)
1112  */
1113 LRESULT WINAPI ColorDlgProc16(HWND16 hDlg, UINT16 message,
1114                             WPARAM16 wParam, LONG lParam)
1115 {
1116  int res;
1117  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER); 
1118  if (message!=WM_INITDIALOG)
1119  {
1120   if (!lpp)
1121      return FALSE;
1122   res=0;
1123   if (CC_HookCallChk(lpp->lpcc))
1124      res=CallWindowProc16((WNDPROC16)lpp->lpcc->lpfnHook,hDlg,message,wParam,lParam);
1125   if (res)
1126      return res;
1127  }
1128
1129  /* FIXME: SetRGB message
1130  if (message && message==msetrgb)
1131     return HandleSetRGB(hDlg,lParam);
1132  */
1133
1134  switch (message)
1135         {
1136           case WM_INITDIALOG:
1137                         return CC_WMInitDialog(hDlg,wParam,lParam);
1138           case WM_NCDESTROY:
1139                         DeleteDC(lpp->hdcMem); 
1140                         DeleteObject(lpp->hbmMem); 
1141                         free(lpp);
1142                         SetWindowLongA(hDlg, DWL_USER, 0L); /* we don't need it anymore */
1143                         break;
1144           case WM_COMMAND:
1145                         if (CC_WMCommand(hDlg, wParam, lParam))
1146                            return TRUE;
1147                         break;     
1148           case WM_PAINT:
1149                         if (CC_WMPaint(hDlg, wParam, lParam))
1150                            return TRUE;
1151                         break;
1152           case WM_LBUTTONDBLCLK:
1153                         if (CC_MouseCheckResultWindow(hDlg,lParam))
1154                           return TRUE;
1155                         break;
1156           case WM_MOUSEMOVE:  /* FIXME: calculate new hue,sat,lum (if in color graph) */
1157                         break;
1158           case WM_LBUTTONUP:  /* FIXME: ClipCursor off (if in color graph)*/
1159                         break;
1160           case WM_LBUTTONDOWN:/* FIXME: ClipCursor on  (if in color graph)*/
1161                         if (CC_WMLButtonDown(hDlg, wParam, lParam))
1162                            return TRUE;
1163                         break;     
1164         }
1165      return FALSE ;
1166 }
1167
1168
1169 /***********************************************************************
1170  *            ChooseColorA  (COMDLG32.1)
1171  */
1172 BOOL WINAPI ChooseColorA(LPCHOOSECOLORA lpChCol )
1173
1174 {
1175   BOOL16 ret;
1176   char *str = NULL;
1177   COLORREF* ccref=SEGPTR_ALLOC(64);
1178   LPCHOOSECOLOR16 lpcc16=SEGPTR_ALLOC(sizeof(CHOOSECOLOR16));
1179
1180   memset(lpcc16,'\0',sizeof(*lpcc16));
1181   lpcc16->lStructSize=sizeof(*lpcc16);
1182   lpcc16->hwndOwner=lpChCol->hwndOwner;
1183   lpcc16->hInstance=MapHModuleLS(lpChCol->hInstance);
1184   lpcc16->rgbResult=lpChCol->rgbResult;
1185   memcpy(ccref,lpChCol->lpCustColors,64);
1186   lpcc16->lpCustColors=(COLORREF*)SEGPTR_GET(ccref);
1187   lpcc16->Flags=lpChCol->Flags;
1188   lpcc16->lCustData=lpChCol->lCustData;
1189   lpcc16->lpfnHook=(LPCCHOOKPROC16)lpChCol->lpfnHook;
1190   if (lpChCol->lpTemplateName)
1191     str = SEGPTR_STRDUP(lpChCol->lpTemplateName );
1192   lpcc16->lpTemplateName=SEGPTR_GET(str);
1193   
1194   ret = ChooseColor16(lpcc16);
1195
1196   if(ret)
1197       lpChCol->rgbResult = lpcc16->rgbResult;
1198
1199   if(str)
1200     SEGPTR_FREE(str);
1201   memcpy(lpChCol->lpCustColors,ccref,64);
1202   SEGPTR_FREE(ccref);
1203   SEGPTR_FREE(lpcc16);
1204   return (BOOL)ret;
1205 }
1206
1207 /***********************************************************************
1208  *            ChooseColorW  (COMDLG32.2)
1209  */
1210 BOOL WINAPI ChooseColorW(LPCHOOSECOLORW lpChCol )
1211
1212 {
1213   BOOL16 ret;
1214   char *str = NULL;
1215   COLORREF* ccref=SEGPTR_ALLOC(64);
1216   LPCHOOSECOLOR16 lpcc16=SEGPTR_ALLOC(sizeof(CHOOSECOLOR16));
1217
1218   memset(lpcc16,'\0',sizeof(*lpcc16));
1219   lpcc16->lStructSize=sizeof(*lpcc16);
1220   lpcc16->hwndOwner=lpChCol->hwndOwner;
1221   lpcc16->hInstance=MapHModuleLS(lpChCol->hInstance);
1222   lpcc16->rgbResult=lpChCol->rgbResult;
1223   memcpy(ccref,lpChCol->lpCustColors,64);
1224   lpcc16->lpCustColors=(COLORREF*)SEGPTR_GET(ccref);
1225   lpcc16->Flags=lpChCol->Flags;
1226   lpcc16->lCustData=lpChCol->lCustData;
1227   lpcc16->lpfnHook=(LPCCHOOKPROC16)lpChCol->lpfnHook;
1228   if (lpChCol->lpTemplateName)
1229     str = SEGPTR_STRDUP_WtoA(lpChCol->lpTemplateName );
1230   lpcc16->lpTemplateName=SEGPTR_GET(str);
1231   
1232   ret = ChooseColor16(lpcc16);
1233
1234   if(ret)
1235       lpChCol->rgbResult = lpcc16->rgbResult;
1236
1237   if(str)
1238     SEGPTR_FREE(str);
1239   memcpy(lpChCol->lpCustColors,ccref,64);
1240   SEGPTR_FREE(ccref);
1241   SEGPTR_FREE(lpcc16);
1242   return (BOOL)ret;
1243 }