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