Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2087 lines
62 KiB

  1. /*++
  2. Copyright (c) 1990-1998, Microsoft Corporation All rights reserved.
  3. Module Name:
  4. color.c
  5. Abstract:
  6. This module implements the Win32 color dialog.
  7. Revision History:
  8. --*/
  9. // precompiled headers
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. #include "color.h"
  13. #include "util.h"
  14. // from pwin32.h
  15. #define LONG2POINT(l, pt) ((pt).x = (SHORT)LOWORD(l), (pt).y = (SHORT)HIWORD(l))
  16. //
  17. // Global Variables.
  18. //
  19. DWORD rgbBoxColorDefault[COLORBOXES] =
  20. {
  21. 0x8080FF, 0x80FFFF, 0x80FF80, 0x80FF00, 0xFFFF80, 0xFF8000, 0xC080FF, 0xFF80FF,
  22. 0x0000FF, 0x00FFFF, 0x00FF80, 0x40FF00, 0xFFFF00, 0xC08000, 0xC08080, 0xFF00FF,
  23. 0x404080, 0x4080FF, 0x00FF00, 0x808000, 0x804000, 0xFF8080, 0x400080, 0x8000FF,
  24. 0x000080, 0x0080FF, 0x008000, 0x408000, 0xFF0000, 0xA00000, 0x800080, 0xFF0080,
  25. 0x000040, 0x004080, 0x004000, 0x404000, 0x800000, 0x400000, 0x400040, 0x800040,
  26. 0x000000, 0x008080, 0x408080, 0x808080, 0x808040, 0xC0C0C0, 0x400040, 0xFFFFFF,
  27. 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF,
  28. 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF
  29. };
  30. RECT rColorBox[COLORBOXES];
  31. UINT msgCOLOROKA;
  32. UINT msgSETRGBA;
  33. UINT msgCOLOROKW;
  34. UINT msgSETRGBW;
  35. LPCCHOOKPROC glpfnColorHook = 0;
  36. #ifdef UNICODE
  37. ////////////////////////////////////////////////////////////////////////////
  38. //
  39. // ChooseColorA
  40. //
  41. // ANSI entry point for ChooseColor when this code is built UNICODE.
  42. //
  43. ////////////////////////////////////////////////////////////////////////////
  44. BOOL WINAPI ChooseColorA(
  45. LPCHOOSECOLORA pCCA)
  46. {
  47. LPCHOOSECOLORW pCCW;
  48. BOOL bRet;
  49. DWORD cchLen;
  50. COLORINFO CI;
  51. ZeroMemory(&CI, sizeof(CI));
  52. if (!pCCA)
  53. {
  54. StoreExtendedError(CDERR_INITIALIZATION);
  55. return (FALSE);
  56. }
  57. if (pCCA->lStructSize != sizeof(CHOOSECOLORA))
  58. {
  59. StoreExtendedError(CDERR_STRUCTSIZE);
  60. return (FALSE);
  61. }
  62. if (!(pCCW = (LPCHOOSECOLORW)LocalAlloc(LPTR, sizeof(CHOOSECOLORW))))
  63. {
  64. StoreExtendedError(CDERR_MEMALLOCFAILURE);
  65. return (FALSE);
  66. }
  67. //
  68. // Init simple invariants.
  69. //
  70. pCCW->lStructSize = sizeof(CHOOSECOLORW);
  71. pCCW->hwndOwner = pCCA->hwndOwner;
  72. pCCW->hInstance = pCCA->hInstance;
  73. pCCW->lpfnHook = pCCA->lpfnHook;
  74. //
  75. // TemplateName array invariant.
  76. //
  77. if (pCCA->Flags & CC_ENABLETEMPLATE)
  78. {
  79. if (!IS_INTRESOURCE(pCCA->lpTemplateName))
  80. {
  81. cchLen = lstrlenA(pCCA->lpTemplateName) + 1;
  82. if (!(pCCW->lpTemplateName = (LPWSTR)LocalAlloc(LPTR, (cchLen * sizeof(WCHAR)))))
  83. {
  84. StoreExtendedError(CDERR_MEMALLOCFAILURE);
  85. return (FALSE);
  86. }
  87. else
  88. {
  89. MultiByteToWideChar( CP_ACP,
  90. 0,
  91. pCCA->lpTemplateName,
  92. -1,
  93. (LPWSTR)pCCW->lpTemplateName,
  94. cchLen );
  95. }
  96. }
  97. else
  98. {
  99. pCCW->lpTemplateName = (LPWSTR)pCCA->lpTemplateName;
  100. }
  101. }
  102. else
  103. {
  104. pCCW->lpTemplateName = NULL;
  105. }
  106. CI.pCC = pCCW;
  107. CI.pCCA = pCCA;
  108. CI.ApiType = COMDLG_ANSI;
  109. ThunkChooseColorA2W(&CI);
  110. if (bRet = ChooseColorX(&CI))
  111. {
  112. ThunkChooseColorW2A(&CI);
  113. }
  114. if (!IS_INTRESOURCE(pCCW->lpTemplateName))
  115. {
  116. LocalFree((HLOCAL)pCCW->lpTemplateName);
  117. }
  118. LocalFree(pCCW);
  119. return (bRet);
  120. }
  121. #else
  122. ////////////////////////////////////////////////////////////////////////////
  123. //
  124. // ChooseColorW
  125. //
  126. // Stub UNICODE function for ChooseColor when this code is built ANSI.
  127. //
  128. ////////////////////////////////////////////////////////////////////////////
  129. BOOL WINAPI ChooseColorW(
  130. LPCHOOSECOLORW pCCW)
  131. {
  132. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  133. return (FALSE);
  134. }
  135. #endif
  136. ////////////////////////////////////////////////////////////////////////////
  137. //
  138. // ChooseColor
  139. //
  140. // The ChooseColor function creates a system-defined dialog box from
  141. // which the user can select a color.
  142. //
  143. ////////////////////////////////////////////////////////////////////////////
  144. BOOL WINAPI ChooseColor(
  145. LPCHOOSECOLOR pCC)
  146. {
  147. COLORINFO CI;
  148. ZeroMemory(&CI, sizeof(CI));
  149. CI.pCC = pCC;
  150. CI.ApiType = COMDLG_WIDE;
  151. return ( ChooseColorX(&CI) );
  152. }
  153. ////////////////////////////////////////////////////////////////////////////
  154. //
  155. // ChooseColorX
  156. //
  157. // Worker routine for the ChooseColor api.
  158. //
  159. ////////////////////////////////////////////////////////////////////////////
  160. BOOL ChooseColorX(
  161. PCOLORINFO pCI)
  162. {
  163. LPCHOOSECOLOR pCC = pCI->pCC;
  164. INT_PTR iRet = FALSE;
  165. TCHAR szDialog[cbDlgNameMax];
  166. LPTSTR lpDlg;
  167. HANDLE hDlgTemplate;
  168. HRSRC hRes;
  169. #ifdef UNICODE
  170. UINT uiWOWFlag = 0;
  171. #endif
  172. LANGID LangID = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
  173. //
  174. // Initialize the error code.
  175. //
  176. StoreExtendedError(0);
  177. g_bUserPressedCancel = FALSE;
  178. if (!pCC)
  179. {
  180. StoreExtendedError(CDERR_INITIALIZATION);
  181. return (FALSE);
  182. }
  183. if (pCC->lStructSize != sizeof(CHOOSECOLOR))
  184. {
  185. StoreExtendedError(CDERR_STRUCTSIZE);
  186. return (FALSE);
  187. }
  188. if (pCC->Flags & CC_ENABLEHOOK)
  189. {
  190. if (!pCC->lpfnHook)
  191. {
  192. StoreExtendedError(CDERR_NOHOOK);
  193. return (FALSE);
  194. }
  195. }
  196. else
  197. {
  198. pCC->lpfnHook = 0;
  199. }
  200. if (pCC->Flags & CC_ENABLETEMPLATE)
  201. {
  202. //
  203. // Both custom instance handle and the dialog template name are
  204. // user specified. Locate the dialog resource in the specified
  205. // instance block and load it.
  206. //
  207. if (!(hRes = FindResource( (HMODULE)pCC->hInstance,
  208. pCC->lpTemplateName,
  209. RT_DIALOG )))
  210. {
  211. StoreExtendedError(CDERR_FINDRESFAILURE);
  212. return (FALSE);
  213. }
  214. if (!(hDlgTemplate = LoadResource((HMODULE)pCC->hInstance, hRes)))
  215. {
  216. StoreExtendedError(CDERR_LOADRESFAILURE);
  217. return (FALSE);
  218. }
  219. }
  220. else if (pCC->Flags & CC_ENABLETEMPLATEHANDLE)
  221. {
  222. //
  223. // A handle to the pre-loaded resource has been specified.
  224. //
  225. hDlgTemplate = pCC->hInstance;
  226. }
  227. else
  228. {
  229. LangID = GetDialogLanguage(pCC->hwndOwner, NULL);
  230. //
  231. // Warning! Warning! Warning!
  232. //
  233. // We have to set g_tlsLangID before any call for CDLoadString
  234. //
  235. TlsSetValue(g_tlsLangID, (LPVOID) LangID);
  236. if (!CDLoadString( g_hinst,
  237. dlgChooseColor,
  238. szDialog,
  239. cbDlgNameMax - 1 ))
  240. {
  241. StoreExtendedError(CDERR_LOADSTRFAILURE);
  242. return (FALSE);
  243. }
  244. lpDlg = szDialog;
  245. if (!(hRes = FindResourceExFallback(g_hinst, RT_DIALOG, lpDlg, LangID)))
  246. {
  247. StoreExtendedError(CDERR_FINDRESFAILURE);
  248. return (FALSE);
  249. }
  250. if (!(hDlgTemplate = LoadResource(g_hinst, hRes)))
  251. {
  252. StoreExtendedError(CDERR_LOADRESFAILURE);
  253. return (FALSE);
  254. }
  255. }
  256. // In case it did nt called upove and some new code called CDLoadString.
  257. TlsSetValue(g_tlsLangID, (LPVOID) LangID);
  258. if (LockResource(hDlgTemplate))
  259. {
  260. if (pCI->pCC->Flags & CC_ENABLEHOOK)
  261. {
  262. glpfnColorHook = GETHOOKFN(pCI->pCC);
  263. }
  264. #ifdef UNICODE
  265. if (IS16BITWOWAPP(pCC))
  266. {
  267. uiWOWFlag = SCDLG_16BIT;
  268. }
  269. iRet = DialogBoxIndirectParamAorW( g_hinst,
  270. (LPDLGTEMPLATE)hDlgTemplate,
  271. pCC->hwndOwner,
  272. ColorDlgProc,
  273. (LPARAM)pCI,
  274. uiWOWFlag );
  275. #else
  276. iRet = DialogBoxIndirectParam( g_hinst,
  277. (LPDLGTEMPLATE)hDlgTemplate,
  278. pCC->hwndOwner,
  279. ColorDlgProc,
  280. (LPARAM)pCI );
  281. #endif
  282. glpfnColorHook = 0;
  283. if (iRet == -1 || ((iRet == 0) && (!g_bUserPressedCancel) && (!GetStoredExtendedError())) )
  284. {
  285. StoreExtendedError(CDERR_DIALOGFAILURE);
  286. }
  287. }
  288. else
  289. {
  290. StoreExtendedError(CDERR_LOCKRESFAILURE);
  291. }
  292. return (iRet == IDOK);
  293. }
  294. // Does this dialog have Right to left layout?
  295. BOOL IsRTL(HWND hDlg)
  296. {
  297. return ((GetWindowLongPtr(hDlg, GWL_EXSTYLE) & WS_EX_LAYOUTRTL) == WS_EX_LAYOUTRTL);
  298. }
  299. ////////////////////////////////////////////////////////////////////////////
  300. //
  301. // ColorDlgProc
  302. //
  303. // Color Dialog.
  304. //
  305. ////////////////////////////////////////////////////////////////////////////
  306. BOOL_PTR CALLBACK ColorDlgProc(
  307. HWND hDlg,
  308. UINT wMsg,
  309. WPARAM wParam,
  310. LPARAM lParam)
  311. {
  312. PCOLORINFO pCI;
  313. BOOL_PTR bRet;
  314. BOOL_PTR bHookRet = FALSE;
  315. int temp;
  316. PAINTSTRUCT ps;
  317. HDC hDC;
  318. RECT rRect;
  319. RECT rcTemp;
  320. SHORT id;
  321. WORD nVal;
  322. BOOL bUpdateExample = FALSE;
  323. BOOL bOK;
  324. HWND hPointWnd;
  325. TCHAR cEdit[3];
  326. DWORD FAR *lpCust ;
  327. int i;
  328. POINT pt;
  329. LPCCHOOKPROC lpfnHook;
  330. //
  331. // The call to PvGetInst will fail until set under WM_INITDIALOG.
  332. //
  333. if (pCI = (PCOLORINFO)GetProp(hDlg, COLORPROP))
  334. {
  335. lpfnHook = GETHOOKFN(pCI->pCC);
  336. if ((lpfnHook) &&
  337. (bRet = (* lpfnHook)(hDlg, wMsg, wParam, lParam)))
  338. {
  339. if ((wMsg == WM_COMMAND) &&
  340. (GET_WM_COMMAND_ID(wParam, lParam) == IDCANCEL))
  341. {
  342. //
  343. // Set global flag stating that the user pressed cancel.
  344. //
  345. g_bUserPressedCancel = TRUE;
  346. }
  347. return (bRet);
  348. }
  349. }
  350. else if (wMsg != WM_INITDIALOG)
  351. {
  352. if (glpfnColorHook &&
  353. (bRet = (*glpfnColorHook)(hDlg, wMsg, wParam, lParam)))
  354. {
  355. return (bRet);
  356. }
  357. else
  358. {
  359. return (FALSE);
  360. }
  361. }
  362. switch (wMsg)
  363. {
  364. case ( WM_INITDIALOG ) :
  365. {
  366. //
  367. // Change cursor to hourglass.
  368. //
  369. HourGlass(TRUE);
  370. pCI = (PCOLORINFO)lParam;
  371. SetProp(hDlg, COLORPROP, (HANDLE)pCI);
  372. glpfnColorHook = 0;
  373. bRet = InitColor(hDlg, wParam, pCI);
  374. //
  375. // Change cursor back to arrow.
  376. //
  377. HourGlass(FALSE);
  378. return (bRet);
  379. break;
  380. }
  381. case ( WM_MOVE ) :
  382. {
  383. if (pCI)
  384. {
  385. SetupRainbowCapture(pCI);
  386. }
  387. return(FALSE);
  388. break;
  389. }
  390. case ( WM_LBUTTONDBLCLK ) :
  391. {
  392. LONG2POINT(lParam, pt);
  393. if (PtInRect((LPRECT)&pCI->rNearestPure, pt))
  394. {
  395. NearestSolid(pCI);
  396. }
  397. break;
  398. }
  399. case ( WM_MOUSEMOVE ) :
  400. {
  401. //
  402. // Dialog Boxes don't receive MOUSEMOVE unless mouse is captured.
  403. // If mouse isn't captured, break.
  404. //
  405. if (!bMouseCapture)
  406. {
  407. break;
  408. }
  409. // Fall Thru...
  410. }
  411. case ( WM_LBUTTONDOWN ) :
  412. {
  413. LONG2POINT(lParam, pt);
  414. if (PtInRect((LPRECT)&pCI->rRainbow, pt))
  415. {
  416. if (wMsg == WM_LBUTTONDOWN)
  417. {
  418. hDC = GetDC(hDlg);
  419. EraseCrossHair(hDC, pCI);
  420. ReleaseDC(hDlg, hDC);
  421. }
  422. pCI->nHuePos = LOWORD(lParam);
  423. HLSPostoHLS(COLOR_HUE, pCI);
  424. SetHLSEdit(COLOR_HUE, pCI);
  425. pCI->nSatPos = HIWORD(lParam);
  426. HLSPostoHLS(COLOR_SAT, pCI);
  427. SetHLSEdit(COLOR_SAT, pCI);
  428. pCI->currentRGB = HLStoRGB( pCI->currentHue,
  429. pCI->currentLum,
  430. pCI->currentSat );
  431. pCI->currentRGB = MapColor(pCI, pCI->currentRGB);
  432. hDC = GetDC(hDlg);
  433. RainbowPaint(pCI, hDC, (LPRECT)&pCI->rLumPaint);
  434. RainbowPaint(pCI, hDC, (LPRECT)&pCI->rColorSamples);
  435. ReleaseDC(hDlg, hDC);
  436. SetRGBEdit(0, pCI);
  437. if (!bMouseCapture)
  438. {
  439. SetCapture(hDlg);
  440. CopyRect(&rcTemp, &pCI->rRainbow);
  441. MapWindowPoints(hDlg, NULL, (LPPOINT)&rcTemp, 2);
  442. ClipCursor(&rcTemp);
  443. bMouseCapture = TRUE;
  444. }
  445. }
  446. else if ( PtInRect((LPRECT)&pCI->rLumPaint, pt) ||
  447. PtInRect((LPRECT)&pCI->rLumScroll, pt) )
  448. {
  449. hDC = GetDC(hDlg);
  450. EraseLumArrow(hDC, pCI);
  451. LumArrowPaint(hDC, pCI->nLumPos = HIWORD(lParam), pCI);
  452. HLSPostoHLS(COLOR_LUM, pCI);
  453. SetHLSEdit(COLOR_LUM, pCI);
  454. pCI->currentRGB = HLStoRGB( pCI->currentHue,
  455. pCI->currentLum,
  456. pCI->currentSat );
  457. pCI->currentRGB = MapColor(pCI, pCI->currentRGB);
  458. RainbowPaint(pCI, hDC, (LPRECT)&pCI->rColorSamples);
  459. ReleaseDC(hDlg, hDC);
  460. ValidateRect(hDlg, (LPRECT)&pCI->rLumScroll);
  461. ValidateRect(hDlg, (LPRECT)&pCI->rColorSamples);
  462. SetRGBEdit(0, pCI);
  463. if (!bMouseCapture)
  464. {
  465. SetCapture(hDlg);
  466. CopyRect(&rcTemp, &pCI->rLumScroll);
  467. MapWindowPoints(hDlg, NULL, (LPPOINT)&rcTemp, 2);
  468. ClipCursor(&rcTemp);
  469. bMouseCapture = TRUE;
  470. }
  471. }
  472. else
  473. {
  474. hPointWnd = ChildWindowFromPoint(hDlg, pt);
  475. if (hPointWnd == GetDlgItem(hDlg, COLOR_BOX1))
  476. {
  477. rRect.top = rColorBox[0].top;
  478. rRect.left = rColorBox[0].left;
  479. rRect.right = rColorBox[NUM_BASIC_COLORS - 1].right +
  480. BOX_X_MARGIN;
  481. rRect.bottom = rColorBox[NUM_BASIC_COLORS - 1].bottom +
  482. BOX_Y_MARGIN;
  483. temp = (NUM_BASIC_COLORS) / NUM_X_BOXES;
  484. id = 0;
  485. }
  486. else if (hPointWnd == GetDlgItem(hDlg, COLOR_CUSTOM1))
  487. {
  488. rRect.top = rColorBox[NUM_BASIC_COLORS].top;
  489. rRect.left = rColorBox[NUM_BASIC_COLORS].left;
  490. rRect.right = rColorBox[COLORBOXES - 1].right + BOX_X_MARGIN;
  491. rRect.bottom = rColorBox[COLORBOXES - 1].bottom + BOX_Y_MARGIN;
  492. temp = (NUM_CUSTOM_COLORS) / NUM_X_BOXES;
  493. id = NUM_BASIC_COLORS;
  494. }
  495. else
  496. {
  497. return (FALSE);
  498. }
  499. if (hPointWnd != GetFocus())
  500. {
  501. SetFocus(hPointWnd);
  502. }
  503. if (HIWORD(lParam) >= (WORD)rRect.bottom)
  504. {
  505. break;
  506. }
  507. if (LOWORD(lParam) >= (WORD)rRect.right)
  508. {
  509. break;
  510. }
  511. if (HIWORD(lParam) < (WORD)rRect.top)
  512. {
  513. break;
  514. }
  515. if (LOWORD(lParam) < (WORD)rRect.left)
  516. {
  517. break;
  518. }
  519. //
  520. // Make sure the click wasn't on a border between squares.
  521. //
  522. if ( ((LOWORD(lParam) - rRect.left) % nBoxWidth) >=
  523. (nBoxWidth - BOX_X_MARGIN) )
  524. {
  525. break;
  526. }
  527. if ( ((HIWORD(lParam) - rRect.top) % nBoxHeight) >=
  528. (nBoxHeight - BOX_Y_MARGIN) )
  529. {
  530. break;
  531. }
  532. //
  533. // Now calculate which square was selected.
  534. //
  535. id += (SHORT)(((HIWORD(lParam) - rRect.top) * temp /
  536. (rRect.bottom - rRect.top)) * NUM_X_BOXES);
  537. id += (SHORT)(((LOWORD(lParam) - rRect.left) * NUM_X_BOXES) /
  538. (rRect.right - rRect.left));
  539. if ((id < nDriverColors) || (id >= NUM_BASIC_COLORS))
  540. {
  541. ChangeBoxSelection(pCI, id);
  542. pCI->nCurBox = id;
  543. ChangeBoxFocus(pCI, id);
  544. if (id >= NUM_BASIC_COLORS)
  545. {
  546. pCI->nCurMix = pCI->nCurBox;
  547. }
  548. else
  549. {
  550. pCI->nCurDsp = pCI->nCurBox;
  551. }
  552. pCI->currentRGB = pCI->rgbBoxColor[pCI->nCurBox];
  553. pCI->currentRGB = MapColor(pCI, pCI->currentRGB);
  554. hDC = GetDC(hDlg);
  555. if (pCI->bFoldOut)
  556. {
  557. ChangeColorSettings(pCI);
  558. SetHLSEdit(0, pCI);
  559. SetRGBEdit(0, pCI);
  560. RainbowPaint(pCI, hDC, (LPRECT)&pCI->rColorSamples);
  561. }
  562. PaintBox(pCI, hDC, pCI->nCurDsp);
  563. PaintBox(pCI, hDC, pCI->nCurMix);
  564. ReleaseDC(hDlg, hDC);
  565. }
  566. }
  567. break;
  568. }
  569. case ( WM_LBUTTONUP ) :
  570. {
  571. LONG2POINT(lParam, pt);
  572. if (bMouseCapture)
  573. {
  574. bMouseCapture = FALSE;
  575. SetCapture(NULL);
  576. ClipCursor((LPRECT)NULL);
  577. if (PtInRect((LPRECT)&pCI->rRainbow, pt))
  578. {
  579. hDC = GetDC(hDlg);
  580. CrossHairPaint( hDC,
  581. pCI->nHuePos = LOWORD(lParam),
  582. pCI->nSatPos = HIWORD(lParam),
  583. pCI );
  584. RainbowPaint(pCI, hDC, (LPRECT)&pCI->rLumPaint);
  585. ReleaseDC(hDlg, hDC);
  586. ValidateRect(hDlg, (LPRECT)&pCI->rRainbow);
  587. }
  588. else if (PtInRect((LPRECT)&pCI->rLumPaint, pt))
  589. {
  590. //
  591. // Update Sample Shown.
  592. //
  593. hDC = GetDC(hDlg);
  594. LumArrowPaint(hDC, pCI->nLumPos, pCI);
  595. ReleaseDC(hDlg, hDC);
  596. ValidateRect(hDlg, (LPRECT)&pCI->rLumPaint);
  597. }
  598. }
  599. break;
  600. }
  601. case ( WM_CHAR ) :
  602. {
  603. if (wParam == VK_SPACE)
  604. {
  605. if (GetFocus() == GetDlgItem(hDlg, COLOR_BOX1))
  606. {
  607. temp = pCI->nCurDsp;
  608. }
  609. else if (GetFocus() == GetDlgItem(hDlg, COLOR_CUSTOM1))
  610. {
  611. temp = pCI->nCurMix;
  612. }
  613. else
  614. {
  615. return (FALSE);
  616. }
  617. pCI->currentRGB = pCI->rgbBoxColor[temp];
  618. pCI->currentRGB = MapColor(pCI, pCI->currentRGB);
  619. if (pCI->bFoldOut)
  620. {
  621. ChangeColorSettings(pCI);
  622. SetHLSEdit(0, pCI);
  623. SetRGBEdit(0, pCI);
  624. }
  625. InvalidateRect(hDlg, (LPRECT)&pCI->rColorSamples, FALSE);
  626. ChangeBoxSelection(pCI, (short)temp);
  627. pCI->nCurBox = (short)temp;
  628. bUpdateExample = TRUE;
  629. }
  630. break;
  631. }
  632. case ( WM_KEYDOWN ) :
  633. {
  634. if (ColorKeyDown(wParam, &temp, pCI, IsRTL(hDlg)))
  635. {
  636. ChangeBoxFocus(pCI, (SHORT)temp);
  637. }
  638. break;
  639. }
  640. case ( WM_GETDLGCODE ) :
  641. {
  642. return (DLGC_WANTALLKEYS | DLGC_WANTARROWS | DLGC_HASSETSEL);
  643. break;
  644. }
  645. case ( WM_COMMAND ) :
  646. {
  647. if (!pCI)
  648. {
  649. return (FALSE);
  650. }
  651. switch (GET_WM_COMMAND_ID(wParam, lParam))
  652. {
  653. case ( IDOK ) :
  654. {
  655. pCI->pCC->rgbResult = pCI->currentRGB;
  656. goto LeaveDialog;
  657. }
  658. case ( IDCANCEL ) :
  659. {
  660. g_bUserPressedCancel = TRUE;
  661. LeaveDialog:
  662. if (bMouseCapture)
  663. {
  664. bMouseCapture = FALSE;
  665. SetCapture(NULL);
  666. ClipCursor((LPRECT)NULL);
  667. }
  668. lpCust = pCI->pCC->lpCustColors;
  669. for ( i = NUM_BASIC_COLORS;
  670. i < NUM_BASIC_COLORS + NUM_CUSTOM_COLORS;
  671. i++ )
  672. {
  673. *lpCust++ = pCI->rgbBoxColor[i];
  674. }
  675. bRet = (GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
  676. lpfnHook = GETHOOKFN(pCI->pCC);
  677. #ifdef UNICODE
  678. if (pCI->ApiType == COMDLG_ANSI)
  679. {
  680. if (bRet && lpfnHook)
  681. {
  682. ThunkChooseColorW2A(pCI);
  683. bHookRet = (*lpfnHook)( hDlg,
  684. msgCOLOROKA,
  685. 0,
  686. (LONG_PTR)(LPTSTR)pCI->pCCA );
  687. }
  688. }
  689. else
  690. #endif
  691. {
  692. if (bRet && lpfnHook)
  693. {
  694. bHookRet = (*lpfnHook)( hDlg,
  695. msgCOLOROKW,
  696. 0,
  697. (LONG_PTR)(LPTSTR)pCI->pCC );
  698. }
  699. }
  700. if (bHookRet)
  701. {
  702. #ifdef UNICODE
  703. if (pCI->ApiType == COMDLG_ANSI)
  704. {
  705. ThunkChooseColorA2W(pCI);
  706. pCI->pCC->lCustData = pCI->pCCA->lCustData;
  707. }
  708. #endif
  709. break;
  710. }
  711. }
  712. case ( IDABORT ) :
  713. {
  714. if (pCI->pCC->Flags & CC_ENABLEHOOK)
  715. {
  716. glpfnColorHook = GETHOOKFN(pCI->pCC);
  717. }
  718. RemoveProp(hDlg, COLORPROP);
  719. EndDialog( hDlg,
  720. (GET_WM_COMMAND_ID(wParam, lParam) == IDABORT)
  721. ? (BOOL_PTR)lParam
  722. : bRet );
  723. if (hRainbowBitmap)
  724. {
  725. DeleteObject(hRainbowBitmap);
  726. hRainbowBitmap = NULL;
  727. }
  728. if (hDCFastBlt)
  729. {
  730. DeleteDC(hDCFastBlt);
  731. hDCFastBlt = 0;
  732. }
  733. break;
  734. }
  735. case ( pshHelp ) :
  736. {
  737. #ifdef UNICODE
  738. if (pCI->ApiType == COMDLG_ANSI)
  739. {
  740. if (msgHELPA && pCI->pCC->hwndOwner)
  741. {
  742. ThunkChooseColorW2A(pCI);
  743. SendMessage( pCI->pCC->hwndOwner,
  744. msgHELPA,
  745. (WPARAM)hDlg,
  746. (LPARAM)pCI->pCCA );
  747. ThunkChooseColorA2W(pCI);
  748. pCI->pCC->lCustData = pCI->pCCA->lCustData;
  749. }
  750. }
  751. else
  752. #endif
  753. {
  754. if (msgHELPW && pCI->pCC->hwndOwner)
  755. {
  756. SendMessage( pCI->pCC->hwndOwner,
  757. msgHELPW,
  758. (WPARAM)hDlg,
  759. (LPARAM)pCI->pCC );
  760. }
  761. }
  762. break;
  763. }
  764. case ( COLOR_SOLID ) :
  765. {
  766. NearestSolid(pCI);
  767. break;
  768. }
  769. case ( COLOR_RED ) :
  770. case ( COLOR_GREEN ) :
  771. case ( COLOR_BLUE ) :
  772. {
  773. if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
  774. {
  775. RGBEditChange(GET_WM_COMMAND_ID(wParam, lParam), pCI);
  776. InvalidateRect(hDlg, (LPRECT)&pCI->rColorSamples, FALSE);
  777. }
  778. else if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_KILLFOCUS)
  779. {
  780. GetDlgItemInt( hDlg,
  781. GET_WM_COMMAND_ID(wParam, lParam),
  782. &bOK,
  783. FALSE );
  784. if (!bOK)
  785. {
  786. SetRGBEdit(GET_WM_COMMAND_ID(wParam, lParam), pCI);
  787. }
  788. }
  789. break;
  790. }
  791. case ( COLOR_HUE ) :
  792. {
  793. if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
  794. {
  795. nVal = (WORD)GetDlgItemInt(hDlg, COLOR_HUE, &bOK, FALSE);
  796. if (bOK)
  797. {
  798. if (nVal > RANGE - 1)
  799. {
  800. nVal = RANGE - 1;
  801. SetDlgItemInt(hDlg, COLOR_HUE, (int)nVal, FALSE);
  802. }
  803. if (nVal != pCI->currentHue)
  804. {
  805. hDC = GetDC(hDlg);
  806. EraseCrossHair(hDC, pCI);
  807. pCI->currentHue = nVal;
  808. pCI->currentRGB = HLStoRGB( nVal,
  809. pCI->currentLum,
  810. pCI->currentSat );
  811. pCI->currentRGB = MapColor(pCI, pCI->currentRGB);
  812. SetRGBEdit(0, pCI);
  813. HLStoHLSPos(COLOR_HUE, pCI);
  814. CrossHairPaint( hDC,
  815. pCI->nHuePos,
  816. pCI->nSatPos,
  817. pCI );
  818. ReleaseDC(hDlg, hDC);
  819. InvalidateRect( hDlg,
  820. (LPRECT)&pCI->rLumPaint,
  821. FALSE );
  822. InvalidateRect( hDlg,
  823. (LPRECT)&pCI->rColorSamples,
  824. FALSE );
  825. UpdateWindow(hDlg);
  826. }
  827. }
  828. else if (GetDlgItemText(
  829. hDlg,
  830. COLOR_HUE,
  831. (LPTSTR)cEdit,
  832. 2 ))
  833. {
  834. SetHLSEdit(COLOR_HUE, pCI);
  835. SendDlgItemMessage(
  836. hDlg,
  837. COLOR_HUE,
  838. EM_SETSEL,
  839. (WPARAM)0,
  840. (LPARAM)-1 );
  841. }
  842. }
  843. else if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_KILLFOCUS)
  844. {
  845. GetDlgItemInt(hDlg, COLOR_HUE, &bOK, FALSE);
  846. if (!bOK)
  847. {
  848. SetHLSEdit(COLOR_HUE, pCI);
  849. }
  850. }
  851. break;
  852. }
  853. case ( COLOR_SAT ) :
  854. {
  855. if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
  856. {
  857. nVal = (WORD)GetDlgItemInt(hDlg, COLOR_SAT, &bOK, FALSE);
  858. if (bOK)
  859. {
  860. if (nVal > RANGE)
  861. {
  862. nVal = RANGE;
  863. SetDlgItemInt(hDlg, COLOR_SAT, (int)nVal, FALSE);
  864. }
  865. if (nVal != pCI->currentSat)
  866. {
  867. hDC = GetDC(hDlg);
  868. EraseCrossHair(hDC, pCI);
  869. pCI->currentSat = nVal;
  870. pCI->currentRGB = HLStoRGB( pCI->currentHue,
  871. pCI->currentLum,
  872. nVal );
  873. pCI->currentRGB = MapColor(pCI, pCI->currentRGB);
  874. SetRGBEdit(0, pCI);
  875. HLStoHLSPos(COLOR_SAT, pCI);
  876. CrossHairPaint( hDC,
  877. pCI->nHuePos,
  878. pCI->nSatPos,
  879. pCI );
  880. ReleaseDC(hDlg, hDC);
  881. InvalidateRect( hDlg,
  882. (LPRECT)&pCI->rLumPaint,
  883. FALSE );
  884. InvalidateRect( hDlg,
  885. (LPRECT)&pCI->rColorSamples,
  886. FALSE );
  887. UpdateWindow(hDlg);
  888. }
  889. }
  890. else if (GetDlgItemText(
  891. hDlg,
  892. COLOR_SAT,
  893. (LPTSTR)cEdit,
  894. 2 ))
  895. {
  896. SetHLSEdit(COLOR_SAT, pCI);
  897. SendDlgItemMessage(
  898. hDlg,
  899. COLOR_SAT,
  900. EM_SETSEL,
  901. (WPARAM)0,
  902. (LPARAM)-1 );
  903. }
  904. }
  905. else if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_KILLFOCUS)
  906. {
  907. GetDlgItemInt(hDlg, COLOR_SAT, &bOK, FALSE);
  908. if (!bOK)
  909. {
  910. SetHLSEdit(COLOR_SAT, pCI);
  911. }
  912. }
  913. break;
  914. }
  915. case ( COLOR_LUM ) :
  916. {
  917. if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
  918. {
  919. nVal = (WORD)GetDlgItemInt(hDlg, COLOR_LUM, &bOK, FALSE);
  920. if (bOK)
  921. {
  922. if (nVal > RANGE)
  923. {
  924. nVal = RANGE;
  925. SetDlgItemInt(hDlg, COLOR_LUM, (int)nVal, FALSE);
  926. }
  927. if (nVal != pCI->currentLum)
  928. {
  929. hDC = GetDC(hDlg);
  930. EraseLumArrow(hDC, pCI);
  931. pCI->currentLum = nVal;
  932. HLStoHLSPos(COLOR_LUM, pCI);
  933. pCI->currentRGB = HLStoRGB( pCI->currentHue,
  934. nVal,
  935. pCI->currentSat );
  936. pCI->currentRGB = MapColor(pCI, pCI->currentRGB);
  937. SetRGBEdit(0, pCI);
  938. LumArrowPaint(hDC, pCI->nLumPos, pCI);
  939. ReleaseDC(hDlg, hDC);
  940. InvalidateRect( hDlg,
  941. (LPRECT)&pCI->rColorSamples,
  942. FALSE );
  943. UpdateWindow(hDlg);
  944. }
  945. }
  946. else if (GetDlgItemText(
  947. hDlg,
  948. COLOR_LUM,
  949. (LPTSTR)cEdit,
  950. 2 ))
  951. {
  952. SetHLSEdit(COLOR_LUM, pCI);
  953. SendDlgItemMessage(
  954. hDlg,
  955. COLOR_LUM,
  956. EM_SETSEL,
  957. (WPARAM)0,
  958. (LPARAM)-1 );
  959. }
  960. }
  961. else if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_KILLFOCUS)
  962. {
  963. GetDlgItemInt(hDlg, COLOR_LUM, &bOK, FALSE);
  964. if (!bOK)
  965. {
  966. SetHLSEdit(COLOR_LUM, pCI);
  967. }
  968. }
  969. break;
  970. }
  971. case ( COLOR_ADD ) :
  972. {
  973. pCI->rgbBoxColor[pCI->nCurMix] = pCI->currentRGB;
  974. InvalidateRect(hDlg, (LPRECT)rColorBox + pCI->nCurMix, FALSE);
  975. if (pCI->nCurMix >= COLORBOXES - 1)
  976. {
  977. pCI->nCurMix = NUM_BASIC_COLORS;
  978. }
  979. #if HORIZONTELINC
  980. else
  981. {
  982. pCI->nCurMix++;
  983. }
  984. #else
  985. else if (pCI->nCurMix >= NUM_BASIC_COLORS + 8)
  986. {
  987. //
  988. // Increment nCurBox VERTICALLY! extra code
  989. // for vertical instead of horizontal increment.
  990. //
  991. pCI->nCurMix -= 7;
  992. }
  993. else
  994. {
  995. pCI->nCurMix += 8;
  996. }
  997. #endif
  998. break;
  999. }
  1000. case ( COLOR_MIX ) :
  1001. {
  1002. //
  1003. // Change cursor to hourglass.
  1004. //
  1005. HourGlass(TRUE);
  1006. InitRainbow(pCI);
  1007. //
  1008. // Code relies on COLOR_HUE through COLOR_BLUE being
  1009. // consecutive.
  1010. //
  1011. for (temp = COLOR_HUE; temp <= COLOR_BLUE; temp++)
  1012. {
  1013. EnableWindow(GetDlgItem(hDlg, temp), TRUE);
  1014. }
  1015. for (temp = COLOR_HUEACCEL; temp <= COLOR_BLUEACCEL; temp++)
  1016. {
  1017. EnableWindow(GetDlgItem(hDlg, temp), TRUE);
  1018. }
  1019. EnableWindow(GetDlgItem(hDlg, COLOR_ADD), TRUE);
  1020. EnableWindow(GetDlgItem(hDlg, COLOR_SOLID), TRUE);
  1021. EnableWindow(GetDlgItem(hDlg, COLOR_SOLID_RIGHT), TRUE);
  1022. EnableWindow(GetDlgItem(hDlg, COLOR_MIX), FALSE);
  1023. GetWindowRect(hDlg, (LPRECT)&rcTemp);
  1024. SetWindowPos( hDlg,
  1025. NULL,
  1026. pCI->rOriginal.left,
  1027. pCI->rOriginal.top,
  1028. pCI->rOriginal.right - pCI->rOriginal.left,
  1029. pCI->rOriginal.bottom - pCI->rOriginal.top,
  1030. SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
  1031. //
  1032. // Only invalidate exposed area.
  1033. //
  1034. rcTemp.right = rcTemp.left;
  1035. rcTemp.left = pCI->rOriginal.left;
  1036. InvalidateRect(hDlg, (LPRECT)&rcTemp, FALSE);
  1037. //
  1038. // Change cursor back to arrow.
  1039. //
  1040. HourGlass(FALSE);
  1041. SetFocus(GetDlgItem(hDlg, COLOR_HUE));
  1042. pCI->bFoldOut = TRUE;
  1043. break;
  1044. }
  1045. }
  1046. break;
  1047. }
  1048. case ( WM_QUERYNEWPALETTE ) :
  1049. {
  1050. if (pCI->hPal)
  1051. {
  1052. HDC hdc = GetDC(hDlg);
  1053. SelectPalette(hdc, pCI->hPal, FALSE);
  1054. i = RealizePalette(hdc);
  1055. ReleaseDC(hDlg, hdc);
  1056. if (i > 0)
  1057. {
  1058. InvalidateRect(hDlg, NULL, FALSE);
  1059. }
  1060. }
  1061. break;
  1062. }
  1063. case ( WM_PALETTECHANGED ) :
  1064. {
  1065. if (pCI->hPal && (HWND)wParam != hDlg)
  1066. {
  1067. InvalidateRect(hDlg, NULL, FALSE);
  1068. }
  1069. break;
  1070. }
  1071. case ( WM_PAINT ) :
  1072. {
  1073. BeginPaint(hDlg, (LPPAINTSTRUCT)&ps);
  1074. ColorPaint(hDlg, pCI, ps.hdc, (LPRECT)&ps.rcPaint);
  1075. EndPaint(hDlg, (LPPAINTSTRUCT)&ps);
  1076. break;
  1077. }
  1078. case ( WM_HELP ) :
  1079. {
  1080. if (IsWindowEnabled(hDlg))
  1081. {
  1082. WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle,
  1083. NULL,
  1084. HELP_WM_HELP,
  1085. (ULONG_PTR)(LPTSTR)aColorHelpIDs );
  1086. }
  1087. break;
  1088. }
  1089. case ( WM_CONTEXTMENU ) :
  1090. {
  1091. if (IsWindowEnabled(hDlg))
  1092. {
  1093. WinHelp( (HWND)wParam,
  1094. NULL,
  1095. HELP_CONTEXTMENU,
  1096. (ULONG_PTR)(LPVOID)aColorHelpIDs );
  1097. }
  1098. break;
  1099. }
  1100. default :
  1101. {
  1102. if (wMsg == msgSETRGBA || wMsg == msgSETRGBW)
  1103. {
  1104. if (ChangeColorBox(pCI, (DWORD)lParam))
  1105. {
  1106. pCI->currentRGB = MapColor(pCI, (DWORD) lParam);
  1107. if (pCI->nCurBox < pCI->nCurMix)
  1108. {
  1109. pCI->nCurDsp = pCI->nCurBox;
  1110. }
  1111. else
  1112. {
  1113. pCI->nCurMix = pCI->nCurBox;
  1114. }
  1115. }
  1116. if (pCI->bFoldOut)
  1117. {
  1118. pCI->currentRGB = MapColor(pCI, (DWORD) lParam);
  1119. ChangeColorSettings(pCI);
  1120. SetHLSEdit(0, pCI);
  1121. SetRGBEdit(0, pCI);
  1122. hDC = GetDC(hDlg);
  1123. RainbowPaint(pCI, hDC, (LPRECT)&pCI->rColorSamples);
  1124. ReleaseDC(hDlg, hDC);
  1125. }
  1126. break;
  1127. }
  1128. return (FALSE);
  1129. break;
  1130. }
  1131. }
  1132. return (TRUE);
  1133. }
  1134. ////////////////////////////////////////////////////////////////////////////
  1135. //
  1136. // ChangeColorBox
  1137. //
  1138. // Update box shown.
  1139. //
  1140. ////////////////////////////////////////////////////////////////////////////
  1141. BOOL ChangeColorBox(
  1142. register PCOLORINFO pCI,
  1143. DWORD dwRGBcolor)
  1144. {
  1145. register short nBox;
  1146. for (nBox = 0; nBox < COLORBOXES; nBox++)
  1147. {
  1148. if (pCI->rgbBoxColor[nBox] == dwRGBcolor)
  1149. {
  1150. break;
  1151. }
  1152. }
  1153. if (nBox >= COLORBOXES)
  1154. {
  1155. //
  1156. // Color Not Found. Now What Should We Do?
  1157. //
  1158. }
  1159. else
  1160. {
  1161. ChangeBoxSelection(pCI, nBox);
  1162. pCI->nCurBox = nBox;
  1163. }
  1164. return (nBox < COLORBOXES);
  1165. }
  1166. ////////////////////////////////////////////////////////////////////////////
  1167. //
  1168. // HiLiteBox
  1169. //
  1170. ////////////////////////////////////////////////////////////////////////////
  1171. VOID HiLiteBox(
  1172. HDC hDC,
  1173. SHORT nBox,
  1174. SHORT fStyle)
  1175. {
  1176. RECT rRect;
  1177. HBRUSH hBrush;
  1178. CopyRect((LPRECT)&rRect, (LPRECT)rColorBox + nBox);
  1179. rRect.left--, rRect.top--, rRect.right++, rRect.bottom++;
  1180. hBrush = CreateSolidBrush((fStyle & 1) ? 0L : GetSysColor(COLOR_3DFACE));
  1181. FrameRect(hDC, (LPRECT)&rRect, hBrush);
  1182. DeleteObject(hBrush);
  1183. }
  1184. ////////////////////////////////////////////////////////////////////////////
  1185. //
  1186. // ChangeBoxSelection
  1187. //
  1188. ////////////////////////////////////////////////////////////////////////////
  1189. VOID ChangeBoxSelection(
  1190. PCOLORINFO pCI,
  1191. SHORT nNewBox)
  1192. {
  1193. register HDC hDC;
  1194. register HWND hDlg = pCI->hDialog;
  1195. hDC = GetDC(hDlg);
  1196. HiLiteBox(hDC, pCI->nCurBox, 0);
  1197. HiLiteBox(hDC, nNewBox, 1);
  1198. ReleaseDC(hDlg, hDC);
  1199. pCI->currentRGB = pCI->rgbBoxColor[nNewBox];
  1200. pCI->currentRGB = MapColor(pCI, pCI->currentRGB);
  1201. }
  1202. ////////////////////////////////////////////////////////////////////////////
  1203. //
  1204. // ChangeBoxFocus
  1205. //
  1206. // Can't trust the state of the XOR for DrawFocusRect, so must draw
  1207. // the rectangle in the window background color first.
  1208. //
  1209. ////////////////////////////////////////////////////////////////////////////
  1210. VOID ChangeBoxFocus(
  1211. PCOLORINFO pCI,
  1212. SHORT nNewBox)
  1213. {
  1214. HANDLE hDlg = pCI->hDialog;
  1215. HDC hDC;
  1216. RECT rRect;
  1217. LPWORD nCur = (LPWORD)((nNewBox < (NUM_BASIC_COLORS))
  1218. ? (LONG_PTR)&pCI->nCurDsp
  1219. : (LONG_PTR)&pCI->nCurMix);
  1220. HPEN hPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DFACE));
  1221. HBRUSH hBrush = GetStockObject(HOLLOW_BRUSH);
  1222. hDC = GetDC(hDlg);
  1223. hPen = SelectObject(hDC, hPen);
  1224. hBrush = SelectObject(hDC, hBrush);
  1225. CopyRect((LPRECT)&rRect, (LPRECT)rColorBox + *nCur);
  1226. InflateRect((LPRECT)&rRect, 3, 3);
  1227. Rectangle(hDC, rRect.left, rRect.top, rRect.right, rRect.bottom);
  1228. CopyRect((LPRECT)&rRect, (LPRECT)rColorBox + (*nCur = nNewBox));
  1229. InflateRect((LPRECT)&rRect, 3, 3);
  1230. Rectangle(hDC, rRect.left, rRect.top, rRect.right, rRect.bottom);
  1231. DrawFocusRect(hDC, (LPRECT)&rRect);
  1232. hPen = SelectObject(hDC, hPen);
  1233. SelectObject(hDC, hBrush);
  1234. ReleaseDC(hDlg, hDC);
  1235. DeleteObject(hPen);
  1236. }
  1237. ////////////////////////////////////////////////////////////////////////////
  1238. //
  1239. // ColorKeyDown
  1240. //
  1241. ////////////////////////////////////////////////////////////////////////////
  1242. BOOL ColorKeyDown(
  1243. WPARAM wParam,
  1244. int *id,
  1245. PCOLORINFO pCI,
  1246. BOOL bRTL)
  1247. {
  1248. WORD temp;
  1249. temp = (WORD)GetWindowLong(GetFocus(), GWL_ID);
  1250. if (temp == COLOR_BOX1)
  1251. {
  1252. temp = pCI->nCurDsp;
  1253. }
  1254. else if (temp == COLOR_CUSTOM1)
  1255. {
  1256. temp = pCI->nCurMix;
  1257. }
  1258. else
  1259. {
  1260. return (FALSE);
  1261. }
  1262. // Switch meaning of right and left if we have RTL layout.
  1263. if (bRTL)
  1264. {
  1265. if (wParam == VK_LEFT)
  1266. {
  1267. wParam = VK_RIGHT;
  1268. }
  1269. else if (wParam == VK_RIGHT)
  1270. {
  1271. wParam = VK_LEFT;
  1272. }
  1273. }
  1274. switch (wParam)
  1275. {
  1276. case ( VK_UP ) :
  1277. {
  1278. if (temp >= (NUM_BASIC_COLORS + NUM_X_BOXES))
  1279. {
  1280. temp -= NUM_X_BOXES;
  1281. }
  1282. else if ((temp < NUM_BASIC_COLORS) && (temp >= NUM_X_BOXES))
  1283. {
  1284. temp -= NUM_X_BOXES;
  1285. }
  1286. break;
  1287. }
  1288. case ( VK_HOME ) :
  1289. {
  1290. if (temp == pCI->nCurDsp)
  1291. {
  1292. temp = 0;
  1293. }
  1294. else
  1295. {
  1296. temp = NUM_BASIC_COLORS;
  1297. }
  1298. break;
  1299. }
  1300. case ( VK_END ) :
  1301. {
  1302. if (temp == pCI->nCurDsp)
  1303. {
  1304. temp = (WORD)(nDriverColors - 1);
  1305. }
  1306. else
  1307. {
  1308. temp = COLORBOXES - 1;
  1309. }
  1310. break;
  1311. }
  1312. case ( VK_DOWN ) :
  1313. {
  1314. if (temp < (NUM_BASIC_COLORS - NUM_X_BOXES))
  1315. {
  1316. temp += NUM_X_BOXES;
  1317. }
  1318. else if ((temp >= (NUM_BASIC_COLORS)) &&
  1319. (temp < (COLORBOXES - NUM_X_BOXES)))
  1320. {
  1321. temp += NUM_X_BOXES;
  1322. }
  1323. break;
  1324. }
  1325. case ( VK_LEFT ) :
  1326. {
  1327. if (temp % NUM_X_BOXES)
  1328. {
  1329. temp--;
  1330. }
  1331. break;
  1332. }
  1333. case ( VK_RIGHT ) :
  1334. {
  1335. if (!(++temp % NUM_X_BOXES))
  1336. {
  1337. --temp;
  1338. }
  1339. break;
  1340. }
  1341. }
  1342. //
  1343. // If we've received colors from the driver, make certain the arrow would
  1344. // not take us to an undefined color.
  1345. //
  1346. if ((temp >= (WORD)nDriverColors) && (temp < NUM_BASIC_COLORS))
  1347. {
  1348. temp = pCI->nCurDsp;
  1349. }
  1350. *id = temp;
  1351. return ((temp != pCI->nCurDsp) && (temp != pCI->nCurMix));
  1352. }
  1353. ////////////////////////////////////////////////////////////////////////////
  1354. //
  1355. // FillBox
  1356. //
  1357. ////////////////////////////////////////////////////////////////////////////
  1358. VOID FillBox(
  1359. PCOLORINFO pCI,
  1360. HDC hDC,
  1361. LPRECT prc,
  1362. COLORREF rgb)
  1363. {
  1364. HBRUSH hBrush;
  1365. RECT rc = *prc;
  1366. DrawEdge(hDC, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
  1367. hBrush = CreateSolidBrush(MapColor(pCI, rgb));
  1368. FillRect(hDC, &rc, hBrush);
  1369. DeleteObject(hBrush);
  1370. }
  1371. ////////////////////////////////////////////////////////////////////////////
  1372. //
  1373. // PaintBox
  1374. //
  1375. ////////////////////////////////////////////////////////////////////////////
  1376. VOID PaintBox(
  1377. PCOLORINFO pCI,
  1378. register HDC hDC,
  1379. SHORT i)
  1380. {
  1381. if ((i < NUM_BASIC_COLORS) && (i >= nDriverColors))
  1382. {
  1383. return;
  1384. }
  1385. FillBox(pCI, hDC, &rColorBox[i], pCI->rgbBoxColor[i]);
  1386. if (i == (short)pCI->nCurBox)
  1387. {
  1388. HiLiteBox(hDC, i, 1);
  1389. }
  1390. }
  1391. ////////////////////////////////////////////////////////////////////////////
  1392. //
  1393. // InitScreenCoords
  1394. //
  1395. // Returns TRUE iff we make it.
  1396. //
  1397. ////////////////////////////////////////////////////////////////////////////
  1398. BOOL InitScreenCoords(
  1399. HWND hDlg,
  1400. PCOLORINFO pCI)
  1401. {
  1402. RECT rRect;
  1403. SHORT i;
  1404. // DWORD *lpDriverRGB;
  1405. HWND hBox1, hCustom1;
  1406. hBox1 = GetDlgItem(hDlg, COLOR_BOX1);
  1407. hCustom1 = GetDlgItem(hDlg, COLOR_CUSTOM1);
  1408. lpprocStatic = (WNDPROC)GetWindowLongPtr(hBox1, GWLP_WNDPROC);
  1409. SetWindowLongPtr(hBox1, GWLP_WNDPROC, (LONG_PTR)WantArrows);
  1410. SetWindowLongPtr(hCustom1, GWLP_WNDPROC, (LONG_PTR)WantArrows);
  1411. GetWindowRect(hBox1, (LPRECT)&rRect);
  1412. MapWindowPoints(NULL, hDlg, (LPPOINT)&rRect, 2);
  1413. rRect.left += (BOX_X_MARGIN + 1) / 2;
  1414. rRect.top += (BOX_Y_MARGIN + 1) / 2;
  1415. rRect.right -= (BOX_X_MARGIN + 1) / 2;
  1416. rRect.bottom -= (BOX_Y_MARGIN + 1) / 2;
  1417. nBoxWidth = (SHORT)((rRect.right - rRect.left) / NUM_X_BOXES);
  1418. nBoxHeight = (SHORT)((rRect.bottom - rRect.top) /
  1419. (NUM_BASIC_COLORS / NUM_X_BOXES));
  1420. //
  1421. // Assume no colors from driver.
  1422. //
  1423. nDriverColors = 0;
  1424. for (i = 0; i < NUM_BASIC_COLORS; i++)
  1425. {
  1426. rColorBox[i].left = rRect.left + nBoxWidth * (i % NUM_X_BOXES);
  1427. rColorBox[i].right = rColorBox[i].left + nBoxWidth - BOX_X_MARGIN;
  1428. rColorBox[i].top = rRect.top + nBoxHeight * (i / NUM_X_BOXES);
  1429. rColorBox[i].bottom = rColorBox[i].top + nBoxHeight - BOX_Y_MARGIN;
  1430. //
  1431. // Setup the colors. If the driver still has colors to give, take it.
  1432. // If not, if the driver actually gave colors, set the color to white.
  1433. // Otherwise set to the default colors.
  1434. //
  1435. if (i < nDriverColors)
  1436. {
  1437. // pCI->rgbBoxColor[i] = *lpDriverRGB++;
  1438. }
  1439. else
  1440. {
  1441. pCI->rgbBoxColor[i] = nDriverColors
  1442. ? 0xFFFFFF
  1443. : rgbBoxColorDefault[i];
  1444. }
  1445. }
  1446. //
  1447. // If no driver colors, use default number.
  1448. //
  1449. if (!nDriverColors)
  1450. {
  1451. nDriverColors = NUM_BASIC_COLORS;
  1452. }
  1453. GetWindowRect(hCustom1, (LPRECT)&rRect);
  1454. MapWindowPoints(NULL, hDlg, (LPPOINT)&rRect, 2);
  1455. rRect.left += (BOX_X_MARGIN + 1) / 2;
  1456. rRect.top += (BOX_Y_MARGIN + 1) / 2;
  1457. rRect.right -= (BOX_X_MARGIN + 1) / 2;
  1458. rRect.bottom -= (BOX_Y_MARGIN + 1) / 2;
  1459. for (; i < COLORBOXES; i++)
  1460. {
  1461. rColorBox[i].left = rRect.left +
  1462. nBoxWidth * ((i - (NUM_BASIC_COLORS)) % NUM_X_BOXES);
  1463. rColorBox[i].right = rColorBox[i].left + nBoxWidth - BOX_X_MARGIN;
  1464. rColorBox[i].top = rRect.top +
  1465. nBoxHeight * ((i - (NUM_BASIC_COLORS)) / NUM_X_BOXES);
  1466. rColorBox[i].bottom = rColorBox[i].top + nBoxHeight - BOX_Y_MARGIN;
  1467. }
  1468. return (TRUE);
  1469. }
  1470. ////////////////////////////////////////////////////////////////////////////
  1471. //
  1472. // SetupRainbowCapture
  1473. //
  1474. ////////////////////////////////////////////////////////////////////////////
  1475. VOID SetupRainbowCapture(
  1476. PCOLORINFO pCI)
  1477. {
  1478. HWND hwnd;
  1479. HWND hDlg = pCI->hDialog;
  1480. hwnd = GetDlgItem(hDlg, COLOR_RAINBOW);
  1481. GetClientRect(hwnd, &pCI->rRainbow);
  1482. MapWindowPoints(hwnd, hDlg, (LPPOINT)&pCI->rRainbow, 2);
  1483. hwnd = GetDlgItem(hDlg, COLOR_LUMSCROLL);
  1484. GetClientRect(hwnd, &pCI->rLumPaint);
  1485. MapWindowPoints(hwnd, hDlg, (LPPOINT)&pCI->rLumPaint, 2);
  1486. hwnd = GetDlgItem(hDlg, COLOR_CURRENT);
  1487. GetClientRect(hwnd, &pCI->rColorSamples);
  1488. MapWindowPoints(hwnd, hDlg, (LPPOINT)&pCI->rColorSamples, 2);
  1489. pCI->rLumScroll = pCI->rLumPaint;
  1490. pCI->rLumScroll.left = pCI->rLumScroll.right;
  1491. pCI->rLumScroll.right += cxSize / 2;
  1492. pCI->nLumHeight = (WORD)(pCI->rLumPaint.bottom - pCI->rLumPaint.top);
  1493. pCI->rNearestPure = pCI->rColorSamples;
  1494. pCI->rCurrentColor = pCI->rColorSamples;
  1495. pCI->rCurrentColor.right = (pCI->rColorSamples.left + pCI->rColorSamples.right) / 2;
  1496. pCI->rNearestPure.left = pCI->rCurrentColor.right;
  1497. }
  1498. ////////////////////////////////////////////////////////////////////////////
  1499. //
  1500. // InitColor
  1501. //
  1502. // Returns TRUE iff everything's OK.
  1503. //
  1504. ////////////////////////////////////////////////////////////////////////////
  1505. BOOL_PTR InitColor(
  1506. HWND hDlg,
  1507. WPARAM wParam,
  1508. PCOLORINFO pCI)
  1509. {
  1510. SHORT i;
  1511. RECT rRect;
  1512. LPCHOOSECOLOR pCC = pCI->pCC;
  1513. HDC hDC;
  1514. DWORD FAR *lpCust;
  1515. BOOL_PTR bRet;
  1516. HWND hCtlSolid = GetDlgItem(hDlg, COLOR_SOLID);
  1517. if (!hDCFastBlt)
  1518. {
  1519. hDC = GetDC(hDlg);
  1520. hDCFastBlt = CreateCompatibleDC(hDC);
  1521. ReleaseDC(hDlg, hDC);
  1522. if (!hDCFastBlt)
  1523. {
  1524. return(FALSE);
  1525. }
  1526. }
  1527. pCI->hDialog = hDlg;
  1528. SetupRainbowCapture(pCI);
  1529. if (pCC->Flags & CC_RGBINIT)
  1530. {
  1531. pCI->currentRGB = pCC->rgbResult;
  1532. }
  1533. else
  1534. {
  1535. pCI->currentRGB = 0L;
  1536. }
  1537. if (pCC->Flags & (CC_PREVENTFULLOPEN | CC_FULLOPEN))
  1538. {
  1539. EnableWindow(GetDlgItem(hDlg, COLOR_MIX), FALSE);
  1540. }
  1541. if (pCC->Flags & CC_SOLIDCOLOR)
  1542. {
  1543. ShowWindow(GetDlgItem(hDlg, COLOR_SOLID_RIGHT), SW_HIDE);
  1544. }
  1545. if (pCC->Flags & CC_FULLOPEN)
  1546. {
  1547. InitRainbow(pCI);
  1548. pCI->bFoldOut = TRUE;
  1549. RGBtoHLS(pCI->currentRGB);
  1550. pCI->currentHue = gHue;
  1551. pCI->currentSat = gSat;
  1552. pCI->currentLum = gLum;
  1553. SetRGBEdit(0, pCI);
  1554. SetHLSEdit(0, pCI);
  1555. }
  1556. else
  1557. {
  1558. //
  1559. // Code relies on COLOR_HUE through COLOR_BLUE being consecutive.
  1560. //
  1561. for (i = COLOR_HUE; i <= COLOR_BLUE; i++)
  1562. {
  1563. EnableWindow(GetDlgItem(hDlg, i), FALSE);
  1564. }
  1565. for (i = COLOR_HUEACCEL; i <= COLOR_BLUEACCEL; i++)
  1566. {
  1567. EnableWindow(GetDlgItem(hDlg, i), FALSE);
  1568. }
  1569. EnableWindow(GetDlgItem(hDlg, COLOR_ADD), FALSE);
  1570. EnableWindow(hCtlSolid, FALSE);
  1571. EnableWindow(GetDlgItem(hDlg, COLOR_SOLID_RIGHT), FALSE);
  1572. pCI->bFoldOut = FALSE;
  1573. GetWindowRect(GetDlgItem(hDlg, COLOR_BOX1), &rRect);
  1574. MapWindowPoints(NULL, hDlg, (LPPOINT)&rRect, 2);
  1575. i = (SHORT)rRect.right;
  1576. GetWindowRect(GetDlgItem(hDlg, COLOR_RAINBOW), &rRect);
  1577. MapWindowPoints(NULL, hDlg, (LPPOINT)&rRect, 2);
  1578. GetWindowRect(hDlg, &(pCI->rOriginal));
  1579. MoveWindow( hDlg,
  1580. pCI->rOriginal.left,
  1581. pCI->rOriginal.top,
  1582. (rRect.left + i) / 2,
  1583. pCI->rOriginal.bottom - pCI->rOriginal.top,
  1584. FALSE );
  1585. }
  1586. InitScreenCoords(hDlg, pCI);
  1587. lpCust = pCC->lpCustColors;
  1588. for (i = NUM_BASIC_COLORS; i < NUM_BASIC_COLORS + NUM_CUSTOM_COLORS; i++)
  1589. {
  1590. pCI->rgbBoxColor[i] = *lpCust++;
  1591. }
  1592. pCI->nCurBox = pCI->nCurDsp = 0;
  1593. pCI->nCurMix = NUM_BASIC_COLORS;
  1594. ChangeColorBox(pCI, pCI->currentRGB);
  1595. if (pCI->nCurBox < pCI->nCurMix)
  1596. {
  1597. pCI->nCurDsp = pCI->nCurBox;
  1598. }
  1599. else
  1600. {
  1601. pCI->nCurMix = pCI->nCurBox;
  1602. }
  1603. if (!(pCC->Flags & CC_SHOWHELP))
  1604. {
  1605. HWND hHelp;
  1606. EnableWindow(hHelp = GetDlgItem(hDlg, pshHelp), FALSE);
  1607. ShowWindow(hHelp, SW_HIDE);
  1608. }
  1609. SetWindowLong( hCtlSolid,
  1610. GWL_STYLE,
  1611. GetWindowLong(hCtlSolid, GWL_STYLE) & (~WS_TABSTOP) );
  1612. if (pCC->lpfnHook)
  1613. {
  1614. LPCCHOOKPROC lpfnHook = GETHOOKFN(pCC);
  1615. #ifdef UNICODE
  1616. if (pCI->ApiType == COMDLG_ANSI)
  1617. {
  1618. ThunkChooseColorW2A(pCI);
  1619. bRet = ((* lpfnHook)( hDlg,
  1620. WM_INITDIALOG,
  1621. wParam,
  1622. (LPARAM)pCI->pCCA ));
  1623. //
  1624. // Strange win 31 example uses lCustData to hold a temporary
  1625. // variable that it passes back to calling function.
  1626. //
  1627. ThunkChooseColorA2W(pCI);
  1628. pCC->lCustData = pCI->pCCA->lCustData;
  1629. }
  1630. else
  1631. #endif
  1632. {
  1633. bRet = ((* lpfnHook)( hDlg,
  1634. WM_INITDIALOG,
  1635. wParam,
  1636. (LPARAM)pCC ));
  1637. }
  1638. }
  1639. else
  1640. {
  1641. bRet = TRUE;
  1642. }
  1643. return (bRet);
  1644. }
  1645. ////////////////////////////////////////////////////////////////////////////
  1646. //
  1647. // ColorPaint
  1648. //
  1649. ////////////////////////////////////////////////////////////////////////////
  1650. VOID ColorPaint(
  1651. HWND hDlg,
  1652. PCOLORINFO pCI,
  1653. HDC hDC,
  1654. LPRECT lpPaintRect)
  1655. {
  1656. SHORT i;
  1657. HWND hFocus;
  1658. for (i = 0; i < nDriverColors; i++)
  1659. {
  1660. PaintBox(pCI, hDC, i);
  1661. }
  1662. for (i = NUM_BASIC_COLORS; i < COLORBOXES; i++)
  1663. {
  1664. PaintBox(pCI, hDC, i);
  1665. }
  1666. //
  1667. // Must redraw focus as well as paint boxes.
  1668. //
  1669. hFocus = GetFocus();
  1670. if (hFocus == GetDlgItem(hDlg, COLOR_BOX1))
  1671. {
  1672. i = pCI->nCurDsp;
  1673. }
  1674. else if (hFocus == GetDlgItem(hDlg, COLOR_CUSTOM1))
  1675. {
  1676. i = pCI->nCurMix;
  1677. }
  1678. else
  1679. {
  1680. goto NoDrawFocus;
  1681. }
  1682. ChangeBoxFocus(pCI, i);
  1683. NoDrawFocus:
  1684. RainbowPaint(pCI, hDC, lpPaintRect);
  1685. }
  1686. ////////////////////////////////////////////////////////////////////////////
  1687. //
  1688. // WantArrows
  1689. //
  1690. ////////////////////////////////////////////////////////////////////////////
  1691. LONG WINAPI WantArrows(
  1692. HWND hWnd,
  1693. UINT msg,
  1694. WPARAM wParam,
  1695. LPARAM lParam)
  1696. {
  1697. PCOLORINFO pCI;
  1698. RECT rcTemp;
  1699. HDC hDC;
  1700. WORD temp;
  1701. switch (msg)
  1702. {
  1703. case ( WM_GETDLGCODE ) :
  1704. return (DLGC_WANTARROWS | DLGC_WANTCHARS);
  1705. case WM_KEYDOWN:
  1706. case WM_CHAR:
  1707. return ((LONG) SendMessage(GetParent(hWnd), msg, wParam, lParam));
  1708. case ( WM_SETFOCUS ) :
  1709. case ( WM_KILLFOCUS ) :
  1710. {
  1711. if (pCI = (PCOLORINFO) GetProp(GetParent(hWnd), COLORPROP))
  1712. {
  1713. if (GetWindowLong(hWnd, GWL_ID) == COLOR_BOX1)
  1714. {
  1715. temp = pCI->nCurDsp;
  1716. }
  1717. else
  1718. {
  1719. temp = pCI->nCurMix;
  1720. }
  1721. hDC = GetDC(GetParent(hWnd));
  1722. CopyRect((LPRECT)&rcTemp, (LPRECT)rColorBox + temp);
  1723. InflateRect((LPRECT)&rcTemp, 3, 3);
  1724. DrawFocusRect(hDC, (LPRECT)&rcTemp);
  1725. ReleaseDC(GetParent(hWnd), hDC);
  1726. }
  1727. break;
  1728. }
  1729. default:
  1730. break;
  1731. }
  1732. return ((LONG)CallWindowProc(lpprocStatic, hWnd, msg, wParam, lParam));
  1733. }
  1734. ////////////////////////////////////////////////////////////////////////////
  1735. //
  1736. // MapColor
  1737. //
  1738. ////////////////////////////////////////////////////////////////////////////
  1739. DWORD MapColor(
  1740. PCOLORINFO pCI,
  1741. DWORD rgb)
  1742. {
  1743. if (pCI->pCC->Flags & CC_SOLIDCOLOR)
  1744. {
  1745. HDC hdc = GetDC(NULL);
  1746. rgb = GetNearestColor(hdc, rgb);
  1747. ReleaseDC(NULL, hdc);
  1748. }
  1749. return (rgb);
  1750. }
  1751. ////////////////////////////////////////////////////////////////////////////
  1752. //
  1753. // TermColor
  1754. //
  1755. ////////////////////////////////////////////////////////////////////////////
  1756. VOID TermColor()
  1757. {
  1758. if (hRainbowBitmap)
  1759. {
  1760. DeleteObject(hRainbowBitmap);
  1761. hRainbowBitmap = NULL;
  1762. }
  1763. if (hDCFastBlt)
  1764. {
  1765. DeleteDC(hDCFastBlt);
  1766. hDCFastBlt = 0;
  1767. }
  1768. }
  1769. /*========================================================================*/
  1770. /* Ansi->Unicode Thunk routines */
  1771. /*========================================================================*/
  1772. #ifdef UNICODE
  1773. ////////////////////////////////////////////////////////////////////////////
  1774. //
  1775. // ThunkChooseColorA2W
  1776. //
  1777. ////////////////////////////////////////////////////////////////////////////
  1778. VOID ThunkChooseColorA2W(
  1779. PCOLORINFO pCI)
  1780. {
  1781. LPCHOOSECOLORW pCCW = pCI->pCC;
  1782. LPCHOOSECOLORA pCCA = pCI->pCCA;
  1783. pCCW->lCustData = pCCA->lCustData;
  1784. pCCW->Flags = pCCA->Flags;
  1785. pCCW->hInstance = pCCA->hInstance;
  1786. pCCW->lpfnHook = pCCA->lpfnHook;
  1787. //
  1788. // CC_RGBINIT conditional = time it takes to do it => just do it.
  1789. //
  1790. pCCW->rgbResult = pCCA->rgbResult;
  1791. pCCW->lpCustColors = pCCA->lpCustColors;
  1792. }
  1793. ////////////////////////////////////////////////////////////////////////////
  1794. //
  1795. // ThunkChooseColorW2A
  1796. //
  1797. ////////////////////////////////////////////////////////////////////////////
  1798. VOID ThunkChooseColorW2A(
  1799. PCOLORINFO pCI)
  1800. {
  1801. LPCHOOSECOLORW pCCW = pCI->pCC;
  1802. LPCHOOSECOLORA pCCA = pCI->pCCA;
  1803. //
  1804. // Supposedly invariant, but not necessarily.
  1805. //
  1806. pCCA->Flags = pCCW->Flags;
  1807. pCCA->lCustData = pCCW->lCustData;
  1808. pCCA->lpfnHook = pCCW->lpfnHook;
  1809. pCCA->rgbResult = pCCW->rgbResult;
  1810. pCCA->lpCustColors = pCCW->lpCustColors;
  1811. }
  1812. #ifdef WINNT
  1813. ////////////////////////////////////////////////////////////////////////////
  1814. //
  1815. // Ssync_ANSI_UNICODE_CC_For_WOW
  1816. //
  1817. // Function to allow NT WOW to keep the ANSI & UNICODE versions of
  1818. // the CHOOSEFONT structure in ssync as required by many 16-bit apps.
  1819. // See notes for Ssync_ANSI_UNICODE_Struct_For_WOW() in dlgs.c.
  1820. //
  1821. ////////////////////////////////////////////////////////////////////////////
  1822. VOID Ssync_ANSI_UNICODE_CC_For_WOW(
  1823. HWND hDlg,
  1824. BOOL f_ANSI_to_UNICODE)
  1825. {
  1826. PCOLORINFO pCI;
  1827. if (pCI = (PCOLORINFO)GetProp(hDlg, COLORPROP))
  1828. {
  1829. if (pCI->pCC && pCI->pCCA)
  1830. {
  1831. if (f_ANSI_to_UNICODE)
  1832. {
  1833. ThunkChooseColorA2W(pCI);
  1834. }
  1835. else
  1836. {
  1837. ThunkChooseColorW2A(pCI);
  1838. }
  1839. }
  1840. }
  1841. }
  1842. #endif
  1843. #endif