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