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