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 #ifdef __REACTOS__ 400 static int CC_CheckDigitsInEdit( CCPRIV *infoPtr, HWND hwnd, int maxval ) 401 #else 402 static int CC_CheckDigitsInEdit( HWND hwnd, int maxval ) 403 #endif 404 { 405 int i, k, m, result, value; 406 long editpos; 407 char buffer[30]; 408 409 GetWindowTextA(hwnd, buffer, ARRAY_SIZE(buffer)); 410 m = strlen(buffer); 411 result = 0; 412 413 for (i = 0 ; i < m ; i++) 414 if (buffer[i] < '0' || buffer[i] > '9') 415 { 416 for (k = i + 1; k <= m; k++) /* delete bad character */ 417 { 418 buffer[i] = buffer[k]; 419 m--; 420 } 421 buffer[m] = 0; 422 result = 1; 423 } 424 425 value = atoi(buffer); 426 if (value > maxval) /* build a new string */ 427 { 428 #ifdef __REACTOS__ 429 value = maxval; 430 #endif 431 sprintf(buffer, "%d", maxval); 432 result = 2; 433 } 434 if (result) 435 { 436 editpos = SendMessageA(hwnd, EM_GETSEL, 0, 0); 437 #ifdef __REACTOS__ 438 infoPtr->updating = TRUE; 439 #endif 440 SetWindowTextA(hwnd, buffer ); 441 #ifdef __REACTOS__ 442 infoPtr->updating = FALSE; 443 #endif 444 SendMessageA(hwnd, EM_SETSEL, 0, editpos); 445 } 446 return value; 447 } 448 449 450 451 /*********************************************************************** 452 * CC_PaintSelectedColor [internal] 453 */ 454 static void CC_PaintSelectedColor(const CCPRIV *infoPtr) 455 { 456 if (IsWindowVisible( GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_GRAPH) )) /* if full size */ 457 { 458 RECT rect; 459 HDC hdc; 460 HBRUSH hBrush; 461 HWND hwnd = GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_RESULT); 462 463 hdc = GetDC(hwnd); 464 GetClientRect(hwnd, &rect) ; 465 hBrush = CreateSolidBrush(infoPtr->lpcc->rgbResult); 466 if (hBrush) 467 { 468 FillRect(hdc, &rect, hBrush); 469 DrawEdge(hdc, &rect, BDR_SUNKENOUTER, BF_RECT); 470 DeleteObject(hBrush); 471 } 472 ReleaseDC(hwnd, hdc); 473 } 474 } 475 476 /*********************************************************************** 477 * CC_PaintTriangle [internal] 478 */ 479 static void CC_PaintTriangle(CCPRIV *infoPtr) 480 { 481 HDC hDC; 482 long temp; 483 int w = LOWORD(GetDialogBaseUnits()) / 2; 484 POINT points[3]; 485 int height; 486 int oben; 487 RECT rect; 488 HBRUSH hbr; 489 HWND hwnd = GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_LUMBAR); 490 491 if (IsWindowVisible( GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_GRAPH))) /* if full size */ 492 { 493 GetClientRect(hwnd, &rect); 494 height = rect.bottom; 495 hDC = GetDC(infoPtr->hwndSelf); 496 points[0].y = rect.top; 497 points[0].x = rect.right; /* | /| */ 498 ClientToScreen(hwnd, points); /* | / | */ 499 ScreenToClient(infoPtr->hwndSelf, points); /* |< | */ 500 oben = points[0].y; /* | \ | */ 501 /* | \| */ 502 temp = (long)height * (long)infoPtr->l; 503 points[0].x += 1; 504 points[0].y = oben + height - temp / (long)MAXVERT; 505 points[1].y = points[0].y + w; 506 points[2].y = points[0].y - w; 507 points[2].x = points[1].x = points[0].x + w; 508 509 hbr = (HBRUSH)GetClassLongPtrW( hwnd, GCLP_HBRBACKGROUND); 510 if (!hbr) hbr = GetSysColorBrush(COLOR_BTNFACE); 511 FillRect(hDC, &infoPtr->old3angle, hbr); 512 infoPtr->old3angle.left = points[0].x; 513 infoPtr->old3angle.right = points[1].x + 1; 514 infoPtr->old3angle.top = points[2].y - 1; 515 infoPtr->old3angle.bottom= points[1].y + 1; 516 517 hbr = SelectObject(hDC, GetStockObject(BLACK_BRUSH)); 518 Polygon(hDC, points, 3); 519 SelectObject(hDC, hbr); 520 521 ReleaseDC(infoPtr->hwndSelf, hDC); 522 } 523 } 524 525 526 /*********************************************************************** 527 * CC_PaintCross [internal] 528 */ 529 static void CC_PaintCross(CCPRIV *infoPtr) 530 { 531 HWND hwnd = GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_GRAPH); 532 533 if (IsWindowVisible(hwnd)) /* if full size */ 534 { 535 HDC hDC; 536 #ifdef __REACTOS__ 537 int w = 8, wc = 6; 538 #else 539 int w = GetDialogBaseUnits() - 1; 540 int wc = GetDialogBaseUnits() * 3 / 4; 541 #endif 542 RECT rect; 543 POINT point, p; 544 HRGN region; 545 HPEN hPen; 546 int x, y; 547 548 x = infoPtr->h; 549 y = infoPtr->s; 550 551 GetClientRect(hwnd, &rect); 552 hDC = GetDC(hwnd); 553 region = CreateRectRgnIndirect(&rect); 554 SelectClipRgn(hDC, region); 555 DeleteObject(region); 556 557 point.x = ((long)rect.right * (long)x) / (long)MAXHORI; 558 point.y = rect.bottom - ((long)rect.bottom * (long)y) / (long)MAXVERT; 559 if ( infoPtr->oldcross.left != infoPtr->oldcross.right ) 560 BitBlt(hDC, infoPtr->oldcross.left, infoPtr->oldcross.top, 561 infoPtr->oldcross.right - infoPtr->oldcross.left, 562 infoPtr->oldcross.bottom - infoPtr->oldcross.top, 563 infoPtr->hdcMem, infoPtr->oldcross.left, infoPtr->oldcross.top, SRCCOPY); 564 #ifdef __REACTOS__ 565 infoPtr->oldcross.left = point.x - w - 3; 566 infoPtr->oldcross.right = point.x + w + 3; 567 infoPtr->oldcross.top = point.y - w - 3; 568 infoPtr->oldcross.bottom = point.y + w + 3; 569 #else 570 infoPtr->oldcross.left = point.x - w - 1; 571 infoPtr->oldcross.right = point.x + w + 1; 572 infoPtr->oldcross.top = point.y - w - 1; 573 infoPtr->oldcross.bottom = point.y + w + 1; 574 #endif 575 576 hPen = CreatePen(PS_SOLID, 3, RGB(0, 0, 0)); /* -black- color */ 577 hPen = SelectObject(hDC, hPen); 578 MoveToEx(hDC, point.x - w, point.y, &p); 579 LineTo(hDC, point.x - wc, point.y); 580 MoveToEx(hDC, point.x + wc, point.y, &p); 581 LineTo(hDC, point.x + w, point.y); 582 MoveToEx(hDC, point.x, point.y - w, &p); 583 LineTo(hDC, point.x, point.y - wc); 584 MoveToEx(hDC, point.x, point.y + wc, &p); 585 LineTo(hDC, point.x, point.y + w); 586 DeleteObject( SelectObject(hDC, hPen)); 587 588 ReleaseDC(hwnd, hDC); 589 } 590 } 591 592 593 #define XSTEPS 48 594 #define YSTEPS 24 595 596 597 /*********************************************************************** 598 * CC_PrepareColorGraph [internal] 599 */ 600 static void CC_PrepareColorGraph(CCPRIV *infoPtr) 601 { 602 int sdif, hdif, xdif, ydif, hue, sat; 603 HWND hwnd = GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_GRAPH); 604 HBRUSH hbrush; 605 HDC hdc ; 606 RECT rect, client; 607 HCURSOR hcursor = SetCursor( LoadCursorW(0, (LPCWSTR)IDC_WAIT) ); 608 609 GetClientRect(hwnd, &client); 610 hdc = GetDC(hwnd); 611 infoPtr->hdcMem = CreateCompatibleDC(hdc); 612 infoPtr->hbmMem = CreateCompatibleBitmap(hdc, client.right, client.bottom); 613 SelectObject(infoPtr->hdcMem, infoPtr->hbmMem); 614 615 xdif = client.right / XSTEPS; 616 ydif = client.bottom / YSTEPS+1; 617 hdif = 239 / XSTEPS; 618 sdif = 240 / YSTEPS; 619 for (rect.left = hue = 0; hue < 239 + hdif; hue += hdif) 620 { 621 rect.right = rect.left + xdif; 622 rect.bottom = client.bottom; 623 for(sat = 0; sat < 240 + sdif; sat += sdif) 624 { 625 rect.top = rect.bottom - ydif; 626 hbrush = CreateSolidBrush(CC_HSLtoRGB(hue, sat, 120)); 627 FillRect(infoPtr->hdcMem, &rect, hbrush); 628 DeleteObject(hbrush); 629 rect.bottom = rect.top; 630 } 631 rect.left = rect.right; 632 } 633 ReleaseDC(hwnd, hdc); 634 SetCursor(hcursor); 635 } 636 637 /*********************************************************************** 638 * CC_PaintColorGraph [internal] 639 */ 640 static void CC_PaintColorGraph(CCPRIV *infoPtr) 641 { 642 HWND hwnd = GetDlgItem( infoPtr->hwndSelf, IDC_COLOR_GRAPH ); 643 HDC hDC; 644 RECT rect; 645 646 if (IsWindowVisible(hwnd)) /* if full size */ 647 { 648 if (!infoPtr->hdcMem) 649 CC_PrepareColorGraph(infoPtr); /* should not be necessary */ 650 651 hDC = GetDC(hwnd); 652 GetClientRect(hwnd, &rect); 653 if (infoPtr->hdcMem) 654 BitBlt(hDC, 0, 0, rect.right, rect.bottom, infoPtr->hdcMem, 0, 0, SRCCOPY); 655 else 656 WARN("choose color: hdcMem is not defined\n"); 657 ReleaseDC(hwnd, hDC); 658 } 659 } 660 661 /*********************************************************************** 662 * CC_PaintLumBar [internal] 663 */ 664 static void CC_PaintLumBar(const CCPRIV *infoPtr) 665 { 666 HWND hwnd = GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_LUMBAR); 667 RECT rect, client; 668 int lum, ldif, ydif; 669 HBRUSH hbrush; 670 HDC hDC; 671 672 if (IsWindowVisible(hwnd)) 673 { 674 hDC = GetDC(hwnd); 675 GetClientRect(hwnd, &client); 676 rect = client; 677 678 ldif = 240 / YSTEPS; 679 ydif = client.bottom / YSTEPS+1; 680 for (lum = 0; lum < 240 + ldif; lum += ldif) 681 { 682 rect.top = max(0, rect.bottom - ydif); 683 hbrush = CreateSolidBrush(CC_HSLtoRGB(infoPtr->h, infoPtr->s, lum)); 684 FillRect(hDC, &rect, hbrush); 685 DeleteObject(hbrush); 686 rect.bottom = rect.top; 687 } 688 GetClientRect(hwnd, &rect); 689 DrawEdge(hDC, &rect, BDR_SUNKENOUTER, BF_RECT); 690 ReleaseDC(hwnd, hDC); 691 } 692 } 693 694 /*********************************************************************** 695 * CC_EditSetRGB [internal] 696 */ 697 static void CC_EditSetRGB( CCPRIV *infoPtr ) 698 { 699 if (IsWindowVisible( GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_GRAPH) )) /* if full size */ 700 { 701 COLORREF cr = infoPtr->lpcc->rgbResult; 702 int r = GetRValue(cr); 703 int g = GetGValue(cr); 704 int b = GetBValue(cr); 705 706 infoPtr->updating = TRUE; 707 SetDlgItemInt(infoPtr->hwndSelf, IDC_COLOR_EDIT_R, r, TRUE); 708 SetDlgItemInt(infoPtr->hwndSelf, IDC_COLOR_EDIT_G, g, TRUE); 709 SetDlgItemInt(infoPtr->hwndSelf, IDC_COLOR_EDIT_B, b, TRUE); 710 infoPtr->updating = FALSE; 711 } 712 } 713 714 /*********************************************************************** 715 * CC_EditSetHSL [internal] 716 */ 717 static void CC_EditSetHSL( CCPRIV *infoPtr ) 718 { 719 if (IsWindowVisible( GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_GRAPH) )) /* if full size */ 720 { 721 infoPtr->updating = TRUE; 722 SetDlgItemInt(infoPtr->hwndSelf, IDC_COLOR_EDIT_H, infoPtr->h, TRUE); 723 SetDlgItemInt(infoPtr->hwndSelf, IDC_COLOR_EDIT_S, infoPtr->s, TRUE); 724 SetDlgItemInt(infoPtr->hwndSelf, IDC_COLOR_EDIT_L, infoPtr->l, TRUE); 725 infoPtr->updating = FALSE; 726 } 727 CC_PaintLumBar(infoPtr); 728 } 729 730 /*********************************************************************** 731 * CC_SwitchToFullSize [internal] 732 */ 733 static void CC_SwitchToFullSize( CCPRIV *infoPtr, const RECT *lprect ) 734 { 735 int i; 736 737 EnableWindow( GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_DEFINE), FALSE); 738 CC_PrepareColorGraph(infoPtr); 739 for (i = IDC_COLOR_EDIT_H; i <= IDC_COLOR_EDIT_B; i++) 740 ShowWindow( GetDlgItem(infoPtr->hwndSelf, i), SW_SHOW); 741 for (i = IDC_COLOR_HL; i <= IDC_COLOR_BL; i++) 742 ShowWindow( GetDlgItem(infoPtr->hwndSelf, i), SW_SHOW); 743 ShowWindow( GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_RES), SW_SHOW); 744 ShowWindow( GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_ADD), SW_SHOW); 745 ShowWindow( GetDlgItem(infoPtr->hwndSelf, 1090), SW_SHOW); 746 747 if (lprect) 748 SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, lprect->right-lprect->left, 749 lprect->bottom-lprect->top, SWP_NOMOVE|SWP_NOZORDER); 750 751 ShowWindow( GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_LUMBAR), SW_SHOW); 752 ShowWindow( GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_RESULT), SW_SHOW); 753 754 CC_EditSetRGB(infoPtr); 755 CC_EditSetHSL(infoPtr); 756 ShowWindow( GetDlgItem( infoPtr->hwndSelf, IDC_COLOR_GRAPH), SW_SHOW); 757 UpdateWindow( GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_GRAPH) ); 758 } 759 760 /*********************************************************************** 761 * CC_PaintPredefColorArray [internal] 762 * Paints the default standard 48 colors 763 */ 764 static void CC_PaintPredefColorArray(const CCPRIV *infoPtr, int rows, int cols) 765 { 766 HWND hwnd = GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_PREDEF); 767 RECT rect, blockrect; 768 HDC hdc; 769 HBRUSH hBrush; 770 int dx, dy, i, j, k; 771 772 GetClientRect(hwnd, &rect); 773 dx = rect.right / cols; 774 dy = rect.bottom / rows; 775 k = rect.left; 776 777 hdc = GetDC(hwnd); 778 GetClientRect(hwnd, &rect); 779 hBrush = (HBRUSH)GetClassLongPtrW( hwnd, GCLP_HBRBACKGROUND); 780 if (!hBrush) hBrush = GetSysColorBrush(COLOR_BTNFACE); 781 FillRect(hdc, &rect, hBrush); 782 for ( j = 0; j < rows; j++ ) 783 { 784 for ( i = 0; i < cols; i++ ) 785 { 786 hBrush = CreateSolidBrush(predefcolors[j][i]); 787 if (hBrush) 788 { 789 blockrect.left = rect.left; 790 blockrect.top = rect.top; 791 blockrect.right = rect.left + dx - DISTANCE; 792 blockrect.bottom = rect.top + dy - DISTANCE; 793 FillRect(hdc, &blockrect, hBrush); 794 DrawEdge(hdc, &blockrect, BDR_SUNKEN, BF_RECT); 795 DeleteObject(hBrush); 796 } 797 rect.left += dx; 798 } 799 rect.top += dy; 800 rect.left = k; 801 } 802 ReleaseDC(hwnd, hdc); 803 if (infoPtr->hwndFocus == hwnd) 804 CC_DrawCurrentFocusRect(infoPtr); 805 } 806 /*********************************************************************** 807 * CC_PaintUserColorArray [internal] 808 * Paint the 16 user-selected colors 809 */ 810 static void CC_PaintUserColorArray(const CCPRIV *infoPtr, int rows, int cols) 811 { 812 HWND hwnd = GetDlgItem(infoPtr->hwndSelf, IDC_COLOR_USRDEF); 813 RECT rect, blockrect; 814 HDC hdc; 815 HBRUSH hBrush; 816 int dx, dy, i, j, k; 817 818 GetClientRect(hwnd, &rect); 819 820 dx = rect.right / cols; 821 dy = rect.bottom / rows; 822 k = rect.left; 823 824 hdc = GetDC(hwnd); 825 if (hdc) 826 { 827 hBrush = (HBRUSH)GetClassLongPtrW( hwnd, GCLP_HBRBACKGROUND); 828 if (!hBrush) hBrush = GetSysColorBrush(COLOR_BTNFACE); 829 FillRect( hdc, &rect, hBrush ); 830 for (j = 0; j < rows; j++) 831 { 832 for (i = 0; i < cols; i++) 833 { 834 hBrush = CreateSolidBrush(infoPtr->lpcc->lpCustColors[i+j*cols]); 835 if (hBrush) 836 { 837 blockrect.left = rect.left; 838 blockrect.top = rect.top; 839 blockrect.right = rect.left + dx - DISTANCE; 840 blockrect.bottom = rect.top + dy - DISTANCE; 841 FillRect(hdc, &blockrect, hBrush); 842 DrawEdge(hdc, &blockrect, BDR_SUNKEN, BF_RECT); 843 DeleteObject(hBrush); 844 } 845 rect.left += dx; 846 } 847 rect.top += dy; 848 rect.left = k; 849 } 850 ReleaseDC(hwnd, hdc); 851 } 852 if (infoPtr->hwndFocus == hwnd) 853 CC_DrawCurrentFocusRect(infoPtr); 854 } 855 856 857 /*********************************************************************** 858 * CC_HookCallChk [internal] 859 */ 860 static BOOL CC_HookCallChk( const CHOOSECOLORW *lpcc ) 861 { 862 if (lpcc) 863 if(lpcc->Flags & CC_ENABLEHOOK) 864 if (lpcc->lpfnHook) 865 return TRUE; 866 return FALSE; 867 } 868 869 /*********************************************************************** 870 * CC_WMInitDialog [internal] 871 */ 872 static LRESULT CC_WMInitDialog( HWND hDlg, WPARAM wParam, LPARAM lParam ) 873 { 874 CHOOSECOLORW *cc = (CHOOSECOLORW*)lParam; 875 int i, res; 876 int r, g, b; 877 HWND hwnd; 878 RECT rect; 879 POINT point; 880 CCPRIV *lpp; 881 882 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam); 883 884 if (cc->lStructSize != sizeof(CHOOSECOLORW)) 885 { 886 EndDialog(hDlg, 0); 887 return FALSE; 888 } 889 890 lpp = heap_alloc_zero(sizeof(*lpp)); 891 lpp->lpcc = cc; 892 lpp->hwndSelf = hDlg; 893 894 SetPropW( hDlg, szColourDialogProp, lpp ); 895 896 if (!(lpp->lpcc->Flags & CC_SHOWHELP)) 897 ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE); 898 lpp->msetrgb = RegisterWindowMessageA(SETRGBSTRINGA); 899 900 #if 0 901 cpos = MAKELONG(5,7); /* init */ 902 if (lpp->lpcc->Flags & CC_RGBINIT) 903 { 904 for (i = 0; i < 6; i++) 905 for (j = 0; j < 8; j++) 906 if (predefcolors[i][j] == lpp->lpcc->rgbResult) 907 { 908 cpos = MAKELONG(i,j); 909 goto found; 910 } 911 } 912 found: 913 /* FIXME: Draw_a_focus_rect & set_init_values */ 914 #endif 915 916 GetWindowRect(hDlg, &lpp->fullsize); 917 if (lpp->lpcc->Flags & CC_FULLOPEN || lpp->lpcc->Flags & CC_PREVENTFULLOPEN) 918 { 919 hwnd = GetDlgItem(hDlg, IDC_COLOR_DEFINE); 920 EnableWindow(hwnd, FALSE); 921 } 922 if (!(lpp->lpcc->Flags & CC_FULLOPEN ) || lpp->lpcc->Flags & CC_PREVENTFULLOPEN) 923 { 924 rect = lpp->fullsize; 925 res = rect.bottom - rect.top; 926 hwnd = GetDlgItem(hDlg, IDC_COLOR_GRAPH); /* cut at left border */ 927 point.x = point.y = 0; 928 ClientToScreen(hwnd, &point); 929 ScreenToClient(hDlg,&point); 930 GetClientRect(hDlg, &rect); 931 point.x += GetSystemMetrics(SM_CXDLGFRAME); 932 SetWindowPos(hDlg, 0, 0, 0, point.x, res, SWP_NOMOVE|SWP_NOZORDER); 933 934 for (i = IDC_COLOR_EDIT_H; i <= IDC_COLOR_EDIT_B; i++) 935 ShowWindow( GetDlgItem(hDlg, i), SW_HIDE); 936 for (i = IDC_COLOR_HL; i <= IDC_COLOR_BL; i++) 937 ShowWindow( GetDlgItem(hDlg, i), SW_HIDE); 938 ShowWindow( GetDlgItem(hDlg, IDC_COLOR_RES), SW_HIDE); 939 ShowWindow( GetDlgItem(hDlg, IDC_COLOR_ADD), SW_HIDE); 940 ShowWindow( GetDlgItem(hDlg, IDC_COLOR_GRAPH), SW_HIDE); 941 ShowWindow( GetDlgItem(hDlg, IDC_COLOR_RESULT), SW_HIDE); 942 ShowWindow( GetDlgItem(hDlg, 1090 ), SW_HIDE); 943 } 944 else 945 CC_SwitchToFullSize(lpp, NULL); 946 res = TRUE; 947 for (i = IDC_COLOR_EDIT_H; i <= IDC_COLOR_EDIT_B; i++) 948 SendMessageA( GetDlgItem(hDlg, i), EM_LIMITTEXT, 3, 0); /* max 3 digits: xyz */ 949 if (CC_HookCallChk(lpp->lpcc)) 950 { 951 res = CallWindowProcA( (WNDPROC)lpp->lpcc->lpfnHook, hDlg, WM_INITDIALOG, wParam, lParam); 952 } 953 954 /* Set the initial values of the color chooser dialog */ 955 r = GetRValue(lpp->lpcc->rgbResult); 956 g = GetGValue(lpp->lpcc->rgbResult); 957 b = GetBValue(lpp->lpcc->rgbResult); 958 959 CC_PaintSelectedColor(lpp); 960 lpp->h = CC_RGBtoHSL('H', lpp->lpcc->rgbResult); 961 lpp->s = CC_RGBtoHSL('S', lpp->lpcc->rgbResult); 962 lpp->l = CC_RGBtoHSL('L', lpp->lpcc->rgbResult); 963 964 /* Doing it the long way because CC_EditSetRGB/HSL doesn't seem to work */ 965 SetDlgItemInt(hDlg, IDC_COLOR_EDIT_H, lpp->h, TRUE); 966 SetDlgItemInt(hDlg, IDC_COLOR_EDIT_S, lpp->s, TRUE); 967 SetDlgItemInt(hDlg, IDC_COLOR_EDIT_L, lpp->l, TRUE); 968 SetDlgItemInt(hDlg, IDC_COLOR_EDIT_R, r, TRUE); 969 SetDlgItemInt(hDlg, IDC_COLOR_EDIT_G, g, TRUE); 970 SetDlgItemInt(hDlg, IDC_COLOR_EDIT_B, b, TRUE); 971 972 CC_PaintCross(lpp); 973 CC_PaintTriangle(lpp); 974 975 return res; 976 } 977 978 979 /*********************************************************************** 980 * CC_WMCommand [internal] 981 */ 982 static LRESULT CC_WMCommand(CCPRIV *lpp, WPARAM wParam, LPARAM lParam, WORD notifyCode, HWND hwndCtl) 983 { 984 int r, g, b, i, xx; 985 UINT cokmsg; 986 HDC hdc; 987 COLORREF *cr; 988 989 TRACE("CC_WMCommand wParam=%lx lParam=%lx\n", wParam, lParam); 990 switch (LOWORD(wParam)) 991 { 992 case IDC_COLOR_EDIT_R: /* edit notify RGB */ 993 case IDC_COLOR_EDIT_G: 994 case IDC_COLOR_EDIT_B: 995 if (notifyCode == EN_UPDATE && !lpp->updating) 996 { 997 #ifdef __REACTOS__ 998 i = CC_CheckDigitsInEdit(lpp, hwndCtl, 255); 999 #else 1000 i = CC_CheckDigitsInEdit(hwndCtl, 255); 1001 #endif 1002 r = GetRValue(lpp->lpcc->rgbResult); 1003 g = GetGValue(lpp->lpcc->rgbResult); 1004 b= GetBValue(lpp->lpcc->rgbResult); 1005 xx = 0; 1006 switch (LOWORD(wParam)) 1007 { 1008 case IDC_COLOR_EDIT_R: if ((xx = (i != r))) r = i; break; 1009 case IDC_COLOR_EDIT_G: if ((xx = (i != g))) g = i; break; 1010 case IDC_COLOR_EDIT_B: if ((xx = (i != b))) b = i; break; 1011 } 1012 if (xx) /* something has changed */ 1013 { 1014 lpp->lpcc->rgbResult = RGB(r, g, b); 1015 CC_PaintSelectedColor(lpp); 1016 lpp->h = CC_RGBtoHSL('H', lpp->lpcc->rgbResult); 1017 lpp->s = CC_RGBtoHSL('S', lpp->lpcc->rgbResult); 1018 lpp->l = CC_RGBtoHSL('L', lpp->lpcc->rgbResult); 1019 CC_EditSetHSL(lpp); 1020 CC_PaintCross(lpp); 1021 CC_PaintTriangle(lpp); 1022 #ifdef __REACTOS__ 1023 CC_PaintLumBar(lpp); 1024 #endif 1025 } 1026 } 1027 break; 1028 1029 case IDC_COLOR_EDIT_H: /* edit notify HSL */ 1030 case IDC_COLOR_EDIT_S: 1031 case IDC_COLOR_EDIT_L: 1032 if (notifyCode == EN_UPDATE && !lpp->updating) 1033 { 1034 #ifdef __REACTOS__ 1035 i = CC_CheckDigitsInEdit(lpp, hwndCtl , LOWORD(wParam) == IDC_COLOR_EDIT_H ? 239 : 240); 1036 #else 1037 i = CC_CheckDigitsInEdit(hwndCtl , LOWORD(wParam) == IDC_COLOR_EDIT_H ? 239 : 240); 1038 #endif 1039 xx = 0; 1040 switch (LOWORD(wParam)) 1041 { 1042 case IDC_COLOR_EDIT_H: if ((xx = ( i != lpp->h))) lpp->h = i; break; 1043 case IDC_COLOR_EDIT_S: if ((xx = ( i != lpp->s))) lpp->s = i; break; 1044 case IDC_COLOR_EDIT_L: if ((xx = ( i != lpp->l))) lpp->l = i; break; 1045 } 1046 if (xx) /* something has changed */ 1047 { 1048 lpp->lpcc->rgbResult = CC_HSLtoRGB(lpp->h, lpp->s, lpp->l); 1049 CC_PaintSelectedColor(lpp); 1050 CC_EditSetRGB(lpp); 1051 CC_PaintCross(lpp); 1052 CC_PaintTriangle(lpp); 1053 } 1054 } 1055 break; 1056 1057 case IDC_COLOR_DEFINE: 1058 CC_SwitchToFullSize(lpp, &lpp->fullsize); 1059 SetFocus( GetDlgItem(lpp->hwndSelf, IDC_COLOR_EDIT_H)); 1060 break; 1061 1062 case IDC_COLOR_ADD: /* add colors ... column by column */ 1063 cr = lpp->lpcc->lpCustColors; 1064 cr[(lpp->nextuserdef % 2) * 8 + lpp->nextuserdef / 2] = lpp->lpcc->rgbResult; 1065 if (++lpp->nextuserdef == 16) 1066 lpp->nextuserdef = 0; 1067 CC_PaintUserColorArray(lpp, 2, 8); 1068 break; 1069 1070 case IDC_COLOR_RES: /* resulting color */ 1071 hdc = GetDC(lpp->hwndSelf); 1072 lpp->lpcc->rgbResult = GetNearestColor(hdc, lpp->lpcc->rgbResult); 1073 ReleaseDC(lpp->hwndSelf, hdc); 1074 CC_EditSetRGB(lpp); 1075 CC_PaintSelectedColor(lpp); 1076 lpp->h = CC_RGBtoHSL('H', lpp->lpcc->rgbResult); 1077 lpp->s = CC_RGBtoHSL('S', lpp->lpcc->rgbResult); 1078 lpp->l = CC_RGBtoHSL('L', lpp->lpcc->rgbResult); 1079 CC_EditSetHSL(lpp); 1080 CC_PaintCross(lpp); 1081 CC_PaintTriangle(lpp); 1082 break; 1083 1084 case pshHelp: /* Help! */ /* The Beatles, 1965 ;-) */ 1085 i = RegisterWindowMessageA(HELPMSGSTRINGA); 1086 if (lpp->lpcc->hwndOwner) 1087 SendMessageA(lpp->lpcc->hwndOwner, i, 0, (LPARAM)lpp->lpcc); 1088 if ( CC_HookCallChk(lpp->lpcc)) 1089 CallWindowProcA( (WNDPROC) lpp->lpcc->lpfnHook, lpp->hwndSelf, 1090 WM_COMMAND, psh15, (LPARAM)lpp->lpcc); 1091 break; 1092 1093 case IDOK : 1094 cokmsg = RegisterWindowMessageA(COLOROKSTRINGA); 1095 if (lpp->lpcc->hwndOwner) 1096 if (SendMessageA(lpp->lpcc->hwndOwner, cokmsg, 0, (LPARAM)lpp->lpcc)) 1097 break; /* do NOT close */ 1098 EndDialog(lpp->hwndSelf, 1) ; 1099 return TRUE ; 1100 1101 case IDCANCEL : 1102 EndDialog(lpp->hwndSelf, 0) ; 1103 return TRUE ; 1104 1105 } 1106 return FALSE; 1107 } 1108 1109 /*********************************************************************** 1110 * CC_WMPaint [internal] 1111 */ 1112 static LRESULT CC_WMPaint( CCPRIV *lpp ) 1113 { 1114 PAINTSTRUCT ps; 1115 1116 BeginPaint(lpp->hwndSelf, &ps); 1117 /* we have to paint dialog children except text and buttons */ 1118 CC_PaintPredefColorArray(lpp, 6, 8); 1119 CC_PaintUserColorArray(lpp, 2, 8); 1120 CC_PaintLumBar(lpp); 1121 CC_PaintTriangle(lpp); 1122 CC_PaintSelectedColor(lpp); 1123 CC_PaintColorGraph(lpp); 1124 CC_PaintCross(lpp); 1125 EndPaint(lpp->hwndSelf, &ps); 1126 1127 return TRUE; 1128 } 1129 1130 /*********************************************************************** 1131 * CC_WMLButtonUp [internal] 1132 */ 1133 static LRESULT CC_WMLButtonUp( CCPRIV *infoPtr ) 1134 { 1135 if (infoPtr->capturedGraph) 1136 { 1137 #ifdef __REACTOS__ 1138 ClipCursor(NULL); 1139 #endif 1140 infoPtr->capturedGraph = 0; 1141 ReleaseCapture(); 1142 CC_PaintCross(infoPtr); 1143 return 1; 1144 } 1145 return 0; 1146 } 1147 1148 /*********************************************************************** 1149 * CC_WMMouseMove [internal] 1150 */ 1151 static LRESULT CC_WMMouseMove( CCPRIV *infoPtr, LPARAM lParam ) 1152 { 1153 if (infoPtr->capturedGraph) 1154 { 1155 int *ptrh = NULL, *ptrs = &infoPtr->l; 1156 if (infoPtr->capturedGraph == IDC_COLOR_GRAPH) 1157 { 1158 ptrh = &infoPtr->h; 1159 ptrs = &infoPtr->s; 1160 } 1161 if (CC_MouseCheckColorGraph( infoPtr->hwndSelf, infoPtr->capturedGraph, ptrh, ptrs, lParam)) 1162 { 1163 infoPtr->lpcc->rgbResult = CC_HSLtoRGB(infoPtr->h, infoPtr->s, infoPtr->l); 1164 CC_EditSetRGB(infoPtr); 1165 CC_EditSetHSL(infoPtr); 1166 CC_PaintCross(infoPtr); 1167 CC_PaintTriangle(infoPtr); 1168 CC_PaintSelectedColor(infoPtr); 1169 } 1170 else 1171 { 1172 ReleaseCapture(); 1173 infoPtr->capturedGraph = 0; 1174 } 1175 return 1; 1176 } 1177 return 0; 1178 } 1179 1180 /*********************************************************************** 1181 * CC_WMLButtonDown [internal] 1182 */ 1183 static LRESULT CC_WMLButtonDown( CCPRIV *infoPtr, LPARAM lParam ) 1184 { 1185 int i = 0; 1186 1187 if (CC_MouseCheckPredefColorArray(infoPtr, 6, 8, lParam)) 1188 i = 1; 1189 else 1190 if (CC_MouseCheckUserColorArray(infoPtr, 2, 8, lParam)) 1191 i = 1; 1192 else 1193 if (CC_MouseCheckColorGraph(infoPtr->hwndSelf, IDC_COLOR_GRAPH, &infoPtr->h, &infoPtr->s, lParam)) 1194 { 1195 i = 2; 1196 infoPtr->capturedGraph = IDC_COLOR_GRAPH; 1197 } 1198 else 1199 if (CC_MouseCheckColorGraph(infoPtr->hwndSelf, IDC_COLOR_LUMBAR, NULL, &infoPtr->l, lParam)) 1200 { 1201 i = 2; 1202 infoPtr->capturedGraph = IDC_COLOR_LUMBAR; 1203 } 1204 if ( i == 2 ) 1205 { 1206 SetCapture(infoPtr->hwndSelf); 1207 infoPtr->lpcc->rgbResult = CC_HSLtoRGB(infoPtr->h, infoPtr->s, infoPtr->l); 1208 } 1209 if ( i == 1 ) 1210 { 1211 infoPtr->h = CC_RGBtoHSL('H', infoPtr->lpcc->rgbResult); 1212 infoPtr->s = CC_RGBtoHSL('S', infoPtr->lpcc->rgbResult); 1213 infoPtr->l = CC_RGBtoHSL('L', infoPtr->lpcc->rgbResult); 1214 } 1215 if (i) 1216 { 1217 #ifdef __REACTOS__ 1218 if (infoPtr->capturedGraph) 1219 { 1220 RECT rect; 1221 GetWindowRect(GetDlgItem(infoPtr->hwndSelf, infoPtr->capturedGraph), &rect); 1222 ClipCursor(&rect); 1223 } 1224 #endif 1225 CC_EditSetRGB(infoPtr); 1226 CC_EditSetHSL(infoPtr); 1227 CC_PaintCross(infoPtr); 1228 CC_PaintTriangle(infoPtr); 1229 CC_PaintSelectedColor(infoPtr); 1230 return TRUE; 1231 } 1232 return FALSE; 1233 } 1234 1235 /*********************************************************************** 1236 * ColorDlgProc32 [internal] 1237 * 1238 */ 1239 static INT_PTR CALLBACK ColorDlgProc( HWND hDlg, UINT message, 1240 WPARAM wParam, LPARAM lParam ) 1241 { 1242 1243 int res; 1244 CCPRIV *lpp = GetPropW( hDlg, szColourDialogProp ); 1245 1246 if (message != WM_INITDIALOG) 1247 { 1248 if (!lpp) 1249 return FALSE; 1250 res = 0; 1251 if (CC_HookCallChk(lpp->lpcc)) 1252 res = CallWindowProcA( (WNDPROC)lpp->lpcc->lpfnHook, hDlg, message, wParam, lParam); 1253 if ( res ) 1254 return res; 1255 } 1256 1257 /* FIXME: SetRGB message 1258 if (message && message == msetrgb) 1259 return HandleSetRGB(hDlg, lParam); 1260 */ 1261 1262 switch (message) 1263 { 1264 case WM_INITDIALOG: 1265 return CC_WMInitDialog(hDlg, wParam, lParam); 1266 case WM_NCDESTROY: 1267 #ifdef __REACTOS__ 1268 // Ensure clipping is released, in case the dialog is closed before WM_LBUTTONUP is received. 1269 ClipCursor(NULL); 1270 #endif 1271 DeleteDC(lpp->hdcMem); 1272 DeleteObject(lpp->hbmMem); 1273 heap_free(lpp); 1274 RemovePropW( hDlg, szColourDialogProp ); 1275 break; 1276 case WM_COMMAND: 1277 if (CC_WMCommand(lpp, wParam, lParam, HIWORD(wParam), (HWND) lParam)) 1278 return TRUE; 1279 break; 1280 case WM_PAINT: 1281 if (CC_WMPaint(lpp)) 1282 return TRUE; 1283 break; 1284 case WM_LBUTTONDBLCLK: 1285 if (CC_MouseCheckResultWindow(hDlg, lParam)) 1286 return TRUE; 1287 break; 1288 case WM_MOUSEMOVE: 1289 if (CC_WMMouseMove(lpp, lParam)) 1290 return TRUE; 1291 break; 1292 #ifdef __REACTOS__ 1293 /* ReactOS: The following comment doesn't apply */ 1294 #endif 1295 case WM_LBUTTONUP: /* FIXME: ClipCursor off (if in color graph)*/ 1296 if (CC_WMLButtonUp(lpp)) 1297 return TRUE; 1298 break; 1299 #ifdef __REACTOS__ 1300 /* ReactOS: The following comment doesn't apply */ 1301 #endif 1302 case WM_LBUTTONDOWN:/* FIXME: ClipCursor on (if in color graph)*/ 1303 if (CC_WMLButtonDown(lpp, lParam)) 1304 return TRUE; 1305 break; 1306 } 1307 return FALSE ; 1308 } 1309 1310 /*********************************************************************** 1311 * ChooseColorW (COMDLG32.@) 1312 * 1313 * Create a color dialog box. 1314 * 1315 * PARAMS 1316 * lpChCol [I/O] in: information to initialize the dialog box. 1317 * out: User's color selection 1318 * 1319 * RETURNS 1320 * TRUE: Ok button clicked. 1321 * FALSE: Cancel button clicked, or error. 1322 */ 1323 BOOL WINAPI ChooseColorW( CHOOSECOLORW *lpChCol ) 1324 { 1325 HANDLE hDlgTmpl = 0; 1326 const void *template; 1327 1328 TRACE("(%p)\n", lpChCol); 1329 1330 if (!lpChCol) return FALSE; 1331 1332 if (lpChCol->Flags & CC_ENABLETEMPLATEHANDLE) 1333 { 1334 if (!(template = LockResource(lpChCol->hInstance))) 1335 { 1336 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); 1337 return FALSE; 1338 } 1339 } 1340 else if (lpChCol->Flags & CC_ENABLETEMPLATE) 1341 { 1342 HRSRC hResInfo; 1343 if (!(hResInfo = FindResourceW((HINSTANCE)lpChCol->hInstance, 1344 lpChCol->lpTemplateName, 1345 (LPWSTR)RT_DIALOG))) 1346 { 1347 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); 1348 return FALSE; 1349 } 1350 if (!(hDlgTmpl = LoadResource((HINSTANCE)lpChCol->hInstance, hResInfo)) || 1351 !(template = LockResource(hDlgTmpl))) 1352 { 1353 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); 1354 return FALSE; 1355 } 1356 } 1357 else 1358 { 1359 HRSRC hResInfo; 1360 HGLOBAL hDlgTmpl; 1361 static const WCHAR wszCHOOSE_COLOR[] = {'C','H','O','O','S','E','_','C','O','L','O','R',0}; 1362 if (!(hResInfo = FindResourceW(COMDLG32_hInstance, wszCHOOSE_COLOR, (LPWSTR)RT_DIALOG))) 1363 { 1364 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); 1365 return FALSE; 1366 } 1367 if (!(hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo )) || 1368 !(template = LockResource(hDlgTmpl))) 1369 { 1370 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); 1371 return FALSE; 1372 } 1373 } 1374 1375 return DialogBoxIndirectParamW(COMDLG32_hInstance, template, lpChCol->hwndOwner, 1376 ColorDlgProc, (LPARAM)lpChCol); 1377 } 1378 1379 /*********************************************************************** 1380 * ChooseColorA (COMDLG32.@) 1381 * 1382 * See ChooseColorW. 1383 */ 1384 BOOL WINAPI ChooseColorA( LPCHOOSECOLORA lpChCol ) 1385 1386 { 1387 LPWSTR template_name = NULL; 1388 BOOL ret; 1389 1390 CHOOSECOLORW *lpcc = heap_alloc_zero(sizeof(*lpcc)); 1391 lpcc->lStructSize = sizeof(*lpcc); 1392 lpcc->hwndOwner = lpChCol->hwndOwner; 1393 lpcc->hInstance = lpChCol->hInstance; 1394 lpcc->rgbResult = lpChCol->rgbResult; 1395 lpcc->lpCustColors = lpChCol->lpCustColors; 1396 lpcc->Flags = lpChCol->Flags; 1397 lpcc->lCustData = lpChCol->lCustData; 1398 lpcc->lpfnHook = lpChCol->lpfnHook; 1399 if ((lpcc->Flags & CC_ENABLETEMPLATE) && (lpChCol->lpTemplateName)) { 1400 if (!IS_INTRESOURCE(lpChCol->lpTemplateName)) { 1401 INT len = MultiByteToWideChar( CP_ACP, 0, lpChCol->lpTemplateName, -1, NULL, 0); 1402 template_name = heap_alloc( len * sizeof(WCHAR) ); 1403 MultiByteToWideChar( CP_ACP, 0, lpChCol->lpTemplateName, -1, template_name, len ); 1404 lpcc->lpTemplateName = template_name; 1405 } else { 1406 lpcc->lpTemplateName = (LPCWSTR)lpChCol->lpTemplateName; 1407 } 1408 } 1409 1410 ret = ChooseColorW(lpcc); 1411 1412 if (ret) 1413 lpChCol->rgbResult = lpcc->rgbResult; 1414 1415 heap_free(template_name); 1416 heap_free(lpcc); 1417 return ret; 1418 } 1419