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