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