COLORWP.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:39k
源码类别:
Windows编程
开发平台:
Visual C++
- /***************************************************************************
- * *
- * MODULE : ColorWP.c *
- * *
- * DESCRIPTION : Window function for the colors window and related fns. *
- * *
- * FUNCTIONS : ColorWP () - Window function for colors *
- * window. *
- * *
- * ComputeInverseColor() - Gets the inverse RGB of a given *
- * RGB value *
- * *
- * HISTORY : 6/21/89 - adapted from pBrush - LR *
- * *
- ***************************************************************************/
- #include "imagedit.h"
- #include "dialogs.h"
- #include <windowsx.h>
- #include <commdlg.h>
- STATICFN VOID NEAR ColorInit(HWND hwnd);
- STATICFN VOID NEAR ColorProcessCommand(HWND hwnd, INT idCtrl, INT NotifyCode);
- STATICFN VOID NEAR ColorBoxPaint(HDC hdc);
- STATICFN VOID NEAR DrawColorRect(HDC hdc, DWORD rgb, INT x, INT y,
- INT cx, INT cy, HDC hdcMem, BOOL fMonoOK);
- STATICFN VOID NEAR MyRectangle(HDC hdc, INT left, INT top, INT right,
- INT bottom, HDC hdcMem, BOOL fMonoOK);
- STATICFN VOID NEAR ColorBoxClicked(UINT msg, PPOINT ppt);
- STATICFN BOOL NEAR ColorBoxHitTest(PPOINT ppt, PINT piColor, PINT pfMode);
- STATICFN VOID NEAR ColorLRPaint(HWND hwnd, HDC hdc);
- STATICFN VOID NEAR ColorLRDrawSamples(HDC hdc, PRECT prc, BOOL fLeft);
- STATICFN VOID NEAR ColorLRUpdate(BOOL fLeft);
- STATICFN VOID NEAR ColorEdit(VOID);
- STATICFN VOID NEAR SetLeftColor(INT iColor, INT iMode);
- STATICFN VOID NEAR SetRightColor(INT iColor, INT iMode);
- STATICFN HBRUSH NEAR MyCreateSolidBrush(DWORD rgb);
- STATICFN DWORD NEAR MyGetNearestColor(DWORD rgb, BOOL fMonoOK);
- STATICFN DWORD NEAR ComputeInverseColor(DWORD rgb);
- /*
- * Width/height of a single color square.
- */
- static INT gcxColorBox;
- /*
- * Vertical offset within the color box control to where to start the
- * top row of color squares (the color squares are vertically centered
- * within the color box control).
- */
- static INT gyColorBoxStart;
- /*
- * Number of colors and image type. These globals are used by the
- * the color palette routines to know what mode the color palette
- * is in.
- */
- static INT gnColorPalColors;
- static INT giColorPalType;
- /****************************************************************************
- * ColorShow
- *
- * This function shows or hides the color palette.
- *
- * History:
- *
- ****************************************************************************/
- VOID ColorShow(
- BOOL fShow)
- {
- if (fShow)
- ShowWindow(ghwndColor, SW_SHOWNA);
- else
- ShowWindow(ghwndColor, SW_HIDE);
- }
- /************************************************************************
- * ColorDlgProc
- *
- *
- *
- * Arguments:
- *
- * History:
- *
- ************************************************************************/
- DIALOGPROC ColorDlgProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- switch (msg) {
- case WM_INITDIALOG:
- ColorInit(hwnd);
- /*
- * Return TRUE so that the dialog manager does NOT set the focus
- * for me. This prevents the status window from initially having
- * the focus when the editor is started.
- */
- return TRUE;
- case WM_ACTIVATE:
- if (GET_WM_ACTIVATE_STATE(wParam, lParam))
- gidCurrentDlg = DID_COLOR;
- break;
- case WM_CTLCOLORBTN:
- case WM_CTLCOLORDLG:
- case WM_CTLCOLORSTATIC:
- switch (GET_WM_CTLCOLOR_TYPE(wParam, lParam, msg)) {
- case CTLCOLOR_BTN:
- case CTLCOLOR_DLG:
- return (BOOL)GetStockObject(LTGRAY_BRUSH);
- case CTLCOLOR_STATIC:
- SetBkColor(GET_WM_CTLCOLOR_HDC(wParam, lParam, msg),
- RGB_LIGHTGRAY);
- return (BOOL)GetStockObject(LTGRAY_BRUSH);
- }
- return (BOOL)NULL;
- case WM_PAINT:
- {
- HDC hdc;
- PAINTSTRUCT ps;
- hdc = BeginPaint(hwnd, &ps);
- DrawMarginBorder(hwnd, hdc);
- EndPaint(hwnd, &ps);
- }
- break;
- case WM_COMMAND:
- ColorProcessCommand(hwnd,
- GET_WM_COMMAND_ID(wParam, lParam),
- GET_WM_COMMAND_CMD(wParam, lParam));
- break;
- case WM_CLOSE:
- /*
- * The user closed the color palette from the system menu.
- * Hide the window (we don't actually destroy it so
- * that it will appear in the same spot when they show
- * it again).
- */
- ColorShow(FALSE);
- gfShowColor = FALSE;
- break;
- case WM_DESTROY:
- {
- RECT rc;
- /*
- * Save the position of the color palette.
- */
- GetWindowRect(hwnd, &rc);
- WriteWindowPos(&rc, FALSE, szColorPos);
- /*
- * Null out the global window handle for the color palette
- * for safety's sake.
- */
- ghwndColor = NULL;
- }
- break;
- default:
- return FALSE;
- }
- return FALSE;
- }
- /************************************************************************
- * ColorInit
- *
- *
- *
- * Arguments:
- *
- * History:
- *
- ************************************************************************/
- STATICFN VOID NEAR ColorInit(
- HWND hwnd)
- {
- RECT rc;
- /*
- * Get the dimension of a single color square, and the vertical
- * offset to where the top of the squares are.
- */
- GetWindowRect(GetDlgItem(hwnd, DID_COLORBOX), &rc);
- gcxColorBox = (rc.right - rc.left) / COLORCOLS;
- gyColorBoxStart = ((rc.right - rc.left) - (gcxColorBox * COLORCOLS)) / 2;
- }
- /************************************************************************
- * ColorProcessCommand
- *
- *
- * Arguments:
- * HWND hwnd - The window handle.
- * INT idCtrl - The id of the control the WM_COMMAND is for.
- * INT NotifyCode - The control's notification code.
- *
- * History:
- *
- ************************************************************************/
- STATICFN VOID NEAR ColorProcessCommand(
- HWND hwnd,
- INT idCtrl,
- INT NotifyCode)
- {
- switch (idCtrl) {
- case DID_COLOREDIT:
- ColorEdit();
- break;
- case DID_COLORDEFAULT:
- if (gfModeLeft == MODE_COLOR) {
- gargbColor[giColorLeft] = gargbDefaultColor[giColorLeft];
- InvalidateRect(GetDlgItem(ghwndColor, DID_COLORBOX),
- NULL, TRUE);
- SetLeftColor(giColorLeft, gfModeLeft);
- }
- break;
- }
- }
- /************************************************************************
- * ColorBoxWndProc
- *
- *
- *
- * Arguments:
- *
- * History:
- *
- ************************************************************************/
- WINDOWPROC ColorBoxWndProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- POINT pt;
- HDC hdc;
- PAINTSTRUCT ps;
- INT iColor;
- INT iMode;
- switch (msg) {
- case WM_PAINT:
- hdc = BeginPaint(hwnd, &ps);
- ColorBoxPaint(hdc);
- EndPaint(hwnd, &ps);
- break;
- case WM_LBUTTONDOWN:
- case WM_RBUTTONDOWN:
- ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
- ColorBoxClicked(msg, &pt);
- break;
- case WM_LBUTTONDBLCLK:
- ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
- if (ColorBoxHitTest(&pt, &iColor, &iMode))
- ColorEdit();
- break;
- default:
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
- return 0;
- }
- /************************************************************************
- * ColorBoxPaint
- *
- *
- *
- * Arguments:
- *
- * History:
- *
- ************************************************************************/
- STATICFN VOID NEAR ColorBoxPaint(
- HDC hdc)
- {
- HDC hdcMem;
- HBITMAP hbmMem;
- INT i;
- INT x;
- INT y;
- INT cx = gcxColorBox + 1;
- INT cy = gcxColorBox + 1;
- if (giColorPalType != FT_BITMAP) {
- x = 0;
- y = gyColorBoxStart;
- DrawColorRect(hdc, grgbScreen, x, y, cx, cy, NULL, FALSE);
- y += gcxColorBox;
- DrawColorRect(hdc, grgbInverse, x, y, cx, cy, NULL, FALSE);
- }
- if (!(hdcMem = CreateCompatibleDC(hdc)))
- return;
- /*
- * Create a bitmap. It will have the same number of colors as the
- * current image.
- */
- if (!(hbmMem = MyCreateBitmap(hdc, cx, cy, gnColorPalColors))) {
- DeleteDC(hdcMem);
- return;
- }
- SelectObject(hdcMem, hbmMem);
- x = gcxColorBox * 2;
- y = gyColorBoxStart;
- for (i = 1; i <= COLORSMAX; i++) {
- DrawColorRect(hdc, gargbCurrent[i - 1], x, y, cx, cy, hdcMem, TRUE);
- if (i % COLORROWS) {
- y += gcxColorBox;
- }
- else {
- x += gcxColorBox;
- y = gyColorBoxStart;
- }
- }
- DeleteDC(hdcMem);
- DeleteObject(hbmMem);
- }
- /************************************************************************
- * DrawColorRect
- *
- *
- *
- * Arguments:
- *
- * History:
- *
- ************************************************************************/
- STATICFN VOID NEAR DrawColorRect(
- HDC hdc,
- DWORD rgb,
- INT x,
- INT y,
- INT cx,
- INT cy,
- HDC hdcMem,
- BOOL fMonoOK)
- {
- HBRUSH hbr;
- HBRUSH hbrOld;
- hbr = CreateSolidBrush(rgb);
- hbrOld = SelectObject(hdc, hbr);
- MyRectangle(hdc, x, y, x + cx, y + cy, hdcMem, fMonoOK);
- SelectObject(hdc, hbrOld);
- DeleteObject(hbr);
- }
- /************************************************************************
- * MyRectangle
- *
- *
- *
- * Arguments:
- *
- * History:
- *
- ************************************************************************/
- STATICFN VOID NEAR MyRectangle(
- HDC hdc,
- INT left,
- INT top,
- INT right,
- INT bottom,
- HDC hdcMem,
- BOOL fMonoOK)
- {
- HBITMAP hbmMem;
- HBRUSH hbr;
- HPEN hpen;
- HBRUSH hbrOld;
- HPEN hpenOld;
- BOOL fDCCreated = FALSE;
- INT cx = right - left;
- INT cy = bottom - top;
- INT nColors;
- /*
- * Do they want us to create the memory DC and bitmap for them?
- */
- if (!hdcMem) {
- if (!(hdcMem = CreateCompatibleDC(hdc)))
- return;
- /*
- * Create a bitmap. It will be monochrome if in 2 color mode
- * and monochrome is ok, otherwise it will be 16 color.
- */
- nColors = gnColorPalColors;
- if (!fMonoOK)
- nColors = 16;
- if (!(hbmMem = MyCreateBitmap(hdc, cx, cy, nColors))) {
- DeleteDC(hdcMem);
- return;
- }
- SelectObject(hdcMem, hbmMem);
- fDCCreated = TRUE;
- }
- /*
- * Extract the current pen and brush out of the passed in DC.
- */
- hbr = SelectObject(hdc, GetStockObject(NULL_BRUSH));
- hpen = SelectObject(hdc, GetStockObject(NULL_PEN));
- /*
- * Select them into the memory DC.
- */
- hbrOld = SelectObject(hdcMem, hbr);
- hpenOld = SelectObject(hdcMem, hpen);
- /*
- * Draw the rectangle in the memory bitmap.
- */
- Rectangle(hdcMem, 0, 0, cx, cy);
- /*
- * Unselect the pen and brush from the memory DC.
- */
- SelectObject(hdcMem, hbrOld);
- SelectObject(hdcMem, hpenOld);
- /*
- * Restore the pen and brush to the original DC.
- */
- SelectObject(hdc, hbr);
- SelectObject(hdc, hpen);
- /*
- * Blit the memory image to the passed in DC.
- */
- BitBlt(hdc, left, top, cx, cy, hdcMem, 0, 0, SRCCOPY);
- if (fDCCreated) {
- DeleteDC(hdcMem);
- DeleteObject(hbmMem);
- }
- }
- /************************************************************************
- * ColorBoxClicked
- *
- *
- *
- * Arguments:
- *
- * History:
- *
- ************************************************************************/
- STATICFN VOID NEAR ColorBoxClicked(
- UINT msg,
- PPOINT ppt)
- {
- INT iColor;
- INT iMode;
- if (ColorBoxHitTest(ppt, &iColor, &iMode)) {
- switch (msg) {
- case WM_LBUTTONDOWN:
- SetLeftColor(iColor, iMode);
- break;
- case WM_RBUTTONDOWN:
- SetRightColor(iColor, iMode);
- break;
- }
- }
- }
- /************************************************************************
- * ColorBoxHitTest
- *
- *
- *
- * Arguments:
- *
- * History:
- *
- ************************************************************************/
- STATICFN BOOL NEAR ColorBoxHitTest(
- PPOINT ppt,
- PINT piColor,
- PINT pfMode)
- {
- INT iCol;
- INT iRow;
- INT iBox;
- if (ppt->y < gyColorBoxStart)
- return FALSE;
- iCol = ppt->x / gcxColorBox;
- iRow = (ppt->y - gyColorBoxStart) / gcxColorBox;
- if (iCol >= (COLORSMAX / COLORROWS) + 2 || iRow >= COLORROWS)
- return FALSE;
- iBox = iRow + (iCol * COLORROWS);
- switch (iBox) {
- case 0:
- if (giColorPalType == FT_BITMAP)
- return FALSE;
- *piColor = 0;
- *pfMode = MODE_SCREEN;
- return TRUE;
- case 1:
- if (giColorPalType == FT_BITMAP)
- return FALSE;
- *piColor = 0;
- *pfMode = MODE_INVERSE;
- return TRUE;
- case 2:
- case 3:
- return FALSE;
- default:
- *piColor = iBox - (COLORROWS * 2);
- *pfMode = MODE_COLOR;
- return TRUE;
- }
- }
- /************************************************************************
- * ColorLRWndProc
- *
- *
- *
- * Arguments:
- *
- * History:
- *
- ************************************************************************/
- WINDOWPROC ColorLRWndProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- HDC hdc;
- PAINTSTRUCT ps;
- switch (msg) {
- case WM_PAINT:
- hdc = BeginPaint(hwnd, &ps);
- ColorLRPaint(hwnd, hdc);
- EndPaint(hwnd, &ps);
- break;
- default:
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
- return 0;
- }
- /************************************************************************
- * ColorLRPaint
- *
- *
- *
- * Arguments:
- *
- * History:
- *
- ************************************************************************/
- STATICFN VOID NEAR ColorLRPaint(
- HWND hwnd,
- HDC hdc)
- {
- RECT rc;
- GetClientRect(hwnd, &rc);
- DrawSunkenRect(&rc, hdc);
- ColorLRDrawSamples(hdc, &rc, TRUE);
- ColorLRDrawSamples(hdc, &rc, FALSE);
- }
- /************************************************************************
- * ColorLRDrawSamples
- *
- * Draws the sample colors in the Color Left-Right control.
- *
- * Arguments:
- * HDC hdc - DC to draw into.
- * PRECT prc - Rectangle of color sample control. The samples will
- * be centered within this with an appropriate margin.
- * BOOL fLeft - TRUE if the left sample is to be drawn, FALSE for the right.
- *
- * History:
- *
- ************************************************************************/
- STATICFN VOID NEAR ColorLRDrawSamples(
- HDC hdc,
- PRECT prc,
- BOOL fLeft)
- {
- INT xLeftStart;
- INT xRightStart;
- INT ySolidStart;
- INT yDitherStart;
- INT cx;
- INT cy;
- HBRUSH hbrOld;
- HPEN hpenOld;
- BOOL fMonoOK;
- /*
- * The width and height of each square includes the border.
- */
- cx = ((prc->right - prc->left) - (6 * PALETTEMARGIN)) / 2;
- cy = ((prc->bottom - prc->top) - (4 * PALETTEMARGIN)) / 2;
- xLeftStart = prc->left + (PALETTEMARGIN * 2) + 1;
- xRightStart = xLeftStart + cx + (PALETTEMARGIN * 2);
- ySolidStart = prc->top + (PALETTEMARGIN * 2) + 1;
- yDitherStart = ySolidStart - 1 + cy;
- /*
- * Draw either the left or the right color sample.
- */
- if (fLeft) {
- fMonoOK = (gfModeLeft == MODE_COLOR) ? TRUE : FALSE;
- /*
- * Draw the solid color.
- */
- hbrOld = SelectObject(hdc, ghbrLeftSolid);
- hpenOld = SelectObject(hdc, GetStockObject(NULL_PEN));
- MyRectangle(hdc, xLeftStart, ySolidStart,
- xLeftStart + cx, yDitherStart + 1, NULL, fMonoOK);
- /*
- * Draw the true color (may be dithered).
- */
- SelectObject(hdc, ghbrLeft);
- MyRectangle(hdc, xLeftStart, yDitherStart,
- xLeftStart + cx, yDitherStart + cy, NULL, fMonoOK);
- }
- else {
- fMonoOK = (gfModeRight == MODE_COLOR) ? TRUE : FALSE;
- hbrOld = SelectObject(hdc, ghbrRightSolid);
- hpenOld = SelectObject(hdc, GetStockObject(NULL_PEN));
- MyRectangle(hdc, xRightStart, ySolidStart,
- xRightStart + cx, yDitherStart + 1, NULL, fMonoOK);
- SelectObject(hdc, ghbrRight);
- MyRectangle(hdc, xRightStart, yDitherStart,
- xRightStart + cx, yDitherStart + cy, NULL, fMonoOK);
- }
- /*
- * Now draw the outline rectangle.
- */
- SelectObject(hdc, GetStockObject(BLACK_PEN));
- SelectObject(hdc, GetStockObject(NULL_BRUSH));
- if (fLeft) {
- Rectangle(hdc, xLeftStart - 1, ySolidStart - 1,
- xLeftStart + cx, yDitherStart + cy);
- }
- else {
- Rectangle(hdc, xRightStart - 1, ySolidStart - 1,
- xRightStart + cx, yDitherStart + cy);
- }
- /*
- * Clean up.
- */
- SelectObject(hdc, hpenOld);
- SelectObject(hdc, hbrOld);
- }
- /************************************************************************
- * ColorLRUpdate
- *
- * Called when the left or right color has been changed. This function
- * will cause the specified color sample to be updated in the color palette.
- *
- * History:
- *
- ************************************************************************/
- STATICFN VOID NEAR ColorLRUpdate(
- BOOL fLeft)
- {
- RECT rc;
- HWND hwndLR;
- HDC hdc;
- hwndLR = GetDlgItem(ghwndColor, DID_COLORLR);
- GetClientRect(hwndLR, &rc);
- hdc = GetDC(hwndLR);
- ColorLRDrawSamples(hdc, &rc, fLeft);
- ReleaseDC(hwndLR, hdc);
- }
- /************************************************************************
- * ColorEdit
- *
- * This function calls the standard color chooser dialog to get a
- * new color for the selected palette entry.
- *
- * History:
- *
- ************************************************************************/
- STATICFN VOID NEAR ColorEdit(VOID)
- {
- /*
- * This array of custom colors is initialized to all white colors.
- * The custom colors will be remembered between calls, but not
- * between sessions.
- */
- static DWORD argbCust[16] = {
- RGB(255, 255, 255), RGB(255, 255, 255),
- RGB(255, 255, 255), RGB(255, 255, 255),
- RGB(255, 255, 255), RGB(255, 255, 255),
- RGB(255, 255, 255), RGB(255, 255, 255),
- RGB(255, 255, 255), RGB(255, 255, 255),
- RGB(255, 255, 255), RGB(255, 255, 255),
- RGB(255, 255, 255), RGB(255, 255, 255),
- RGB(255, 255, 255), RGB(255, 255, 255)
- };
- CHOOSECOLOR cc;
- DWORD rgbOld;
- BOOL fResult;
- INT idPrevDlg;
- switch (gfModeLeft) {
- case MODE_COLOR:
- /*
- * The monochrome palette cannot be edited.
- */
- if (gnColorPalColors == 2)
- return;
- rgbOld = gargbCurrent[giColorLeft];
- break;
- case MODE_SCREEN:
- rgbOld = grgbScreen;
- break;
- case MODE_INVERSE:
- rgbOld = grgbInverse;
- break;
- }
- cc.lStructSize = sizeof(CHOOSECOLOR);
- cc.hwndOwner = ghwndMain;
- cc.hInstance = ghInst;
- cc.rgbResult = rgbOld;
- cc.lpCustColors = argbCust;
- cc.Flags = CC_RGBINIT | CC_SHOWHELP;
- cc.lCustData = 0;
- cc.lpfnHook = NULL;
- cc.lpTemplateName = NULL;
- EnteringDialog(DID_COMMONFILECHOOSECOLOR, &idPrevDlg, TRUE);
- fResult = ChooseColor(&cc);
- EnteringDialog(idPrevDlg, NULL, FALSE);
- if (fResult && rgbOld != cc.rgbResult) {
- switch (gfModeLeft) {
- case MODE_COLOR:
- gargbCurrent[giColorLeft] = cc.rgbResult;
- break;
- case MODE_SCREEN:
- SetScreenColor(cc.rgbResult);
- break;
- case MODE_INVERSE:
- SetScreenColor(ComputeInverseColor(cc.rgbResult));
- break;
- }
- SetLeftColor(giColorLeft, gfModeLeft);
- InvalidateRect(GetDlgItem(ghwndColor, DID_COLORBOX), NULL, TRUE);
- }
- }
- /************************************************************************
- * SetLeftColor
- *
- *
- * History:
- *
- ************************************************************************/
- STATICFN VOID NEAR SetLeftColor(
- INT iColor,
- INT iMode)
- {
- DWORD rgbSolid;
- BOOL fEnableDefault = FALSE;
- BOOL fEnableEdit = FALSE;
- if (ghbrLeft)
- DeleteObject(ghbrLeft);
- if (ghbrLeftSolid)
- DeleteObject(ghbrLeftSolid);
- if (ghpenLeft)
- DeleteObject(ghpenLeft);
- switch (iMode) {
- case MODE_COLOR:
- ghbrLeft = MyCreateSolidBrush(gargbCurrent[iColor]);
- rgbSolid = MyGetNearestColor(gargbCurrent[iColor], TRUE);
- ghbrLeftSolid = CreateSolidBrush(rgbSolid);
- ghpenLeft = CreatePen(PS_INSIDEFRAME, 1, rgbSolid);
- giColorLeft = iColor;
- /*
- * We will enable the "Default" button if the current color
- * on the left button is not the default color, and we are
- * not in monochrome mode.
- */
- if (gargbColor[giColorLeft] != gargbDefaultColor[giColorLeft] &&
- gnColorPalColors > 2)
- fEnableDefault = TRUE;
- /*
- * For non-screen colors, the Edit button will be enabled
- * if we are not in monochrome mode.
- */
- if (gnColorPalColors > 2)
- fEnableEdit = TRUE;
- break;
- case MODE_SCREEN:
- ghbrLeft = CreateSolidBrush(grgbScreen);
- ghbrLeftSolid = CreateSolidBrush(grgbScreen);
- ghpenLeft = CreatePen(PS_INSIDEFRAME, 1, grgbScreen);
- giColorLeft = 0;
- fEnableEdit = TRUE;
- break;
- case MODE_INVERSE:
- ghbrLeft = CreateSolidBrush(grgbInverse);
- ghbrLeftSolid = CreateSolidBrush(grgbInverse);
- ghpenLeft = CreatePen(PS_INSIDEFRAME, 1, grgbInverse);
- giColorLeft = 0;
- fEnableEdit = TRUE;
- break;
- }
- EnableWindow(GetDlgItem(ghwndColor, DID_COLORDEFAULT), fEnableDefault);
- EnableWindow(GetDlgItem(ghwndColor, DID_COLOREDIT), fEnableEdit);
- gfModeLeft = iMode;
- ColorLRUpdate(TRUE);
- }
- /************************************************************************
- * SetRightColor
- *
- *
- * History:
- *
- ************************************************************************/
- STATICFN VOID NEAR SetRightColor(
- INT iColor,
- INT iMode)
- {
- DWORD rgbSolid;
- if (ghbrRight)
- DeleteObject(ghbrRight);
- if (ghbrRightSolid)
- DeleteObject(ghbrRightSolid);
- if (ghpenRight)
- DeleteObject(ghpenRight);
- switch (iMode) {
- case MODE_COLOR:
- ghbrRight = MyCreateSolidBrush(gargbCurrent[iColor]);
- rgbSolid = MyGetNearestColor(gargbCurrent[iColor], TRUE);
- ghbrRightSolid = CreateSolidBrush(rgbSolid);
- ghpenRight = CreatePen(PS_INSIDEFRAME, 1, rgbSolid);
- giColorRight = iColor;
- break;
- case MODE_SCREEN:
- ghbrRight = CreateSolidBrush(grgbScreen);
- ghbrRightSolid = CreateSolidBrush(grgbScreen);
- ghpenRight = CreatePen(PS_INSIDEFRAME, 1, grgbScreen);
- giColorRight = 0;
- break;
- case MODE_INVERSE:
- ghbrRight = CreateSolidBrush(grgbInverse);
- ghbrRightSolid = CreateSolidBrush(grgbInverse);
- ghpenRight = CreatePen(PS_INSIDEFRAME, 1, grgbInverse);
- giColorRight = 0;
- break;
- }
- gfModeRight = iMode;
- ColorLRUpdate(FALSE);
- }
- /************************************************************************
- * SetScreenColor
- *
- *
- * History:
- *
- ************************************************************************/
- VOID SetScreenColor(
- DWORD rgb)
- {
- DWORD rgbInverse;
- HDC hdcTemp;
- HBITMAP hbmOld;
- HDC hdcANDTemp;
- HBITMAP hbmANDOld;
- rgb = MyGetNearestColor(rgb, FALSE);
- /*
- * Because we are about to change the screen color, separate
- * out the XOR mask (but only for icons/cursors).
- */
- if (giColorPalType != FT_BITMAP) {
- if (gpImageCur) {
- ImageDCSeparate(ghdcImage, gcxImage, gcyImage, ghdcANDMask,
- grgbScreen);
- /*
- * Is there a pending undo buffer? If so, it must be
- * changed as well or an undo that is done after a screen
- * color change will restore the wrong colors!
- */
- if (ghbmUndo) {
- /*
- * Create some temporary DC's to use when separating
- * out the undo buffer's masks. These will be deleted
- * a little later.
- */
- hdcTemp = CreateCompatibleDC(ghdcImage);
- hbmOld = SelectObject(hdcTemp, ghbmUndo);
- hdcANDTemp = CreateCompatibleDC(ghdcANDMask);
- hbmANDOld = SelectObject(hdcANDTemp, ghbmUndoMask);
- /*
- * Separate out the undo buffer's colors, before
- * changing the screen color. It will be combined
- * later.
- */
- ImageDCSeparate(hdcTemp, gcxImage, gcyImage, hdcANDTemp,
- grgbScreen);
- }
- }
- }
- if (ghbrScreen)
- DeleteObject(ghbrScreen);
- ghbrScreen = CreateSolidBrush(rgb);
- grgbScreen = rgb;
- if (ghbrInverse)
- DeleteObject(ghbrInverse);
- rgbInverse = ComputeInverseColor(rgb);
- ghbrInverse = CreateSolidBrush(rgbInverse);
- grgbInverse = rgbInverse;
- /*
- * For icons and cursors, we might need to update a few more things.
- */
- if (giColorPalType != FT_BITMAP) {
- /*
- * Recombine the XOR and AND images now that there is a new screen
- * color. This updates the image DC with the new color properly.
- */
- if (gpImageCur) {
- ImageDCCombine(ghdcImage, gcxImage, gcyImage, ghdcANDMask);
- /*
- * Is there a pending undo buffer? If so, it has to be
- * recombined with the new screen color.
- */
- if (ghbmUndo) {
- ImageDCCombine(hdcTemp, gcxImage, gcyImage, hdcANDTemp);
- /*
- * Clean up the DC's that were allocated a little earlier.
- */
- SelectObject(hdcANDTemp, hbmANDOld);
- DeleteDC(hdcANDTemp);
- SelectObject(hdcTemp, hbmOld);
- DeleteDC(hdcTemp);
- }
- }
- /*
- * Reset the colors on the mouse buttons, just in case a screen
- * or inverse screen color was assigned to either of them.
- */
- SetLeftColor(giColorLeft, gfModeLeft);
- SetRightColor(giColorRight, gfModeRight);
- InvalidateRect(GetDlgItem(ghwndColor, DID_COLORBOX), NULL, TRUE);
- }
- ViewUpdate();
- }
- /************************************************************************
- * MyCreateSolidBrush
- *
- *
- * History:
- *
- ************************************************************************/
- STATICFN HBRUSH NEAR MyCreateSolidBrush(
- DWORD rgb)
- {
- HDC hdc;
- HDC hdcMem;
- HBRUSH hbr;
- HBRUSH hbrOld;
- HBITMAP hbmPat;
- HBITMAP hbmOld;
- /*
- * First, create a brush for the given RGB value.
- */
- hbr = CreateSolidBrush(rgb);
- /*
- * Create a temporary memory DC.
- */
- hdc = GetDC(ghwndMain);
- hdcMem = CreateCompatibleDC(hdc);
- /*
- * Create a temporary bitmap.
- */
- hbmPat = MyCreateBitmap(hdc, 8, 8, gnColorPalColors);
- ReleaseDC(ghwndMain, hdc);
- /*
- * Draw the (possibly) dithered pattern on the temporary bitmap.
- */
- hbmOld = SelectObject(hdcMem, hbmPat);
- hbrOld = SelectObject(hdcMem, hbr);
- PatBlt(hdcMem, 0, 0, 8, 8, PATCOPY);
- SelectObject(hdcMem, hbrOld);
- SelectObject(hdcMem, hbmOld);
- DeleteDC(hdcMem);
- /*
- * Delete the first brush.
- */
- DeleteObject(hbr);
- /*
- * Now create a pattern brush out of the (dithered) bitmap.
- */
- hbr = CreatePatternBrush(hbmPat);
- DeleteObject(hbmPat);
- /*
- * Return the pattern brush.
- */
- return hbr;
- }
- /************************************************************************
- * MyGetNearestColor
- *
- * This function returns the RGB value of the nearest color to the
- * specified RGB value. If fMonoOK is TRUE, it takes into account
- * the number of colors of the current image being edited. In other
- * words, it will return the nearest solid color for a device that
- * has the number of colors of the current image.
- *
- * Arguments:
- * DWORD rgb - RGB value of the color.
- * BOOL fMonoOK - TRUE if the returned color should be mapped to a
- * color in a monochrome palette, if the current image
- * is monochrome. A value of FALSE will return a
- * color mapped to the closest color in a 16 color
- * palette.
- *
- * History:
- *
- ************************************************************************/
- STATICFN DWORD NEAR MyGetNearestColor(
- DWORD rgb,
- BOOL fMonoOK)
- {
- HDC hdc;
- HDC hdcMem;
- DWORD rgbNearest;
- HBITMAP hbmMem;
- HBITMAP hbmOld;
- hdc = GetDC(ghwndMain);
- hdcMem = CreateCompatibleDC(hdc);
- hbmMem = MyCreateBitmap(hdc, 1, 1, (fMonoOK) ? gnColorPalColors : 16);
- hbmOld = SelectObject(hdcMem, hbmMem);
- rgbNearest = GetNearestColor(hdcMem, rgb);
- SelectObject(hdcMem, hbmOld);
- DeleteObject(hbmMem);
- DeleteDC(hdcMem);
- ReleaseDC(ghwndMain, hdc);
- return rgbNearest;
- }
- /************************************************************************
- * ComputeInverseColor
- *
- * Computes the inverse value of a given rgb color.
- *
- * Arguments:
- *
- * History:
- *
- ************************************************************************/
- STATICFN DWORD NEAR ComputeInverseColor(
- DWORD rgb)
- {
- HBITMAP hTempBit1;
- HBITMAP hTempBit2;
- HDC hTempDC1;
- HDC hTempDC2;
- HDC hdc;
- HANDLE hOldObj1;
- HANDLE hOldObj2;
- DWORD rgbInv;
- hdc = GetDC(ghwndMain);
- hTempDC1 = CreateCompatibleDC(hdc);
- hTempDC2 = CreateCompatibleDC(hdc);
- /* create two temporary 1x1, 16 color bitmaps */
- hTempBit1 = MyCreateBitmap(hdc, 1, 1, 16);
- hTempBit2 = MyCreateBitmap(hdc, 1, 1, 16);
- ReleaseDC(ghwndMain, hdc);
- hOldObj1 = SelectObject(hTempDC1, hTempBit1);
- hOldObj2 = SelectObject(hTempDC2, hTempBit2);
- /* method for getting inverse color : set the given pixel (rgb) on
- * one DC. Now blt it to the other DC using a SRCINVERT rop.
- * This yields a pixel of the inverse color on the destination DC
- */
- SetPixel(hTempDC1, 0, 0, rgb);
- PatBlt(hTempDC2, 0, 0, 1, 1, WHITENESS);
- BitBlt(hTempDC2, 0, 0, 1, 1, hTempDC1, 0, 0, SRCINVERT);
- rgbInv = GetPixel(hTempDC2, 0, 0);
- /* clean up ... */
- SelectObject(hTempDC1, hOldObj1);
- SelectObject(hTempDC2, hOldObj2);
- DeleteObject(hTempBit1);
- DeleteObject(hTempBit2);
- DeleteDC(hTempDC1);
- DeleteDC(hTempDC2);
- /* ...and return the inverted RGB value */
- return rgbInv;
- }
- /************************************************************************
- * SetColorPalette
- *
- *
- * History:
- *
- ************************************************************************/
- VOID SetColorPalette(
- INT nColors,
- INT iType,
- BOOL fForce)
- {
- /*
- * Quit if nothing changed (unless they are forcing it to be updated).
- */
- if (!fForce && nColors == gnColorPalColors && iType == giColorPalType)
- return;
- /*
- * Set the globals that all the color palette routines use.
- */
- gnColorPalColors = nColors;
- giColorPalType = iType;
- if (gnColorPalColors == 2)
- gargbCurrent = gargbMono;
- else
- gargbCurrent = gargbColor;
- ShowWindow(GetDlgItem(ghwndColor, DID_COLORSCREENLABEL),
- (giColorPalType == FT_BITMAP) ? SW_HIDE : SW_SHOW);
- ShowWindow(GetDlgItem(ghwndColor, DID_COLORINVERSELABEL),
- (giColorPalType == FT_BITMAP) ? SW_HIDE : SW_SHOW);
- SetLeftColor(1, MODE_COLOR);
- SetRightColor(0, MODE_COLOR);
- InvalidateRect(GetDlgItem(ghwndColor, DID_COLORBOX), NULL, TRUE);
- }
- /************************************************************************
- * RestoreDefaultColors
- *
- *
- * History:
- *
- ************************************************************************/
- VOID RestoreDefaultColors(VOID)
- {
- INT i;
- for (i = 0; i < COLORSMAX; i++)
- gargbColor[i] = gargbDefaultColor[i];
- SetColorPalette(16, giColorPalType, TRUE);
- }