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