541 lines
12 KiB
C++
541 lines
12 KiB
C++
//
|
||
// CGRP.CPP
|
||
// Color Group
|
||
//
|
||
// Copyright Microsoft 1998-
|
||
//
|
||
|
||
// PRECOMP
|
||
#include "precomp.h"
|
||
|
||
|
||
static const TCHAR szCGClassName[] = "WB_CGRP";
|
||
|
||
// These default colors are the same as MSPaint
|
||
COLORREF g_crDefaultColors[NUMCLRPANES] =
|
||
{
|
||
PALETTERGB( 0, 0, 0 ),
|
||
PALETTERGB( 128,128,128 ),
|
||
PALETTERGB( 128, 0, 0 ),
|
||
PALETTERGB( 128,128, 0 ),
|
||
PALETTERGB( 0,128, 0 ),
|
||
PALETTERGB( 0,128,128 ),
|
||
PALETTERGB( 0, 0,128 ),
|
||
PALETTERGB( 128, 0,128 ),
|
||
PALETTERGB( 128,128, 64 ),
|
||
PALETTERGB( 0, 64, 64 ),
|
||
PALETTERGB( 0,128,255 ),
|
||
PALETTERGB( 0, 64,128 ),
|
||
PALETTERGB( 64, 0,255 ),
|
||
PALETTERGB( 128, 64, 0 ),
|
||
|
||
PALETTERGB( 255,255,255 ),
|
||
PALETTERGB( 192,192,192 ),
|
||
PALETTERGB( 255, 0, 0 ),
|
||
PALETTERGB( 255,255, 0 ),
|
||
PALETTERGB( 0,255, 0 ),
|
||
PALETTERGB( 0,255,255 ),
|
||
PALETTERGB( 0, 0,255 ),
|
||
PALETTERGB( 255, 0,255 ),
|
||
PALETTERGB( 255,255,128 ),
|
||
PALETTERGB( 0,255,128 ),
|
||
PALETTERGB( 128,255,255 ),
|
||
PALETTERGB( 128,128,255 ),
|
||
PALETTERGB( 255, 0,128 ),
|
||
PALETTERGB( 255,128, 64 ),
|
||
|
||
PALETTERGB( 0, 0, 0 ) // Current color
|
||
};
|
||
|
||
|
||
|
||
//
|
||
// WbColorsGroup()
|
||
//
|
||
WbColorsGroup::WbColorsGroup()
|
||
{
|
||
int i;
|
||
|
||
m_hwnd = NULL;
|
||
|
||
for (i = 0; i < NUMCLRPANES; i++)
|
||
{
|
||
m_crColors[i] = g_crDefaultColors[i];
|
||
m_hBrushes[i] = NULL;
|
||
}
|
||
|
||
|
||
for (i = 0; i < NUMCUSTCOLORS; i++)
|
||
{
|
||
m_crCustomColors[i] = CLRPANE_WHITE;
|
||
}
|
||
|
||
m_nLastColor = 0;
|
||
}
|
||
|
||
|
||
|
||
WbColorsGroup::~WbColorsGroup(void)
|
||
{
|
||
int i;
|
||
|
||
// clean up
|
||
for (i = 0; i < NUMCLRPANES; i++)
|
||
{
|
||
if (m_hBrushes[i] != NULL)
|
||
{
|
||
::DeleteBrush(m_hBrushes[i]);
|
||
m_hBrushes[i] = NULL;
|
||
}
|
||
}
|
||
|
||
if (m_hwnd != NULL)
|
||
{
|
||
::DestroyWindow(m_hwnd);
|
||
ASSERT(m_hwnd == NULL);
|
||
}
|
||
|
||
// Unregister our class
|
||
::UnregisterClass(szCGClassName, g_hInstance);
|
||
}
|
||
|
||
|
||
|
||
BOOL WbColorsGroup::Create(HWND hwndParent, LPCRECT lprect)
|
||
{
|
||
int i;
|
||
HDC hdc;
|
||
HPALETTE hPal;
|
||
HPALETTE hOldPal = NULL;
|
||
WNDCLASSEX wc;
|
||
|
||
ASSERT(m_hwnd == NULL);
|
||
|
||
// Register our class
|
||
ZeroMemory(&wc, sizeof(wc));
|
||
wc.cbSize = sizeof(wc);
|
||
wc.style = CS_DBLCLKS;
|
||
wc.lpfnWndProc = CGWndProc;
|
||
wc.hInstance = g_hInstance;
|
||
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
|
||
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
|
||
wc.lpszClassName = szCGClassName;
|
||
|
||
if (!::RegisterClassEx(&wc))
|
||
{
|
||
ERROR_OUT(("WbColorsGroup::Create register class failed"));
|
||
return(FALSE);
|
||
}
|
||
|
||
//
|
||
// We should be created the right siez
|
||
//
|
||
ASSERT(lprect->right - lprect->left == CLRCHOICE_WIDTH + NUMCOLS*CLRPANE_WIDTH);
|
||
ASSERT(lprect->bottom - lprect->top == CLRCHOICE_HEIGHT);
|
||
|
||
//
|
||
// Calculate our item colors, then figure out our size.
|
||
//
|
||
|
||
hdc = ::GetDC(hwndParent);
|
||
hPal = PG_GetPalette();
|
||
if (hPal != NULL)
|
||
{
|
||
hOldPal = ::SelectPalette(hdc, hPal, FALSE);
|
||
::RealizePalette(hdc);
|
||
}
|
||
|
||
// load the colors from last time
|
||
OPT_GetDataOption(OPT_MAIN_COLORPALETTE,
|
||
sizeof m_crColors,
|
||
(BYTE *)m_crColors );
|
||
|
||
OPT_GetDataOption(OPT_MAIN_CUSTOMCOLORS,
|
||
sizeof m_crCustomColors,
|
||
(BYTE *)m_crCustomColors );
|
||
|
||
// make brushes.
|
||
for (i = 0; i < NUMCLRPANES; i++)
|
||
{
|
||
// force color matching
|
||
m_crColors[i] = SET_PALETTERGB( m_crColors[i] );
|
||
m_hBrushes[i] = ::CreateSolidBrush(m_crColors[i]);
|
||
}
|
||
|
||
for (i = 0; i < NUMCUSTCOLORS; i++)
|
||
{
|
||
// force color matching
|
||
m_crCustomColors[i] = SET_PALETTERGB( m_crCustomColors[i] );
|
||
}
|
||
|
||
if (hOldPal != NULL)
|
||
{
|
||
::SelectPalette(hdc, hOldPal, TRUE);
|
||
}
|
||
::ReleaseDC(hwndParent, hdc);
|
||
|
||
//
|
||
// Here's our layout:
|
||
// * The colors window is CHOICEFRAME_HEIGHT pixels high
|
||
// * The current choice is a rect of CHOICEFRAME_WIDTH by
|
||
// CHOICEFRAME_HEIGHT pixels, on the left side. This includes
|
||
// a sunken EDGE.
|
||
// * There is no gap horizontally or vertically among panes.
|
||
|
||
//
|
||
// Create our window -- we're always visible. The attribute group
|
||
// shows/hides colors by showing/hiding itself.
|
||
//
|
||
if (!::CreateWindowEx(0, szCGClassName, NULL, WS_CHILD | WS_VISIBLE,
|
||
lprect->left, lprect->top,
|
||
lprect->right - lprect->left,
|
||
lprect->bottom - lprect->top,
|
||
hwndParent, NULL, g_hInstance, this))
|
||
{
|
||
ERROR_OUT(("Can't create WbColorsGroup"));
|
||
return(FALSE);
|
||
}
|
||
|
||
ASSERT(m_hwnd != NULL);
|
||
return(TRUE);
|
||
}
|
||
|
||
|
||
LRESULT CALLBACK CGWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
LRESULT lResult = 0;
|
||
WbColorsGroup * pcg;
|
||
|
||
pcg = (WbColorsGroup *)::GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||
|
||
switch (message)
|
||
{
|
||
case WM_NCCREATE:
|
||
pcg = (WbColorsGroup *)(((LPCREATESTRUCT)lParam)->lpCreateParams);
|
||
ASSERT(pcg);
|
||
|
||
pcg->m_hwnd = hwnd;
|
||
::SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pcg);
|
||
goto DefWndProc;
|
||
break;
|
||
|
||
case WM_NCDESTROY:
|
||
ASSERT(pcg);
|
||
pcg->m_hwnd = NULL;
|
||
break;
|
||
|
||
case WM_PAINT:
|
||
ASSERT(pcg);
|
||
pcg->OnPaint();
|
||
break;
|
||
|
||
case WM_LBUTTONDOWN:
|
||
pcg->OnLButtonDown((UINT)wParam, LOWORD(lParam), HIWORD(lParam));
|
||
break;
|
||
|
||
case WM_LBUTTONDBLCLK:
|
||
pcg->OnLButtonDblClk((UINT)wParam, LOWORD(lParam), HIWORD(lParam));
|
||
break;
|
||
|
||
default:
|
||
DefWndProc:
|
||
lResult = DefWindowProc(hwnd, message, wParam, lParam);
|
||
break;
|
||
}
|
||
|
||
return(lResult);
|
||
}
|
||
|
||
|
||
|
||
void WbColorsGroup::GetNaturalSize(LPSIZE lpsize)
|
||
{
|
||
lpsize->cx = CLRCHOICE_WIDTH + NUMCOLS*CLRPANE_WIDTH;
|
||
lpsize->cy = CLRCHOICE_HEIGHT;
|
||
}
|
||
|
||
|
||
|
||
COLORREF WbColorsGroup::GetCurColor(void)
|
||
{
|
||
return(GetColorOfBrush(INDEX_CHOICE));
|
||
}
|
||
|
||
|
||
|
||
void WbColorsGroup::SetCurColor(COLORREF clr)
|
||
{
|
||
SetColorOfPane(INDEX_CHOICE, clr);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//
|
||
// OnPaint()
|
||
//
|
||
// MFC message handler for WM_PAINT
|
||
//
|
||
void WbColorsGroup::OnPaint(void)
|
||
{
|
||
PAINTSTRUCT ps;
|
||
RECT rc;
|
||
RECT rcClient;
|
||
int dx, dy;
|
||
int i;
|
||
HPALETTE hPal;
|
||
HPALETTE hOldPal = NULL;
|
||
|
||
::BeginPaint(m_hwnd, &ps);
|
||
|
||
hPal = PG_GetPalette();
|
||
if (hPal != NULL)
|
||
{
|
||
hOldPal = ::SelectPalette(ps.hdc, hPal, FALSE);
|
||
::RealizePalette(ps.hdc);
|
||
}
|
||
|
||
dx = ::GetSystemMetrics(SM_CXEDGE);
|
||
dy = ::GetSystemMetrics(SM_CYEDGE);
|
||
::GetClientRect(m_hwnd, &rcClient);
|
||
|
||
// Draw the current choice
|
||
rc = rcClient;
|
||
rc.right = rc.left + CLRCHOICE_WIDTH;
|
||
::DrawEdge(ps.hdc, &rc, EDGE_SUNKEN, BF_ADJUST | BF_RECT);
|
||
::FillRect(ps.hdc, &rc, m_hBrushes[INDEX_CHOICE]);
|
||
|
||
// Draw the colors
|
||
rcClient.left += CLRCHOICE_WIDTH;
|
||
|
||
rc = rcClient;
|
||
rc.right = rc.left + CLRPANE_WIDTH;
|
||
rc.bottom = rc.top + CLRPANE_HEIGHT;
|
||
|
||
for (i = 0; i < NUMCLRPANES; i++)
|
||
{
|
||
::DrawEdge(ps.hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
|
||
::FillRect(ps.hdc, &rc, m_hBrushes[i]);
|
||
::InflateRect(&rc, dx, dy);
|
||
|
||
if (i == NUMCOLS - 1)
|
||
{
|
||
::OffsetRect(&rc, - (NUMCOLS-1)*CLRPANE_WIDTH, CLRPANE_HEIGHT);
|
||
}
|
||
else
|
||
{
|
||
::OffsetRect(&rc, CLRPANE_WIDTH, 0);
|
||
}
|
||
|
||
}
|
||
|
||
if (hOldPal != NULL)
|
||
{
|
||
::SelectPalette(ps.hdc, hOldPal, TRUE);
|
||
}
|
||
|
||
::EndPaint(m_hwnd, &ps);
|
||
|
||
}
|
||
|
||
//
|
||
// OnLButtonDown()
|
||
//
|
||
void WbColorsGroup::OnLButtonDown(UINT nFlags, int x, int y)
|
||
{
|
||
//
|
||
// If this is the current choice, do nothing. Otherwise, change the
|
||
// current color.
|
||
//
|
||
if (x >= CLRCHOICE_WIDTH)
|
||
{
|
||
int pane;
|
||
|
||
pane = 0;
|
||
if (y >= CLRPANE_HEIGHT)
|
||
pane += NUMCOLS;
|
||
pane += (x - CLRCHOICE_WIDTH) / CLRPANE_WIDTH;
|
||
|
||
// Set the current color
|
||
SetColorOfPane(INDEX_CHOICE, GetColorOfBrush(pane));
|
||
m_nLastColor = pane;
|
||
|
||
// tell Whiteboard about it.
|
||
ClickOwner();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// OnLButtonDblClk()
|
||
//
|
||
void WbColorsGroup::OnLButtonDblClk(UINT nFlags, int x, int y)
|
||
// Invoke color dialog to edit this color
|
||
{
|
||
if (x >= CLRCHOICE_WIDTH)
|
||
{
|
||
int pane;
|
||
|
||
pane = 0;
|
||
if (y >= CLRPANE_HEIGHT)
|
||
pane += NUMCOLS;
|
||
pane += (x - CLRCHOICE_WIDTH) / CLRPANE_WIDTH;
|
||
|
||
DoColorDialog(pane);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
// Returns COLORREF of Brushes[] or BLACK if no brush
|
||
COLORREF WbColorsGroup::GetColorOfBrush( int nColor )
|
||
{
|
||
ASSERT(nColor >= 0);
|
||
ASSERT(nColor < NUMCLRPANES);
|
||
|
||
if (m_hBrushes[nColor] != NULL)
|
||
{
|
||
return(m_crColors[nColor]);
|
||
}
|
||
else
|
||
{
|
||
return(CLRPANE_BLACK);
|
||
}
|
||
}
|
||
|
||
|
||
// Recreates the nColor-th brush, using the new color
|
||
void WbColorsGroup::SetColorOfBrush( int nColor, COLORREF crNewColor )
|
||
{
|
||
HBRUSH hNewBrush;
|
||
|
||
// force color matching
|
||
crNewColor = SET_PALETTERGB( crNewColor );
|
||
|
||
// check if we need to do anything
|
||
if ((nColor > -1) && (crNewColor != GetColorOfBrush(nColor)))
|
||
{
|
||
// new color is different from old color, make a new brush
|
||
|
||
hNewBrush = ::CreateSolidBrush(crNewColor);
|
||
if (hNewBrush != NULL)
|
||
{
|
||
// We managed to create the new brush. Delete the old one
|
||
if (m_hBrushes[nColor] != NULL)
|
||
{
|
||
::DeleteBrush(m_hBrushes[nColor]);
|
||
}
|
||
|
||
m_hBrushes[nColor] = hNewBrush;
|
||
m_crColors[nColor] = crNewColor;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// SetColorOfPane()
|
||
//
|
||
// Replaces brush associated with nPaneId.
|
||
//
|
||
void WbColorsGroup::SetColorOfPane(int pane, COLORREF crNewColor )
|
||
{
|
||
RECT rcClient;
|
||
|
||
// make a new brush
|
||
SetColorOfBrush(pane, crNewColor);
|
||
|
||
// update pane
|
||
::GetClientRect(m_hwnd, &rcClient);
|
||
if (pane == INDEX_CHOICE)
|
||
{
|
||
rcClient.right = rcClient.left + CLRCHOICE_WIDTH;
|
||
}
|
||
else
|
||
{
|
||
rcClient.left += CLRCHOICE_WIDTH;
|
||
|
||
rcClient.top += (pane / NUMCOLS) * CLRPANE_HEIGHT;
|
||
rcClient.bottom = rcClient.top + CLRPANE_HEIGHT;
|
||
rcClient.left += (pane % NUMCOLS) * CLRPANE_WIDTH;
|
||
rcClient.right = rcClient.left + CLRPANE_WIDTH;
|
||
}
|
||
::InvalidateRect(m_hwnd, &rcClient, FALSE);
|
||
}
|
||
|
||
|
||
|
||
|
||
void WbColorsGroup::SaveSettings( void )
|
||
// Saves stuff in registry because we're shutting down
|
||
{
|
||
// load the colors from last time
|
||
OPT_SetDataOption(OPT_MAIN_COLORPALETTE,
|
||
sizeof m_crColors,
|
||
(BYTE *)m_crColors );
|
||
|
||
OPT_SetDataOption(OPT_MAIN_CUSTOMCOLORS,
|
||
sizeof m_crCustomColors,
|
||
(BYTE *)m_crCustomColors );
|
||
|
||
}
|
||
|
||
|
||
|
||
void WbColorsGroup::OnEditColors( void )
|
||
{
|
||
DoColorDialog( m_nLastColor );
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// DoColorDialog()
|
||
// Put up ComDlg color picker to edit the pane's color value
|
||
//
|
||
COLORREF WbColorsGroup::DoColorDialog( int nColor )
|
||
{
|
||
CHOOSECOLOR cc;
|
||
|
||
memset(&cc, 0, sizeof(cc));
|
||
cc.lStructSize = sizeof(cc);
|
||
cc.lpCustColors = m_crCustomColors;
|
||
cc.Flags = CC_RGBINIT;
|
||
cc.rgbResult = GetColorOfBrush(nColor);
|
||
cc.hwndOwner = m_hwnd;
|
||
|
||
::ChooseColor(&cc);
|
||
|
||
// force color matching
|
||
cc.rgbResult = SET_PALETTERGB(cc.rgbResult);
|
||
|
||
// use the new color
|
||
SetColorOfPane(nColor, cc.rgbResult );
|
||
|
||
// set choice pane
|
||
SetColorOfPane(INDEX_CHOICE, cc.rgbResult );
|
||
m_nLastColor = nColor;
|
||
|
||
// tell Whiteboard about it.
|
||
ClickOwner();
|
||
|
||
return(cc.rgbResult );
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
void WbColorsGroup::ClickOwner( void )
|
||
{
|
||
::PostMessage(g_pMain->m_hwnd, WM_COMMAND,
|
||
(WPARAM)MAKELONG( IDM_COLOR, BN_CLICKED ),
|
||
(LPARAM)m_hwnd);
|
||
}
|
||
|
||
|
||
|