Simplified wrc flags handling.
[wine.git] / dlls / commdlg / colordlg.c
blobf35f3022c7f15bfd47cef43d97274687b1014df9
1 /*
2 * COMMDLG - Color Dialog
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
6 */
8 #include <ctype.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include "windef.h"
13 #include "winbase.h"
14 #include "wingdi.h"
15 #include "wine/winbase16.h"
16 #include "wine/winuser16.h"
17 #include "ldt.h"
18 #include "heap.h"
19 #include "commdlg.h"
20 #include "dialog.h"
21 #include "dlgs.h"
22 #include "module.h"
23 #include "debugtools.h"
24 #include "winproc.h"
25 #include "cderr.h"
27 DEFAULT_DEBUG_CHANNEL(commdlg);
29 #include "cdlg.h"
31 static LRESULT WINAPI ColorDlgProc( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam );
33 #define CONV_POINTSTOPOINT( ps, p ) \
34 ((p)->x = (LONG)(ps)->x, (p)->y = (LONG)(ps)->y)
36 static const COLORREF predefcolors[6][8]=
38 { 0x008080FFL, 0x0080FFFFL, 0x0080FF80L, 0x0080FF00L,
39 0x00FFFF80L, 0x00FF8000L, 0x00C080FFL, 0x00FF80FFL },
40 { 0x000000FFL, 0x0000FFFFL, 0x0000FF80L, 0x0040FF00L,
41 0x00FFFF00L, 0x00C08000L, 0x00C08080L, 0x00FF00FFL },
43 { 0x00404080L, 0x004080FFL, 0x0000FF00L, 0x00808000L,
44 0x00804000L, 0x00FF8080L, 0x00400080L, 0x008000FFL },
45 { 0x00000080L, 0x000080FFL, 0x00008000L, 0x00408000L,
46 0x00FF0000L, 0x00A00000L, 0x00800080L, 0x00FF0080L },
48 { 0x00000040L, 0x00004080L, 0x00004000L, 0x00404000L,
49 0x00800000L, 0x00400000L, 0x00400040L, 0x00800040L },
50 { 0x00000000L, 0x00008080L, 0x00408080L, 0x00808080L,
51 0x00808040L, 0x00C0C0C0L, 0x00400040L, 0x00FFFFFFL },
54 struct CCPRIVATE
56 LPCHOOSECOLORW lpcc; /* points to public known data structure */
57 LPCHOOSECOLOR16 lpcc16; /* save the 16 bits pointer */
58 int nextuserdef; /* next free place in user defined color array */
59 HDC hdcMem; /* color graph used for BitBlt() */
60 HBITMAP hbmMem; /* color graph bitmap */
61 RECT fullsize; /* original dialog window size */
62 UINT msetrgb; /* # of SETRGBSTRING message (today not used) */
63 RECT old3angle; /* last position of l-marker */
64 RECT oldcross; /* last position of color/satuation marker */
65 BOOL updating; /* to prevent recursive WM_COMMAND/EN_UPDATE procesing */
66 int h;
67 int s;
68 int l; /* for temporary storing of hue,sat,lum */
69 int capturedGraph; /* control mouse captured */
72 /***********************************************************************
73 * CC_HSLtoRGB [internal]
75 static int CC_HSLtoRGB(char c, int hue, int sat, int lum)
77 int res = 0, maxrgb;
79 /* hue */
80 switch(c)
82 case 'R': if (hue > 80) hue -= 80; else hue += 160; break;
83 case 'G': if (hue > 160) hue -= 160; else hue += 80; break;
84 case 'B': break;
87 /* l below 120 */
88 maxrgb = (256 * min(120,lum)) / 120; /* 0 .. 256 */
89 if (hue < 80)
90 res = 0;
91 else
92 if (hue < 120)
94 res = (hue - 80) * maxrgb; /* 0...10240 */
95 res /= 40; /* 0...256 */
97 else
98 if (hue < 200)
99 res = maxrgb;
100 else
102 res= (240 - hue) * maxrgb;
103 res /= 40;
105 res = res - maxrgb / 2; /* -128...128 */
107 /* saturation */
108 res = maxrgb / 2 + (sat * res) / 240; /* 0..256 */
110 /* lum above 120 */
111 if (lum > 120 && res < 256)
112 res += ((lum - 120) * (256 - res)) / 120;
114 return min(res, 255);
117 /***********************************************************************
118 * CC_RGBtoHSL [internal]
120 static int CC_RGBtoHSL(char c, int r, int g, int b)
122 WORD maxi, mini, mmsum, mmdif, result = 0;
123 int iresult = 0;
125 maxi = max(r, b);
126 maxi = max(maxi, g);
127 mini = min(r, b);
128 mini = min(mini, g);
130 mmsum = maxi + mini;
131 mmdif = maxi - mini;
133 switch(c)
135 /* lum */
136 case 'L': mmsum *= 120; /* 0...61200=(255+255)*120 */
137 result = mmsum / 255; /* 0...240 */
138 break;
139 /* saturation */
140 case 'S': if (!mmsum)
141 result = 0;
142 else
143 if (!mini || maxi == 255)
144 result = 240;
145 else
147 result = mmdif * 240; /* 0...61200=255*240 */
148 result /= (mmsum > 255 ? mmsum = 510 - mmsum : mmsum); /* 0..255 */
150 break;
151 /* hue */
152 case 'H': if (!mmdif)
153 result = 160;
154 else
156 if (maxi == r)
158 iresult = 40 * (g - b); /* -10200 ... 10200 */
159 iresult /= (int) mmdif; /* -40 .. 40 */
160 if (iresult < 0)
161 iresult += 240; /* 0..40 and 200..240 */
163 else
164 if (maxi == g)
166 iresult = 40 * (b - r);
167 iresult /= (int) mmdif;
168 iresult += 80; /* 40 .. 120 */
170 else
171 if (maxi == b)
173 iresult = 40 * (r - g);
174 iresult /= (int) mmdif;
175 iresult += 160; /* 120 .. 200 */
177 result = iresult;
179 break;
181 return result; /* is this integer arithmetic precise enough ? */
184 #define DISTANCE 4
186 /***********************************************************************
187 * CC_MouseCheckPredefColorArray [internal]
188 * returns 1 if one of the predefined colors is clicked
189 * the choosen color is returned in *cr
191 static int CC_MouseCheckPredefColorArray( HWND hDlg, int dlgitem, int rows, int cols,
192 LPARAM lParam, COLORREF *cr )
194 HWND hwnd;
195 POINT point;
196 RECT rect;
197 int dx, dy, x, y;
199 CONV_POINTSTOPOINT(&(MAKEPOINTS(lParam)) , &point);
200 ClientToScreen(hDlg, &point);
201 hwnd = GetDlgItem(hDlg, dlgitem);
202 GetWindowRect(hwnd, &rect);
203 if (PtInRect(&rect, point))
205 dx = (rect.right - rect.left) / cols;
206 dy = (rect.bottom - rect.top) / rows;
207 ScreenToClient(hwnd, &point);
209 if (point.x % dx < ( dx - DISTANCE) && point.y % dy < ( dy - DISTANCE))
211 x = point.x / dx;
212 y = point.y / dy;
213 *cr = predefcolors[y][x];
214 /* FIXME: Draw_a_Focus_Rect() */
215 return 1;
218 return 0;
221 /***********************************************************************
222 * CC_MouseCheckUserColorArray [internal]
223 * return 1 if the user clicked a color (returned in *cr)
225 static int CC_MouseCheckUserColorArray( HWND hDlg, int dlgitem, int rows, int cols,
226 LPARAM lParam, COLORREF *cr, COLORREF*crarr )
228 HWND hwnd;
229 POINT point;
230 RECT rect;
231 int dx, dy, x, y;
233 CONV_POINTSTOPOINT(&(MAKEPOINTS(lParam)), &point);
234 ClientToScreen(hDlg, &point);
235 hwnd=GetDlgItem(hDlg, dlgitem);
236 GetWindowRect(hwnd, &rect);
237 if (PtInRect(&rect, point))
239 dx = (rect.right - rect.left) / cols;
240 dy = (rect.bottom - rect.top) / rows;
241 ScreenToClient(hwnd, &point);
243 if (point.x % dx < (dx - DISTANCE) && point.y % dy < (dy - DISTANCE))
245 x = point.x / dx;
246 y = point.y / dy;
247 *cr = crarr[x+cols*y];
248 /* FIXME: Draw_a_Focus_Rect() */
249 return 1;
252 return 0;
255 #define MAXVERT 240
256 #define MAXHORI 239
258 /* 240 ^...... ^^ 240
259 | . ||
260 SAT | . || LUM
261 | . ||
262 +-----> 239 ----
265 /***********************************************************************
266 * CC_MouseCheckColorGraph [internal]
268 static int CC_MouseCheckColorGraph( HWND hDlg, int dlgitem, int *hori, int *vert, LPARAM lParam )
270 HWND hwnd;
271 POINT point;
272 RECT rect;
273 long x,y;
275 CONV_POINTSTOPOINT(&(MAKEPOINTS(lParam)), &point);
276 ClientToScreen(hDlg, &point);
277 hwnd = GetDlgItem( hDlg, dlgitem );
278 GetWindowRect(hwnd, &rect);
279 if (PtInRect(&rect, point))
281 GetClientRect(hwnd, &rect);
282 ScreenToClient(hwnd, &point);
284 x = (long) point.x * MAXHORI;
285 x /= rect.right;
286 y = (long) (rect.bottom - point.y) * MAXVERT;
287 y /= rect.bottom;
289 if (hori)
290 *hori = x;
291 if (vert)
292 *vert = y;
293 return 1;
295 else
296 return 0;
298 /***********************************************************************
299 * CC_MouseCheckResultWindow [internal]
300 * test if double click one of the result colors
302 static int CC_MouseCheckResultWindow( HWND hDlg, LPARAM lParam )
304 HWND hwnd;
305 POINT point;
306 RECT rect;
308 CONV_POINTSTOPOINT(&(MAKEPOINTS(lParam)), &point);
309 ClientToScreen(hDlg, &point);
310 hwnd = GetDlgItem(hDlg, 0x2c5);
311 GetWindowRect(hwnd, &rect);
312 if (PtInRect(&rect, point))
314 PostMessageA(hDlg, WM_COMMAND, 0x2c9, 0);
315 return 1;
317 return 0;
320 /***********************************************************************
321 * CC_CheckDigitsInEdit [internal]
323 static int CC_CheckDigitsInEdit( HWND hwnd, int maxval )
325 int i, k, m, result, value;
326 long editpos;
327 char buffer[30];
329 GetWindowTextA(hwnd, buffer, sizeof(buffer));
330 m = strlen(buffer);
331 result = 0;
333 for (i = 0 ; i < m ; i++)
334 if (buffer[i] < '0' || buffer[i] > '9')
336 for (k = i + 1; k <= m; k++) /* delete bad character */
338 buffer[i] = buffer[k];
339 m--;
341 buffer[m] = 0;
342 result = 1;
345 value = atoi(buffer);
346 if (value > maxval) /* build a new string */
348 sprintf(buffer, "%d", maxval);
349 result = 2;
351 if (result)
353 editpos = SendMessageA(hwnd, EM_GETSEL, 0, 0);
354 SetWindowTextA(hwnd, buffer );
355 SendMessageA(hwnd, EM_SETSEL, 0, editpos);
357 return value;
362 /***********************************************************************
363 * CC_PaintSelectedColor [internal]
365 static void CC_PaintSelectedColor( HWND hDlg, COLORREF cr )
367 RECT rect;
368 HDC hdc;
369 HBRUSH hBrush;
370 HWND hwnd = GetDlgItem(hDlg, 0x2c5);
371 if (IsWindowVisible( GetDlgItem(hDlg, 0x2c6) )) /* if full size */
373 hdc = GetDC(hwnd);
374 GetClientRect(hwnd, &rect) ;
375 hBrush = CreateSolidBrush(cr);
376 if (hBrush)
378 hBrush = SelectObject(hdc, hBrush) ;
379 Rectangle(hdc, rect.left, rect.top, rect.right/2, rect.bottom);
380 DeleteObject ( SelectObject(hdc, hBrush) ) ;
381 hBrush = CreateSolidBrush( GetNearestColor(hdc, cr) );
382 if (hBrush)
384 hBrush = SelectObject(hdc, hBrush) ;
385 Rectangle(hdc, rect.right/2-1, rect.top, rect.right, rect.bottom);
386 DeleteObject(SelectObject(hdc, hBrush)) ;
389 ReleaseDC(hwnd, hdc);
393 /***********************************************************************
394 * CC_PaintTriangle [internal]
396 static void CC_PaintTriangle( HWND hDlg, int y)
398 HDC hDC;
399 long temp;
400 int w = GetDialogBaseUnits();
401 POINT points[3];
402 int height;
403 int oben;
404 RECT rect;
405 HWND hwnd = GetDlgItem(hDlg, 0x2be);
406 struct CCPRIVATE *lpp = (struct CCPRIVATE *)GetWindowLongA( hDlg, DWL_USER);
408 if (IsWindowVisible( GetDlgItem(hDlg, 0x2c6))) /* if full size */
410 GetClientRect(hwnd, &rect);
411 height = rect.bottom;
412 hDC = GetDC(hDlg);
413 points[0].y = rect.top;
414 points[0].x = rect.right; /* | /| */
415 ClientToScreen(hwnd, points); /* | / | */
416 ScreenToClient(hDlg, points); /* |< | */
417 oben = points[0].y; /* | \ | */
418 /* | \| */
419 temp = (long)height * (long)y;
420 points[0].y = oben + height - temp / (long)MAXVERT;
421 points[1].y = points[0].y + w;
422 points[2].y = points[0].y - w;
423 points[2].x = points[1].x = points[0].x + w;
425 FillRect(hDC, &lpp->old3angle, GetClassLongA( hwnd, GCL_HBRBACKGROUND));
426 lpp->old3angle.left = points[0].x;
427 lpp->old3angle.right = points[1].x + 1;
428 lpp->old3angle.top = points[2].y - 1;
429 lpp->old3angle.bottom= points[1].y + 1;
430 Polygon(hDC, points, 3);
431 ReleaseDC(hDlg, hDC);
436 /***********************************************************************
437 * CC_PaintCross [internal]
439 static void CC_PaintCross( HWND hDlg, int x, int y)
441 HDC hDC;
442 int w = GetDialogBaseUnits();
443 HWND hwnd = GetDlgItem(hDlg, 0x2c6);
444 struct CCPRIVATE * lpp = (struct CCPRIVATE *)GetWindowLongA( hDlg, DWL_USER );
445 RECT rect;
446 POINT point, p;
447 HPEN hPen;
449 if (IsWindowVisible( GetDlgItem(hDlg, 0x2c6) )) /* if full size */
451 GetClientRect(hwnd, &rect);
452 hDC = GetDC(hwnd);
453 SelectClipRgn( hDC, CreateRectRgnIndirect(&rect));
454 hPen = CreatePen(PS_SOLID, 2, 0);
455 hPen = SelectObject(hDC, hPen);
456 point.x = ((long)rect.right * (long)x) / (long)MAXHORI;
457 point.y = rect.bottom - ((long)rect.bottom * (long)y) / (long)MAXVERT;
458 if ( lpp->oldcross.left != lpp->oldcross.right )
459 BitBlt(hDC, lpp->oldcross.left, lpp->oldcross.top,
460 lpp->oldcross.right - lpp->oldcross.left,
461 lpp->oldcross.bottom - lpp->oldcross.top,
462 lpp->hdcMem, lpp->oldcross.left, lpp->oldcross.top, SRCCOPY);
463 lpp->oldcross.left = point.x - w - 1;
464 lpp->oldcross.right = point.x + w + 1;
465 lpp->oldcross.top = point.y - w - 1;
466 lpp->oldcross.bottom = point.y + w + 1;
468 MoveToEx(hDC, point.x - w, point.y, &p);
469 LineTo(hDC, point.x + w, point.y);
470 MoveToEx(hDC, point.x, point.y - w, &p);
471 LineTo(hDC, point.x, point.y + w);
472 DeleteObject( SelectObject(hDC, hPen)) ;
473 ReleaseDC(hwnd, hDC);
478 #define XSTEPS 48
479 #define YSTEPS 24
482 /***********************************************************************
483 * CC_PrepareColorGraph [internal]
485 static void CC_PrepareColorGraph( HWND hDlg )
487 int sdif, hdif, xdif, ydif, r, g, b, hue, sat;
488 HWND hwnd = GetDlgItem(hDlg, 0x2c6);
489 struct CCPRIVATE * lpp = (struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
490 HBRUSH hbrush;
491 HDC hdc ;
492 RECT rect, client;
493 HCURSOR hcursor = SetCursor( LoadCursorA(0, IDC_WAITA) );
495 GetClientRect(hwnd, &client);
496 hdc = GetDC(hwnd);
497 lpp->hdcMem = CreateCompatibleDC(hdc);
498 lpp->hbmMem = CreateCompatibleBitmap(hdc, client.right, client.bottom);
499 SelectObject(lpp->hdcMem, lpp->hbmMem);
501 xdif = client.right / XSTEPS;
502 ydif = client.bottom / YSTEPS+1;
503 hdif = 239 / XSTEPS;
504 sdif = 240 / YSTEPS;
505 for (rect.left = hue = 0; hue < 239 + hdif; hue += hdif)
507 rect.right = rect.left + xdif;
508 rect.bottom = client.bottom;
509 for(sat = 0; sat < 240 + sdif; sat += sdif)
511 rect.top = rect.bottom - ydif;
512 r = CC_HSLtoRGB('R', hue, sat, 120);
513 g = CC_HSLtoRGB('G', hue, sat, 120);
514 b = CC_HSLtoRGB('B', hue, sat, 120);
515 hbrush = CreateSolidBrush( RGB(r, g, b));
516 FillRect(lpp->hdcMem, &rect, hbrush);
517 DeleteObject(hbrush);
518 rect.bottom = rect.top;
520 rect.left = rect.right;
522 ReleaseDC(hwnd, hdc);
523 SetCursor(hcursor);
526 /***********************************************************************
527 * CC_PaintColorGraph [internal]
529 static void CC_PaintColorGraph( HWND hDlg )
531 HWND hwnd = GetDlgItem( hDlg, 0x2c6 );
532 struct CCPRIVATE * lpp = (struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
533 HDC hDC;
534 RECT rect;
535 if (IsWindowVisible(hwnd)) /* if full size */
537 if (!lpp->hdcMem)
538 CC_PrepareColorGraph(hDlg); /* should not be necessary */
540 hDC = GetDC(hwnd);
541 GetClientRect(hwnd, &rect);
542 if (lpp->hdcMem)
543 BitBlt(hDC, 0, 0, rect.right, rect.bottom, lpp->hdcMem, 0, 0, SRCCOPY);
544 else
545 WARN("choose color: hdcMem is not defined\n");
546 ReleaseDC(hwnd, hDC);
550 /***********************************************************************
551 * CC_PaintLumBar [internal]
553 static void CC_PaintLumBar( HWND hDlg, int hue, int sat )
555 HWND hwnd = GetDlgItem(hDlg, 0x2be);
556 RECT rect, client;
557 int lum, ldif, ydif, r, g, b;
558 HBRUSH hbrush;
559 HDC hDC;
561 if (IsWindowVisible(hwnd))
563 hDC = GetDC(hwnd);
564 GetClientRect(hwnd, &client);
565 rect = client;
567 ldif = 240 / YSTEPS;
568 ydif = client.bottom / YSTEPS+1;
569 for (lum = 0; lum < 240 + ldif; lum += ldif)
571 rect.top = max(0, rect.bottom - ydif);
572 r = CC_HSLtoRGB('R', hue, sat, lum);
573 g = CC_HSLtoRGB('G', hue, sat, lum);
574 b = CC_HSLtoRGB('B', hue, sat, lum);
575 hbrush = CreateSolidBrush( RGB(r, g, b) );
576 FillRect(hDC, &rect, hbrush);
577 DeleteObject(hbrush);
578 rect.bottom = rect.top;
580 GetClientRect(hwnd, &rect);
581 FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH) );
582 ReleaseDC(hwnd, hDC);
586 /***********************************************************************
587 * CC_EditSetRGB [internal]
589 static void CC_EditSetRGB( HWND hDlg, COLORREF cr )
591 char buffer[10];
592 struct CCPRIVATE * lpp = (struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
593 int r = GetRValue(cr);
594 int g = GetGValue(cr);
595 int b = GetBValue(cr);
596 if (IsWindowVisible( GetDlgItem(hDlg, 0x2c6) )) /* if full size */
598 lpp->updating = TRUE;
599 sprintf(buffer, "%d", r);
600 SetWindowTextA( GetDlgItem(hDlg, 0x2c2), buffer);
601 sprintf(buffer, "%d", g);
602 SetWindowTextA( GetDlgItem(hDlg, 0x2c3), buffer);
603 sprintf( buffer, "%d", b );
604 SetWindowTextA( GetDlgItem(hDlg, 0x2c4),buffer);
605 lpp->updating = FALSE;
609 /***********************************************************************
610 * CC_EditSetHSL [internal]
612 static void CC_EditSetHSL( HWND hDlg, int h, int s, int l )
614 char buffer[10];
615 struct CCPRIVATE * lpp = (struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
616 lpp->updating = TRUE;
617 if (IsWindowVisible( GetDlgItem(hDlg, 0x2c6) )) /* if full size */
619 lpp->updating = TRUE;
620 sprintf(buffer, "%d", h);
621 SetWindowTextA( GetDlgItem(hDlg, 0x2bf), buffer);
622 sprintf(buffer, "%d", s);
623 SetWindowTextA( GetDlgItem(hDlg, 0x2c0), buffer);
624 sprintf(buffer, "%d", l);
625 SetWindowTextA( GetDlgItem(hDlg, 0x2c1), buffer);
626 lpp->updating = FALSE;
628 CC_PaintLumBar(hDlg, h, s);
631 /***********************************************************************
632 * CC_SwitchToFullSize [internal]
634 static void CC_SwitchToFullSize( HWND hDlg, COLORREF result, LPRECT lprect )
636 int i;
637 struct CCPRIVATE * lpp = (struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
639 EnableWindow( GetDlgItem(hDlg, 0x2cf), FALSE);
640 CC_PrepareColorGraph(hDlg);
641 for (i = 0x2bf; i < 0x2c5; i++)
642 ShowWindow( GetDlgItem(hDlg, i), SW_SHOW);
643 for (i = 0x2d3; i < 0x2d9; i++)
644 ShowWindow( GetDlgItem(hDlg, i), SW_SHOW);
645 ShowWindow( GetDlgItem(hDlg, 0x2c9), SW_SHOW);
646 ShowWindow( GetDlgItem(hDlg, 0x2c8), SW_SHOW);
647 ShowWindow( GetDlgItem(hDlg, 1090), SW_SHOW);
649 if (lprect)
650 SetWindowPos(hDlg, 0, 0, 0, lprect->right-lprect->left,
651 lprect->bottom-lprect->top, SWP_NOMOVE|SWP_NOZORDER);
653 ShowWindow( GetDlgItem(hDlg, 0x2be), SW_SHOW);
654 ShowWindow( GetDlgItem(hDlg, 0x2c5), SW_SHOW);
656 CC_EditSetRGB(hDlg, result);
657 CC_EditSetHSL(hDlg, lpp->h, lpp->s, lpp->l);
658 ShowWindow( GetDlgItem( hDlg, 0x2c6), SW_SHOW);
659 UpdateWindow( GetDlgItem(hDlg, 0x2c6) );
662 /***********************************************************************
663 * CC_PaintPredefColorArray [internal]
664 * Paints the default standard 48 colors
666 static void CC_PaintPredefColorArray( HWND hDlg, int rows, int cols)
668 HWND hwnd = GetDlgItem(hDlg, 0x2d0);
669 RECT rect;
670 HDC hdc;
671 HBRUSH hBrush;
672 int dx, dy, i, j, k;
674 GetClientRect(hwnd, &rect);
675 dx = rect.right / cols;
676 dy = rect.bottom / rows;
677 k = rect.left;
679 hdc = GetDC(hwnd);
680 GetClientRect(hwnd, &rect);
681 FillRect(hdc, &rect, GetClassLongA(hwnd, GCL_HBRBACKGROUND));
682 for ( j = 0; j < rows; j++ )
684 for ( i = 0; i < cols; i++ )
686 hBrush = CreateSolidBrush(predefcolors[j][i]);
687 if (hBrush)
689 hBrush = SelectObject(hdc, hBrush);
690 Rectangle(hdc, rect.left, rect.top,
691 rect.left + dx - DISTANCE, rect.top + dy - DISTANCE);
692 rect.left = rect.left + dx;
693 DeleteObject(SelectObject(hdc, hBrush)) ;
696 rect.top = rect.top + dy;
697 rect.left = k;
699 ReleaseDC(hwnd, hdc);
700 /* FIXME: draw_a_focus_rect */
702 /***********************************************************************
703 * CC_PaintUserColorArray [internal]
704 * Paint the 16 user-selected colors
706 static void CC_PaintUserColorArray( HWND hDlg, int rows, int cols, COLORREF* lpcr )
708 HWND hwnd = GetDlgItem(hDlg, 0x2d1);
709 RECT rect;
710 HDC hdc;
711 HBRUSH hBrush;
712 int dx, dy, i, j, k;
714 GetClientRect(hwnd, &rect);
716 dx = rect.right / cols;
717 dy = rect.bottom / rows;
718 k = rect.left;
720 hdc = GetDC(hwnd);
721 if (hdc)
723 FillRect(hdc, &rect, GetClassLongA(hwnd, GCL_HBRBACKGROUND) );
724 for (j = 0; j < rows; j++)
726 for (i = 0; i < cols; i++)
728 hBrush = CreateSolidBrush(lpcr[i+j*cols]);
729 if (hBrush)
731 hBrush = SelectObject(hdc, hBrush) ;
732 Rectangle(hdc, rect.left, rect.top,
733 rect.left + dx - DISTANCE, rect.top + dy - DISTANCE);
734 rect.left = rect.left + dx;
735 DeleteObject( SelectObject(hdc, hBrush) ) ;
738 rect.top = rect.top + dy;
739 rect.left = k;
741 ReleaseDC(hwnd, hdc);
743 /* FIXME: draw_a_focus_rect */
748 /***********************************************************************
749 * CC_HookCallChk [internal]
751 static BOOL CC_HookCallChk( LPCHOOSECOLORW lpcc )
753 if (lpcc)
754 if(lpcc->Flags & CC_ENABLEHOOK)
755 if (lpcc->lpfnHook)
756 return TRUE;
757 return FALSE;
761 /***********************************************************************
762 * CC_WMInitDialog [internal]
764 static LONG CC_WMInitDialog( HWND hDlg, WPARAM wParam, LPARAM lParam, BOOL b16 )
766 int i, res;
767 int r, g, b;
768 HWND hwnd;
769 RECT rect;
770 POINT point;
771 struct CCPRIVATE * lpp;
773 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
774 lpp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct CCPRIVATE) );
775 if (b16)
777 CHOOSECOLORW *ch32;
778 CHOOSECOLOR16 *ch16 = (CHOOSECOLOR16 *) lParam;
779 ch32 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CHOOSECOLORW) );
780 lpp->lpcc = ch32;
781 lpp->lpcc16 = ch16;
782 if (lpp->lpcc16->lStructSize != sizeof(CHOOSECOLOR16) )
784 EndDialog (hDlg, 0) ;
785 return FALSE;
787 ch32->lStructSize = sizeof(CHOOSECOLORW);
788 ch32->hwndOwner = ch16->hwndOwner;
789 ch32->hInstance = ch16->hInstance;
790 ch32->lpCustColors = PTR_SEG_TO_LIN(ch16->lpCustColors);
791 ch32->lpfnHook = (LPCCHOOKPROC) ch16->lpfnHook; /* only used as flag */
792 ch32->Flags = ch16->Flags;
794 else
795 lpp->lpcc = (LPCHOOSECOLORW) lParam;
797 if (lpp->lpcc->lStructSize != sizeof(CHOOSECOLORW) )
799 EndDialog (hDlg, 0) ;
800 return FALSE;
802 SetWindowLongA(hDlg, DWL_USER, (LONG)lpp);
804 if (!(lpp->lpcc->Flags & CC_SHOWHELP))
805 ShowWindow( GetDlgItem(hDlg,0x40e), SW_HIDE);
806 lpp->msetrgb = RegisterWindowMessageA(SETRGBSTRING);
808 #if 0
809 cpos = MAKELONG(5,7); /* init */
810 if (lpp->lpcc->Flags & CC_RGBINIT)
812 for (i = 0; i < 6; i++)
813 for (j = 0; j < 8; j++)
814 if (predefcolors[i][j] == lpp->lpcc->rgbResult)
816 cpos = MAKELONG(i,j);
817 goto found;
820 found:
821 /* FIXME: Draw_a_focus_rect & set_init_values */
822 #endif
824 GetWindowRect(hDlg, &lpp->fullsize);
825 if (lpp->lpcc->Flags & CC_FULLOPEN || lpp->lpcc->Flags & CC_PREVENTFULLOPEN)
827 hwnd = GetDlgItem(hDlg, 0x2cf);
828 EnableWindow(hwnd, FALSE);
830 if (!(lpp->lpcc->Flags & CC_FULLOPEN ) || lpp->lpcc->Flags & CC_PREVENTFULLOPEN)
832 rect = lpp->fullsize;
833 res = rect.bottom - rect.top;
834 hwnd = GetDlgItem(hDlg, 0x2c6); /* cut at left border */
835 point.x = point.y = 0;
836 ClientToScreen(hwnd, &point);
837 ScreenToClient(hDlg,&point);
838 GetClientRect(hDlg, &rect);
839 point.x += GetSystemMetrics(SM_CXDLGFRAME);
840 SetWindowPos(hDlg, 0, 0, 0, point.x, res, SWP_NOMOVE|SWP_NOZORDER);
842 for (i = 0x2bf; i < 0x2c5; i++)
843 ShowWindow( GetDlgItem(hDlg, i), SW_HIDE);
844 for (i = 0x2d3; i < 0x2d9; i++)
845 ShowWindow( GetDlgItem(hDlg, i), SW_HIDE);
846 ShowWindow( GetDlgItem(hDlg, 0x2c9), SW_HIDE);
847 ShowWindow( GetDlgItem(hDlg, 0x2c8), SW_HIDE);
848 ShowWindow( GetDlgItem(hDlg, 0x2c6), SW_HIDE);
849 ShowWindow( GetDlgItem(hDlg, 0x2c5), SW_HIDE);
850 ShowWindow( GetDlgItem(hDlg, 1090 ), SW_HIDE);
852 else
853 CC_SwitchToFullSize(hDlg, lpp->lpcc->rgbResult, NULL);
854 res=TRUE;
855 for (i = 0x2bf; i < 0x2c5; i++)
856 SendMessageA( GetDlgItem(hDlg, i), EM_LIMITTEXT, 3, 0); /* max 3 digits: xyz */
857 if (CC_HookCallChk(lpp->lpcc))
859 if (b16)
860 res = CallWindowProc16( (WNDPROC16)lpp->lpcc16->lpfnHook, hDlg, WM_INITDIALOG, wParam, lParam);
861 else
862 res = CallWindowProcA( (WNDPROC)lpp->lpcc->lpfnHook, hDlg, WM_INITDIALOG, wParam, lParam);
865 /* Set the initial values of the color chooser dialog */
866 r = GetRValue(lpp->lpcc->rgbResult);
867 g = GetGValue(lpp->lpcc->rgbResult);
868 b = GetBValue(lpp->lpcc->rgbResult);
870 CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult);
871 lpp->h = CC_RGBtoHSL('H', r, g, b);
872 lpp->s = CC_RGBtoHSL('S', r, g, b);
873 lpp->l = CC_RGBtoHSL('L', r, g, b);
875 /* Doing it the long way becaus CC_EditSetRGB/HSL doesn'nt seem to work */
876 SetDlgItemInt(hDlg, 703, lpp->h, TRUE);
877 SetDlgItemInt(hDlg, 704, lpp->s, TRUE);
878 SetDlgItemInt(hDlg, 705, lpp->l, TRUE);
879 SetDlgItemInt(hDlg, 706, r, TRUE);
880 SetDlgItemInt(hDlg, 707, g, TRUE);
881 SetDlgItemInt(hDlg, 708, b, TRUE);
883 CC_PaintCross(hDlg, lpp->h, lpp->s);
884 CC_PaintTriangle(hDlg, lpp->l);
886 return res;
890 /***********************************************************************
891 * CC_WMCommand [internal]
893 static LRESULT CC_WMCommand( HWND hDlg, WPARAM wParam, LPARAM lParam, WORD notifyCode, HWND hwndCtl )
895 int r, g, b, i, xx;
896 UINT cokmsg;
897 HDC hdc;
898 COLORREF *cr;
899 struct CCPRIVATE * lpp = (struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
900 TRACE("CC_WMCommand wParam=%x lParam=%lx\n", wParam, lParam);
901 switch (wParam)
903 case 0x2c2: /* edit notify RGB */
904 case 0x2c3:
905 case 0x2c4:
906 if (notifyCode == EN_UPDATE && !lpp->updating)
908 i = CC_CheckDigitsInEdit(hwndCtl, 255);
909 r = GetRValue(lpp->lpcc->rgbResult);
910 g = GetGValue(lpp->lpcc->rgbResult);
911 b= GetBValue(lpp->lpcc->rgbResult);
912 xx = 0;
913 switch (wParam)
915 case 0x2c2: if ((xx = (i != r))) r = i; break;
916 case 0x2c3: if ((xx = (i != g))) g = i; break;
917 case 0x2c4: if ((xx = (i != b))) b = i; break;
919 if (xx) /* something has changed */
921 lpp->lpcc->rgbResult = RGB(r, g, b);
922 CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult);
923 lpp->h = CC_RGBtoHSL('H', r, g, b);
924 lpp->s = CC_RGBtoHSL('S', r, g, b);
925 lpp->l = CC_RGBtoHSL('L', r, g, b);
926 CC_EditSetHSL(hDlg, lpp->h, lpp->s, lpp->l);
927 CC_PaintCross(hDlg, lpp->h, lpp->s);
928 CC_PaintTriangle(hDlg, lpp->l);
931 break;
933 case 0x2bf: /* edit notify HSL */
934 case 0x2c0:
935 case 0x2c1:
936 if (notifyCode == EN_UPDATE && !lpp->updating)
938 i = CC_CheckDigitsInEdit(hwndCtl , wParam == 0x2bf ? 239:240);
939 xx = 0;
940 switch (wParam)
942 case 0x2bf: if ((xx = ( i != lpp->h))) lpp->h = i; break;
943 case 0x2c0: if ((xx = ( i != lpp->s))) lpp->s = i; break;
944 case 0x2c1: if ((xx = ( i != lpp->l))) lpp->l = i; break;
946 if (xx) /* something has changed */
948 r = CC_HSLtoRGB('R', lpp->h, lpp->s, lpp->l);
949 g = CC_HSLtoRGB('G', lpp->h, lpp->s, lpp->l);
950 b = CC_HSLtoRGB('B', lpp->h, lpp->s, lpp->l);
951 lpp->lpcc->rgbResult = RGB(r, g, b);
952 CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult);
953 CC_EditSetRGB(hDlg, lpp->lpcc->rgbResult);
954 CC_PaintCross(hDlg, lpp->h, lpp->s);
955 CC_PaintTriangle(hDlg, lpp->l);
958 break;
960 case 0x2cf:
961 CC_SwitchToFullSize(hDlg, lpp->lpcc->rgbResult, &lpp->fullsize);
962 SetFocus( GetDlgItem(hDlg, 0x2bf));
963 break;
965 case 0x2c8: /* add colors ... column by column */
966 cr = lpp->lpcc->lpCustColors;
967 cr[(lpp->nextuserdef % 2) * 8 + lpp->nextuserdef / 2] = lpp->lpcc->rgbResult;
968 if (++lpp->nextuserdef == 16)
969 lpp->nextuserdef = 0;
970 CC_PaintUserColorArray(hDlg, 2, 8, lpp->lpcc->lpCustColors);
971 break;
973 case 0x2c9: /* resulting color */
974 hdc = GetDC(hDlg);
975 lpp->lpcc->rgbResult = GetNearestColor(hdc, lpp->lpcc->rgbResult);
976 ReleaseDC(hDlg, hdc);
977 CC_EditSetRGB(hDlg, lpp->lpcc->rgbResult);
978 CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult);
979 r = GetRValue(lpp->lpcc->rgbResult);
980 g = GetGValue(lpp->lpcc->rgbResult);
981 b = GetBValue(lpp->lpcc->rgbResult);
982 lpp->h = CC_RGBtoHSL('H', r, g, b);
983 lpp->s = CC_RGBtoHSL('S', r, g, b);
984 lpp->l = CC_RGBtoHSL('L', r, g, b);
985 CC_EditSetHSL(hDlg, lpp->h, lpp->s, lpp->l);
986 CC_PaintCross(hDlg, lpp->h, lpp->s);
987 CC_PaintTriangle(hDlg, lpp->l);
988 break;
990 case 0x40e: /* Help! */ /* The Beatles, 1965 ;-) */
991 i = RegisterWindowMessageA(HELPMSGSTRING);
992 if (lpp->lpcc16)
994 if (lpp->lpcc->hwndOwner)
995 SendMessage16(lpp->lpcc->hwndOwner, i, 0, (LPARAM)lpp->lpcc16);
996 if ( CC_HookCallChk(lpp->lpcc))
997 CallWindowProc16( (WNDPROC16) lpp->lpcc16->lpfnHook, hDlg,
998 WM_COMMAND, psh15, (LPARAM)lpp->lpcc16);
1000 else
1002 if (lpp->lpcc->hwndOwner)
1003 SendMessageA(lpp->lpcc->hwndOwner, i, 0, (LPARAM)lpp->lpcc);
1004 if ( CC_HookCallChk(lpp->lpcc))
1005 CallWindowProcA( (WNDPROC) lpp->lpcc->lpfnHook, hDlg,
1006 WM_COMMAND, psh15, (LPARAM)lpp->lpcc);
1008 break;
1010 case IDOK :
1011 cokmsg = RegisterWindowMessageA(COLOROKSTRING);
1012 if (lpp->lpcc16)
1014 if (lpp->lpcc->hwndOwner)
1015 if (SendMessage16(lpp->lpcc->hwndOwner, cokmsg, 0, (LPARAM)lpp->lpcc16))
1016 break; /* do NOT close */
1018 else
1020 if (lpp->lpcc->hwndOwner)
1021 if (SendMessageA(lpp->lpcc->hwndOwner, cokmsg, 0, (LPARAM)lpp->lpcc))
1022 break; /* do NOT close */
1024 if (lpp->lpcc16)
1026 BYTE *ptr = PTR_SEG_TO_LIN(lpp->lpcc16->lpCustColors);
1027 memcpy(ptr, lpp->lpcc->lpCustColors, sizeof(COLORREF)*16);
1028 lpp->lpcc16->rgbResult = lpp->lpcc->rgbResult;
1030 EndDialog(hDlg, 1) ;
1031 return TRUE ;
1033 case IDCANCEL :
1034 EndDialog(hDlg, 0) ;
1035 return TRUE ;
1038 return FALSE;
1041 /***********************************************************************
1042 * CC_WMPaint [internal]
1044 static LRESULT CC_WMPaint( HWND hDlg, WPARAM wParam, LPARAM lParam )
1046 HDC hdc;
1047 PAINTSTRUCT ps;
1048 struct CCPRIVATE * lpp = (struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
1050 hdc = BeginPaint(hDlg, &ps);
1051 EndPaint(hDlg, &ps);
1052 /* we have to paint dialog children except text and buttons */
1053 CC_PaintPredefColorArray(hDlg, 6, 8);
1054 CC_PaintUserColorArray(hDlg, 2, 8, lpp->lpcc->lpCustColors);
1055 CC_PaintLumBar(hDlg, lpp->h, lpp->s);
1056 CC_PaintCross(hDlg, lpp->h, lpp->s);
1057 CC_PaintTriangle(hDlg, lpp->l);
1058 CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult);
1059 CC_PaintColorGraph(hDlg);
1061 /* special necessary for Wine */
1062 ValidateRect( GetDlgItem(hDlg, 0x2d0), NULL);
1063 ValidateRect( GetDlgItem(hDlg, 0x2d1), NULL);
1064 ValidateRect( GetDlgItem(hDlg, 0x2be), NULL);
1065 ValidateRect( GetDlgItem(hDlg, 0x2c5), NULL);
1066 ValidateRect( GetDlgItem(hDlg, 0x2c6), NULL);
1067 /* hope we can remove it later -->FIXME */
1068 return TRUE;
1072 /***********************************************************************
1073 * CC_WMLButtonUp [internal]
1075 static LRESULT CC_WMLButtonUp( HWND hDlg, WPARAM wParam, LPARAM lParam )
1077 struct CCPRIVATE * lpp = (struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
1078 if (lpp->capturedGraph)
1080 lpp->capturedGraph = 0;
1081 ReleaseCapture();
1082 CC_PaintCross(hDlg, lpp->h, lpp->s);
1083 return 1;
1085 return 0;
1089 /***********************************************************************
1090 * CC_WMMouseMove [internal]
1092 static LRESULT CC_WMMouseMove( HWND hDlg, LPARAM lParam )
1094 struct CCPRIVATE * lpp = (struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
1095 int r, g, b;
1097 if (lpp->capturedGraph)
1099 int *ptrh = NULL, *ptrs = &lpp->l;
1100 if (lpp->capturedGraph == 0x2c6)
1102 ptrh = &lpp->h;
1103 ptrs = &lpp->s;
1105 if (CC_MouseCheckColorGraph( hDlg, lpp->capturedGraph, ptrh, ptrs, lParam))
1107 r = CC_HSLtoRGB('R', lpp->h, lpp->s, lpp->l);
1108 g = CC_HSLtoRGB('G', lpp->h, lpp->s, lpp->l);
1109 b = CC_HSLtoRGB('B', lpp->h, lpp->s, lpp->l);
1110 lpp->lpcc->rgbResult = RGB(r, g, b);
1111 CC_EditSetRGB(hDlg, lpp->lpcc->rgbResult);
1112 CC_EditSetHSL(hDlg,lpp->h, lpp->s, lpp->l);
1113 CC_PaintCross(hDlg, lpp->h, lpp->s);
1114 CC_PaintTriangle(hDlg, lpp->l);
1115 CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult);
1117 else
1119 ReleaseCapture();
1120 lpp->capturedGraph = 0;
1122 return 1;
1124 return 0;
1126 /***********************************************************************
1127 * CC_WMLButtonDown [internal]
1129 static LRESULT CC_WMLButtonDown( HWND hDlg, WPARAM wParam, LPARAM lParam )
1131 struct CCPRIVATE * lpp = (struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
1132 int r, g, b, i;
1133 i = 0;
1135 if (CC_MouseCheckPredefColorArray(hDlg, 0x2d0, 6, 8, lParam, &lpp->lpcc->rgbResult))
1136 i = 1;
1137 else
1138 if (CC_MouseCheckUserColorArray(hDlg, 0x2d1, 2, 8, lParam,&lpp->lpcc->rgbResult,
1139 lpp->lpcc->lpCustColors))
1140 i = 1;
1141 else
1142 if (CC_MouseCheckColorGraph(hDlg, 0x2c6, &lpp->h, &lpp->s, lParam))
1144 i = 2;
1145 lpp->capturedGraph = 0x2c6;
1147 else
1148 if (CC_MouseCheckColorGraph(hDlg, 0x2be, NULL, &lpp->l, lParam))
1150 i = 2;
1151 lpp->capturedGraph = 0x2be;
1153 if ( i == 2 )
1155 SetCapture(hDlg);
1156 r = CC_HSLtoRGB('R', lpp->h, lpp->s, lpp->l);
1157 g = CC_HSLtoRGB('G', lpp->h, lpp->s, lpp->l);
1158 b = CC_HSLtoRGB('B', lpp->h, lpp->s, lpp->l);
1159 lpp->lpcc->rgbResult = RGB(r, g, b);
1161 if ( i == 1 )
1163 r = GetRValue(lpp->lpcc->rgbResult);
1164 g = GetGValue(lpp->lpcc->rgbResult);
1165 b = GetBValue(lpp->lpcc->rgbResult);
1166 lpp->h = CC_RGBtoHSL('H', r, g, b);
1167 lpp->s = CC_RGBtoHSL('S', r, g, b);
1168 lpp->l = CC_RGBtoHSL('L', r, g, b);
1170 if (i)
1172 CC_EditSetRGB(hDlg, lpp->lpcc->rgbResult);
1173 CC_EditSetHSL(hDlg,lpp->h, lpp->s, lpp->l);
1174 CC_PaintCross(hDlg, lpp->h, lpp->s);
1175 CC_PaintTriangle(hDlg, lpp->l);
1176 CC_PaintSelectedColor(hDlg, lpp->lpcc->rgbResult);
1177 return TRUE;
1179 return FALSE;
1183 /***********************************************************************
1184 * ColorDlgProc32 [internal]
1187 static LRESULT WINAPI ColorDlgProc( HWND hDlg, UINT message,
1188 WPARAM wParam, LPARAM lParam )
1191 int res;
1192 struct CCPRIVATE * lpp = (struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
1193 if (message != WM_INITDIALOG)
1195 if (!lpp)
1196 return FALSE;
1197 res = 0;
1198 if (CC_HookCallChk(lpp->lpcc))
1199 res = CallWindowProcA( (WNDPROC)lpp->lpcc->lpfnHook, hDlg, message, wParam, lParam);
1200 if ( res )
1201 return res;
1204 /* FIXME: SetRGB message
1205 if (message && message == msetrgb)
1206 return HandleSetRGB(hDlg, lParam);
1209 switch (message)
1211 case WM_INITDIALOG:
1212 return CC_WMInitDialog(hDlg, wParam, lParam, FALSE);
1213 case WM_NCDESTROY:
1214 DeleteDC(lpp->hdcMem);
1215 DeleteObject(lpp->hbmMem);
1216 HeapFree(GetProcessHeap(), 0, lpp);
1217 SetWindowLongA(hDlg, DWL_USER, 0L); /* we don't need it anymore */
1218 break;
1219 case WM_COMMAND:
1220 if (CC_WMCommand( hDlg, wParam, lParam, HIWORD(wParam), (HWND) lParam))
1221 return TRUE;
1222 break;
1223 case WM_PAINT:
1224 if ( CC_WMPaint(hDlg, wParam, lParam))
1225 return TRUE;
1226 break;
1227 case WM_LBUTTONDBLCLK:
1228 if (CC_MouseCheckResultWindow(hDlg, lParam))
1229 return TRUE;
1230 break;
1231 case WM_MOUSEMOVE:
1232 if (CC_WMMouseMove(hDlg, lParam))
1233 return TRUE;
1234 break;
1235 case WM_LBUTTONUP: /* FIXME: ClipCursor off (if in color graph)*/
1236 if (CC_WMLButtonUp(hDlg, wParam, lParam))
1237 return TRUE;
1238 break;
1239 case WM_LBUTTONDOWN:/* FIXME: ClipCursor on (if in color graph)*/
1240 if (CC_WMLButtonDown(hDlg, wParam, lParam))
1241 return TRUE;
1242 break;
1244 return FALSE ;
1247 /***********************************************************************
1248 * ColorDlgProc16 (COMMDLG.8)
1250 LRESULT WINAPI ColorDlgProc16( HWND16 hDlg, UINT16 message,
1251 WPARAM16 wParam, LONG lParam )
1253 int res;
1254 struct CCPRIVATE * lpp = (struct CCPRIVATE *)GetWindowLongA(hDlg, DWL_USER);
1255 if (message != WM_INITDIALOG)
1257 if (!lpp)
1258 return FALSE;
1259 res=0;
1260 if (CC_HookCallChk(lpp->lpcc))
1261 res = CallWindowProc16( (WNDPROC16)lpp->lpcc16->lpfnHook, hDlg, message, wParam, lParam);
1262 if (res)
1263 return res;
1266 /* FIXME: SetRGB message
1267 if (message && message == msetrgb)
1268 return HandleSetRGB(hDlg, lParam);
1271 switch (message)
1273 case WM_INITDIALOG:
1274 return CC_WMInitDialog(hDlg, wParam, lParam, TRUE);
1275 case WM_NCDESTROY:
1276 DeleteDC(lpp->hdcMem);
1277 DeleteObject(lpp->hbmMem);
1278 HeapFree(GetProcessHeap(), 0, lpp->lpcc);
1279 HeapFree(GetProcessHeap(), 0, lpp);
1280 SetWindowLongA(hDlg, DWL_USER, 0L); /* we don't need it anymore */
1281 break;
1282 case WM_COMMAND:
1283 if (CC_WMCommand(hDlg, wParam, lParam, HIWORD(lParam), (HWND)LOWORD(lParam)))
1284 return TRUE;
1285 break;
1286 case WM_PAINT:
1287 if (CC_WMPaint(hDlg, wParam, lParam))
1288 return TRUE;
1289 break;
1290 case WM_LBUTTONDBLCLK:
1291 if (CC_MouseCheckResultWindow(hDlg,lParam))
1292 return TRUE;
1293 break;
1294 case WM_MOUSEMOVE:
1295 if (CC_WMMouseMove(hDlg, lParam))
1296 return TRUE;
1297 break;
1298 case WM_LBUTTONUP: /* FIXME: ClipCursor off (if in color graph)*/
1299 if (CC_WMLButtonUp(hDlg, wParam, lParam))
1300 return TRUE;
1301 break;
1302 case WM_LBUTTONDOWN:/* FIXME: ClipCursor on (if in color graph)*/
1303 if (CC_WMLButtonDown(hDlg, wParam, lParam))
1304 return TRUE;
1305 break;
1307 return FALSE ;
1312 /***********************************************************************
1313 * ChooseColor16 (COMMDLG.5)
1315 BOOL16 WINAPI ChooseColor16( LPCHOOSECOLOR16 lpChCol )
1317 HINSTANCE16 hInst;
1318 HANDLE16 hDlgTmpl16 = 0, hResource16 = 0;
1319 HGLOBAL16 hGlobal16 = 0;
1320 BOOL16 bRet = FALSE;
1321 LPCVOID template;
1322 FARPROC16 ptr;
1324 TRACE("ChooseColor\n");
1325 if (!lpChCol) return FALSE;
1327 if (lpChCol->Flags & CC_ENABLETEMPLATEHANDLE)
1328 hDlgTmpl16 = lpChCol->hInstance;
1329 else if (lpChCol->Flags & CC_ENABLETEMPLATE)
1331 HANDLE16 hResInfo;
1332 if (!(hResInfo = FindResource16(lpChCol->hInstance,
1333 lpChCol->lpTemplateName,
1334 RT_DIALOG16)))
1336 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
1337 return FALSE;
1339 if (!(hDlgTmpl16 = LoadResource16(lpChCol->hInstance, hResInfo)))
1341 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
1342 return FALSE;
1344 hResource16 = hDlgTmpl16;
1346 else
1348 HANDLE hResInfo, hDlgTmpl32;
1349 LPCVOID template32;
1350 DWORD size;
1351 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "CHOOSE_COLOR", RT_DIALOGA)))
1353 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
1354 return FALSE;
1356 if (!(hDlgTmpl32 = LoadResource(COMMDLG_hInstance32, hResInfo)) ||
1357 !(template32 = LockResource(hDlgTmpl32)))
1359 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
1360 return FALSE;
1362 size = SizeofResource(GetModuleHandleA("COMDLG32"), hResInfo);
1363 hGlobal16 = GlobalAlloc16(0, size);
1364 if (!hGlobal16)
1366 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE);
1367 ERR("alloc failure for %ld bytes\n", size);
1368 return FALSE;
1370 template = GlobalLock16(hGlobal16);
1371 if (!template)
1373 COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE);
1374 ERR("global lock failure for %x handle\n", hDlgTmpl16);
1375 GlobalFree16(hGlobal16);
1376 return FALSE;
1378 ConvertDialog32To16((LPVOID)template32, size, (LPVOID)template);
1379 hDlgTmpl16 = hGlobal16;
1382 ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (SEGPTR) 8);
1383 hInst = GetWindowLongA(lpChCol->hwndOwner, GWL_HINSTANCE);
1384 bRet = DialogBoxIndirectParam16(hInst, hDlgTmpl16, lpChCol->hwndOwner,
1385 (DLGPROC16) ptr, (DWORD)lpChCol);
1386 if (hResource16) FreeResource16(hDlgTmpl16);
1387 if (hGlobal16)
1389 GlobalUnlock16(hGlobal16);
1390 GlobalFree16(hGlobal16);
1392 return bRet;
1395 /***********************************************************************
1396 * ChooseColorW (COMDLG32.2)
1398 BOOL WINAPI ChooseColorW( LPCHOOSECOLORW lpChCol )
1402 HANDLE hDlgTmpl = 0;
1403 BOOL bRet = FALSE;
1404 LPCVOID template;
1406 TRACE("ChooseColor\n");
1407 if (!lpChCol) return FALSE;
1409 if (lpChCol->Flags & CC_ENABLETEMPLATEHANDLE)
1411 if (!(template = LockResource(lpChCol->hInstance)))
1413 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
1414 return FALSE;
1417 else if (lpChCol->Flags & CC_ENABLETEMPLATE)
1419 HANDLE hResInfo;
1420 if (!(hResInfo = FindResourceW(lpChCol->hInstance,
1421 lpChCol->lpTemplateName,
1422 RT_DIALOGW)))
1424 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
1425 return FALSE;
1427 if (!(hDlgTmpl = LoadResource(lpChCol->hInstance, hResInfo)) ||
1428 !(template = LockResource(hDlgTmpl)))
1430 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
1431 return FALSE;
1434 else
1436 HANDLE hResInfo, hDlgTmpl;
1437 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32, "CHOOSE_COLOR", RT_DIALOGA)))
1439 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
1440 return FALSE;
1442 if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
1443 !(template = LockResource(hDlgTmpl)))
1445 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
1446 return FALSE;
1450 bRet = DialogBoxIndirectParamW(COMMDLG_hInstance32, template, lpChCol->hwndOwner,
1451 (DLGPROC)ColorDlgProc, (DWORD)lpChCol);
1452 return bRet;
1455 /***********************************************************************
1456 * ChooseColorA (COMDLG32.1)
1458 BOOL WINAPI ChooseColorA( LPCHOOSECOLORA lpChCol )
1461 BOOL ret;
1462 LPCHOOSECOLORW lpcc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CHOOSECOLORW));
1463 lpcc->lStructSize = sizeof(*lpcc);
1464 lpcc->hwndOwner = lpChCol->hwndOwner;
1465 lpcc->hInstance = lpChCol->hInstance;
1466 lpcc->rgbResult = lpChCol->rgbResult;
1467 lpcc->lpCustColors = lpChCol->lpCustColors;
1468 lpcc->Flags = lpChCol->Flags;
1469 lpcc->lCustData = lpChCol->lCustData;
1470 lpcc->lpfnHook = (LPCCHOOKPROC) lpChCol->lpfnHook;
1471 if ((lpcc->Flags & CC_ENABLETEMPLATE) && (lpChCol->lpTemplateName))
1472 lpcc->lpTemplateName = HEAP_strdupAtoW(GetProcessHeap(), 0, lpChCol->lpTemplateName);
1474 ret = ChooseColorW(lpcc);
1476 if (ret)
1477 lpChCol->rgbResult = lpcc->rgbResult;
1478 if (lpcc->lpTemplateName) HeapFree(GetProcessHeap(), 0, (LPSTR)lpcc->lpTemplateName);
1479 HeapFree(GetProcessHeap(), 0, lpcc);
1480 return ret;