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