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