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