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