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