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