602 lines
19 KiB
C++
602 lines
19 KiB
C++
|
/*****************************************************************************\
|
||
|
FILE: colorpic.cpp
|
||
|
|
||
|
DESCRIPTION:
|
||
|
This code will display a color picker UI.
|
||
|
|
||
|
??????? ?/??/1993 Created
|
||
|
BryanSt 3/23/2000 Updated and Converted to C++ (Bryan Starbuck)
|
||
|
|
||
|
Copyright (C) Microsoft Corp 1993-2000. All rights reserved.
|
||
|
\*****************************************************************************/
|
||
|
|
||
|
#include "priv.h"
|
||
|
#include "AdvAppearPg.h"
|
||
|
#include "PreviewSM.h"
|
||
|
|
||
|
#define NUM_COLORSMAX 64
|
||
|
#define NUM_COLORSPERROW 4
|
||
|
|
||
|
typedef struct {
|
||
|
LPCOLORPICK_INFO lpcpi;
|
||
|
int dxColor;
|
||
|
int dyColor;
|
||
|
int iCurColor;
|
||
|
int iNumColors;
|
||
|
BOOL capturing;
|
||
|
BOOL justdropped;
|
||
|
COLORREF Colors[NUM_COLORSMAX];
|
||
|
} MYDATA, * PMYDATA, FAR * LPMYDATA;
|
||
|
|
||
|
BOOL g_bCursorHidden;
|
||
|
|
||
|
INT_PTR CALLBACK ColorPickDlgProc(HWND hDlg, UINT message , WPARAM wParam, LPARAM lParam);
|
||
|
|
||
|
BOOL NEAR PASCAL UseColorPicker( LPCOLORPICK_INFO lpcpi )
|
||
|
{
|
||
|
CHOOSECOLOR cc;
|
||
|
extern COLORREF g_CustomColors[16];
|
||
|
|
||
|
cc.lStructSize = sizeof(cc);
|
||
|
cc.hwndOwner = lpcpi->hwndParent; // NOT lpcpi->hwndOwner
|
||
|
cc.hInstance = NULL;
|
||
|
cc.rgbResult = lpcpi->rgb;
|
||
|
cc.lpCustColors = g_CustomColors;
|
||
|
cc.Flags = CC_RGBINIT | lpcpi->flags;
|
||
|
cc.lCustData = 0L;
|
||
|
cc.lpfnHook = NULL;
|
||
|
cc.lpTemplateName = NULL;
|
||
|
|
||
|
if (ChooseColor(&cc))
|
||
|
{
|
||
|
lpcpi->rgb = cc.rgbResult;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
void NEAR PASCAL DrawColorSquare(HDC hdc, int iColor, PMYDATA pmd)
|
||
|
{
|
||
|
RECT rc;
|
||
|
COLORREF rgb;
|
||
|
HPALETTE hpalOld = NULL;
|
||
|
HBRUSH hbr;
|
||
|
|
||
|
// custom color
|
||
|
if (iColor == pmd->iNumColors)
|
||
|
{
|
||
|
rc.left = 0;
|
||
|
rc.top = 0;
|
||
|
rgb = pmd->lpcpi->rgb;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rc.left = (iColor % NUM_COLORSPERROW) * pmd->dxColor;
|
||
|
rc.top = (iColor / NUM_COLORSPERROW) * pmd->dyColor;
|
||
|
rgb = pmd->Colors[iColor];
|
||
|
}
|
||
|
rc.right = rc.left + pmd->dxColor;
|
||
|
rc.bottom = rc.top + pmd->dyColor;
|
||
|
|
||
|
// focused one
|
||
|
if (iColor == pmd->iCurColor)
|
||
|
{
|
||
|
PatBlt(hdc, rc.left, rc.top, pmd->dxColor, 3, BLACKNESS);
|
||
|
PatBlt(hdc, rc.left, rc.bottom - 3, pmd->dxColor, 3, BLACKNESS);
|
||
|
PatBlt(hdc, rc.left, rc.top + 3, 3, pmd->dyColor - 6, BLACKNESS);
|
||
|
PatBlt(hdc, rc.right - 3, rc.top + 3, 3, pmd->dyColor - 6, BLACKNESS);
|
||
|
InflateRect(&rc, -1, -1);
|
||
|
HBRUSH hBrushWhite = (HBRUSH) GetStockObject(WHITE_BRUSH);
|
||
|
if (hBrushWhite)
|
||
|
{
|
||
|
FrameRect(hdc, &rc, hBrushWhite);
|
||
|
}
|
||
|
InflateRect(&rc, -2, -2);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// clean up possible focus thing from above
|
||
|
FrameRect(hdc, &rc, GetSysColorBrush(COLOR_3DFACE));
|
||
|
|
||
|
InflateRect(&rc, -cxBorder, -cyBorder);
|
||
|
DrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
|
||
|
}
|
||
|
|
||
|
if ((pmd->lpcpi->flags & CC_SOLIDCOLOR) && !(rgb & 0xFF000000))
|
||
|
rgb = GetNearestColor(hdc, rgb);
|
||
|
|
||
|
hbr = CreateSolidBrush(rgb);
|
||
|
if (pmd->lpcpi->hpal)
|
||
|
{
|
||
|
hpalOld = SelectPalette(hdc, pmd->lpcpi->hpal, FALSE);
|
||
|
RealizePalette(hdc);
|
||
|
}
|
||
|
hbr = (HBRUSH) SelectObject(hdc, hbr);
|
||
|
PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
|
||
|
hbr = (HBRUSH) SelectObject(hdc, hbr);
|
||
|
|
||
|
if (hpalOld)
|
||
|
{
|
||
|
hpalOld = SelectPalette(hdc, hpalOld, TRUE);
|
||
|
RealizePalette(hdc);
|
||
|
}
|
||
|
|
||
|
if (hbr)
|
||
|
{
|
||
|
DeleteObject(hbr);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** set the focus to the given color.
|
||
|
**
|
||
|
** in the process, also take the focus off of the old focus color.
|
||
|
*/
|
||
|
void NEAR PASCAL FocusColor(HWND hDlg, int iNewColor, PMYDATA pmd)
|
||
|
{
|
||
|
int i;
|
||
|
HDC hdc = NULL;
|
||
|
HWND hwnd;
|
||
|
|
||
|
if (iNewColor == pmd->iCurColor)
|
||
|
return;
|
||
|
|
||
|
i = pmd->iCurColor;
|
||
|
pmd->iCurColor = iNewColor;
|
||
|
|
||
|
// unfocus the old one
|
||
|
if( i >= 0 )
|
||
|
{
|
||
|
if (i == pmd->iNumColors)
|
||
|
hwnd = GetDlgItem(hDlg, IDC_CPDLG_COLORCUST);
|
||
|
else
|
||
|
hwnd = GetDlgItem(hDlg, IDC_CPDLG_16COLORS);
|
||
|
hdc = GetDC(hwnd);
|
||
|
DrawColorSquare(hdc, i, pmd);
|
||
|
ReleaseDC(hwnd, hdc);
|
||
|
}
|
||
|
|
||
|
// focus the new one
|
||
|
if( iNewColor >= 0 )
|
||
|
{
|
||
|
if (iNewColor == pmd->iNumColors)
|
||
|
hwnd = GetDlgItem(hDlg, IDC_CPDLG_COLORCUST);
|
||
|
else
|
||
|
hwnd = GetDlgItem(hDlg, IDC_CPDLG_16COLORS);
|
||
|
hdc = GetDC(hwnd);
|
||
|
DrawColorSquare(hdc, iNewColor, pmd);
|
||
|
ReleaseDC(hwnd, hdc);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void NEAR PASCAL Color_TrackMouse(HWND hDlg, POINT pt, PMYDATA pmd)
|
||
|
{
|
||
|
HWND hwndKid;
|
||
|
int id;
|
||
|
|
||
|
hwndKid = ChildWindowFromPoint(hDlg, pt);
|
||
|
if (hwndKid == NULL || hwndKid == hDlg)
|
||
|
return;
|
||
|
|
||
|
id = GetWindowLong(hwndKid, GWL_ID);
|
||
|
switch (id)
|
||
|
{
|
||
|
case IDC_CPDLG_16COLORS:
|
||
|
MapWindowPoints(hDlg, GetDlgItem(hDlg, IDC_CPDLG_16COLORS), &pt, 1);
|
||
|
pt.x /= pmd->dxColor;
|
||
|
pt.y /= pmd->dyColor;
|
||
|
FocusColor(hDlg, pt.x + (pt.y * NUM_COLORSPERROW), pmd);
|
||
|
break;
|
||
|
|
||
|
case IDC_CPDLG_COLORCUST:
|
||
|
if (IsWindowVisible(hwndKid))
|
||
|
FocusColor(hDlg, pmd->iNumColors, pmd);
|
||
|
break;
|
||
|
|
||
|
case IDC_CPDLG_COLOROTHER:
|
||
|
FocusColor(hDlg, -1, pmd);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void NEAR PASCAL Color_DrawItem(HWND hDlg, LPDRAWITEMSTRUCT lpdis, PMYDATA pmd)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
if (lpdis->CtlID == IDC_CPDLG_COLORCUST)
|
||
|
{
|
||
|
DrawColorSquare(lpdis->hDC, pmd->iNumColors, pmd);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (i = 0; i < pmd->iNumColors; i++)
|
||
|
DrawColorSquare(lpdis->hDC, i, pmd);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** init the mini-color-picker
|
||
|
**
|
||
|
** the dialog is pretending to be a menu, so figure out where to pop
|
||
|
** it up so that it is visible all around.
|
||
|
**
|
||
|
** also because this dialog is pretty darn concerned with its look,
|
||
|
** hand-align the components in pixel units. THIS IS GROSS!
|
||
|
*/
|
||
|
void NEAR PASCAL Color_InitDialog(HWND hDlg, PMYDATA pmd)
|
||
|
{
|
||
|
RECT rcOwner;
|
||
|
RECT rc, rc2;
|
||
|
int dx, dy;
|
||
|
int x, y;
|
||
|
int i;
|
||
|
HWND hwndColors, hwnd;
|
||
|
HWND hwndEtch, hwndCust;
|
||
|
int width, widthCust, widthEtch;
|
||
|
int cyEdge = ClassicGetSystemMetrics(SM_CYEDGE);
|
||
|
HPALETTE hpal = pmd->lpcpi->hpal;
|
||
|
MONITORINFO mi;
|
||
|
TCHAR szBuf[50];
|
||
|
LONG cbBuf = ARRAYSIZE( szBuf );
|
||
|
HDC hDC;
|
||
|
SIZE size;
|
||
|
|
||
|
if (hpal == NULL)
|
||
|
hpal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
|
||
|
|
||
|
pmd->iNumColors = 0;
|
||
|
GetObject(hpal, sizeof(int), &pmd->iNumColors);
|
||
|
|
||
|
if (pmd->iNumColors > NUM_COLORSMAX)
|
||
|
pmd->iNumColors = NUM_COLORSMAX;
|
||
|
|
||
|
if (GetPaletteEntries(hpal,0, pmd->iNumColors, (LPPALETTEENTRY)pmd->Colors))
|
||
|
{
|
||
|
for (i = 0; i < pmd->iNumColors; i++)
|
||
|
{
|
||
|
pmd->Colors[i] &= 0x00FFFFFF;
|
||
|
pmd->Colors[i] |= 0x02000000;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < pmd->iNumColors; i++)
|
||
|
{
|
||
|
if ((pmd->Colors[i] & 0x00FFFFFF) == (pmd->lpcpi->rgb & 0x00FFFFFF))
|
||
|
{
|
||
|
ShowWindow(GetDlgItem(hDlg, IDC_CPDLG_COLORCUST), SW_HIDE);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
// current is either one of 16 or the custom color (== pmd->iNumColors
|
||
|
pmd->iCurColor = i;
|
||
|
|
||
|
// size the 16 colors to be square
|
||
|
hwndColors = GetDlgItem(hDlg, IDC_CPDLG_16COLORS);
|
||
|
GetClientRect(hwndColors, &rc);
|
||
|
|
||
|
// To make localization easy..
|
||
|
//
|
||
|
hwndEtch=GetDlgItem(hDlg, IDC_CPDLG_COLORETCH);
|
||
|
GetClientRect(hwndEtch, &rc2);
|
||
|
widthEtch = rc2.right-rc2.left;
|
||
|
|
||
|
hwndCust=GetDlgItem(hDlg, IDC_CPDLG_COLORCUST);
|
||
|
GetClientRect(hwndCust, &rc2);
|
||
|
widthCust = rc2.right-rc2.left;
|
||
|
|
||
|
hwnd = GetDlgItem(hDlg, IDC_CPDLG_COLOROTHER);
|
||
|
GetWindowRect(hwnd, &rc2); // we must initialize rc2 with this control.
|
||
|
|
||
|
// Make sure the button is big enough to contain its text
|
||
|
width = rc.right - rc.left;
|
||
|
if( GetDlgItemText( hDlg, IDC_CPDLG_COLOROTHER, szBuf, cbBuf ) )
|
||
|
{
|
||
|
RECT rcTemp;
|
||
|
int iRet;
|
||
|
HFONT hfont, hfontOld;
|
||
|
|
||
|
// Get the font for the button
|
||
|
hDC = GetDC( hwnd );
|
||
|
if( hDC )
|
||
|
{
|
||
|
hfont = (HFONT)SendMessage( hwnd, WM_GETFONT, 0, 0 );
|
||
|
ASSERT(hfont);
|
||
|
hfontOld = (HFONT) SelectObject( hDC, hfont );
|
||
|
|
||
|
// Get the size of the text
|
||
|
iRet = DrawTextEx( hDC, szBuf, lstrlen(szBuf), &rcTemp, DT_CALCRECT | DT_SINGLELINE, NULL );
|
||
|
ASSERT( iRet );
|
||
|
size.cx = rcTemp.right - rcTemp.left + 7; //account for the button border
|
||
|
size.cy = rcTemp.bottom - rcTemp.top;
|
||
|
|
||
|
// Adjust the button size if the text needs more space
|
||
|
if( size.cx > width )
|
||
|
{
|
||
|
rc2.right = rc2.left + size.cx;
|
||
|
rc2.bottom = rc2.top + size.cy;
|
||
|
MoveWindow( hwnd, rc2.left, rc2.top, rc2.right - rc2.left, rc2.bottom - rc2.top, FALSE );
|
||
|
}
|
||
|
SelectObject( hDC, hfontOld );
|
||
|
ReleaseDC( hwnd, hDC );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Take possible biggest width to calculate sels
|
||
|
//
|
||
|
width = (widthEtch > widthCust+(rc2.right-rc2.left)) ? widthEtch : widthCust+(rc2.right-rc2.left);
|
||
|
width = (width > rc.right-rc.left) ? width: rc.right-rc.left;
|
||
|
|
||
|
#define NUM_COLORSPERCOL (pmd->iNumColors / NUM_COLORSPERROW)
|
||
|
|
||
|
pmd->dxColor = pmd->dyColor
|
||
|
= ((rc.bottom - rc.top) / NUM_COLORSPERCOL > width / NUM_COLORSPERROW )
|
||
|
? (rc.bottom - rc.top) / NUM_COLORSPERCOL : width / NUM_COLORSPERROW;
|
||
|
|
||
|
// Make sure custum color can fit
|
||
|
//
|
||
|
if (pmd->dxColor*(NUM_COLORSPERROW-1) < rc2.right-rc2.left )
|
||
|
pmd->dxColor = pmd->dyColor = (rc2.right-rc2.left)/(NUM_COLORSPERROW-1);
|
||
|
|
||
|
// make each color square's width the same as the height
|
||
|
SetWindowPos(hwndColors, NULL, 0, 0, pmd->dxColor * NUM_COLORSPERROW,
|
||
|
pmd->dyColor * NUM_COLORSPERCOL,
|
||
|
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW);
|
||
|
rc.right = rc.left + pmd->dxColor * NUM_COLORSPERROW;
|
||
|
rc.bottom = rc.top + pmd->dyColor * NUM_COLORSPERCOL;
|
||
|
|
||
|
MapWindowPoints(hwndColors, hDlg, (LPPOINT)(LPRECT)&rc, 2);
|
||
|
|
||
|
// move/size the etch to the right place
|
||
|
// (compensate for the colors being "inset" by one)
|
||
|
MoveWindow(hwndEtch, rc.left + 1, rc.bottom + cyEdge,
|
||
|
rc.right - rc.left - 2, cyEdge, FALSE);
|
||
|
|
||
|
y = rc.bottom + 3 * cyEdge;
|
||
|
|
||
|
// size the custom color to the same square and right-align
|
||
|
MoveWindow(hwndCust, rc.right - pmd->dxColor, y,
|
||
|
pmd->dxColor, pmd->dyColor, FALSE);
|
||
|
|
||
|
// do same for button
|
||
|
MapWindowPoints(NULL, hDlg, (LPPOINT)(LPRECT)&rc2, 2);
|
||
|
// base the width of the custom button on the remaining space to
|
||
|
// the left of the custom color. Also move the custom button one pix right
|
||
|
// of the left edge. This only is done if a custom color is selected...
|
||
|
if (pmd->iCurColor != pmd->iNumColors) {
|
||
|
// no custom color
|
||
|
MoveWindow(hwnd, rc2.left, y, rc2.right-rc2.left, pmd->dyColor, FALSE);
|
||
|
}
|
||
|
else {
|
||
|
// custom color, adjust the Other... button
|
||
|
dx = rc2.right - rc2.left++;
|
||
|
if (rc2.left + dx >= rc.right - pmd->dxColor - 2)
|
||
|
MoveWindow(hwnd, rc2.left, y, rc.right - pmd->dxColor - 2 , pmd->dyColor, FALSE);
|
||
|
else
|
||
|
MoveWindow(hwnd, rc2.left, y, dx, pmd->dyColor, FALSE);
|
||
|
}
|
||
|
|
||
|
// now figure out the size for the dialog itself
|
||
|
rc.left = rc.top = 0;
|
||
|
rc.right = rc.left + pmd->dxColor * NUM_COLORSPERROW;
|
||
|
// (compensate for the colors being "inset" by one)
|
||
|
rc.bottom = y + pmd->dyColor + 1;
|
||
|
|
||
|
AdjustWindowRect(&rc, GetWindowLong(hDlg, GWL_STYLE), FALSE);
|
||
|
dx = rc.right - rc.left;
|
||
|
dy = rc.bottom - rc.top;
|
||
|
|
||
|
GetWindowRect(pmd->lpcpi->hwndOwner, &rcOwner);
|
||
|
|
||
|
// Make sure the window is entirely on the monitor
|
||
|
mi.cbSize = sizeof(mi);
|
||
|
GetMonitorInfo(MonitorFromRect(&rcOwner, MONITOR_DEFAULTTONEAREST), &mi);
|
||
|
|
||
|
if (rcOwner.left < mi.rcMonitor.left) { // overlap left side
|
||
|
x = mi.rcMonitor.left;
|
||
|
}
|
||
|
else if (rcOwner.left + dx >= mi.rcMonitor.right) { // overlap right side
|
||
|
x = mi.rcMonitor.right - dx - 1;
|
||
|
}
|
||
|
else { // no overlap
|
||
|
x = rcOwner.left;
|
||
|
}
|
||
|
|
||
|
if (rcOwner.top < mi.rcMonitor.top) { // overlap top side
|
||
|
y = rcOwner.bottom;
|
||
|
}
|
||
|
else if (rcOwner.bottom + dy >= mi.rcMonitor.bottom) {// overlap bottom side
|
||
|
y = rcOwner.top - dy;
|
||
|
}
|
||
|
else { // no overlap
|
||
|
y = rcOwner.bottom;
|
||
|
}
|
||
|
MoveWindow(hDlg, x, y, dx, dy, FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INT_PTR CALLBACK ColorPickDlgProc(HWND hDlg, UINT message , WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
PMYDATA pmd = (PMYDATA)GetWindowLongPtr(hDlg, DWLP_USER);
|
||
|
HWND hwndKid;
|
||
|
int wRet;
|
||
|
int id;
|
||
|
POINT pt;
|
||
|
BOOL fEnd = FALSE;
|
||
|
|
||
|
if (!pmd && (WM_INITDIALOG != message))
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
switch(message)
|
||
|
{
|
||
|
case WM_INITDIALOG:
|
||
|
pmd = (PMYDATA)LocalAlloc(LPTR, sizeof(MYDATA));
|
||
|
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pmd);
|
||
|
if (pmd)
|
||
|
{
|
||
|
pmd->lpcpi = (LPCOLORPICK_INFO)lParam;
|
||
|
pmd->capturing = FALSE;
|
||
|
pmd->justdropped = TRUE;
|
||
|
|
||
|
Color_InitDialog(hDlg, pmd);
|
||
|
SetFocus(GetDlgItem(hDlg, IDC_CPDLG_16COLORS));
|
||
|
|
||
|
// post self a message to setcapture after painting
|
||
|
PostMessage(hDlg, WM_APP+1, 0, 0L);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
EndDialog(hDlg, IDCANCEL);
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
|
||
|
case WM_APP+1:
|
||
|
if (g_bCursorHidden)
|
||
|
{
|
||
|
ShowCursor(TRUE);
|
||
|
g_bCursorHidden = FALSE;
|
||
|
}
|
||
|
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||
|
pmd->capturing = TRUE;
|
||
|
SetCapture(hDlg);
|
||
|
pmd->capturing = FALSE;
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
LocalFree((HLOCAL)pmd);
|
||
|
break;
|
||
|
|
||
|
case WM_CAPTURECHANGED:
|
||
|
if( pmd->capturing )
|
||
|
return TRUE; // ignore if we're doing this on purpose
|
||
|
|
||
|
// if this wasn't a button in the dialog, dismiss ourselves
|
||
|
if( !pmd->justdropped || (HWND)lParam == NULL || GetParent((HWND)lParam) != hDlg)
|
||
|
{
|
||
|
EndDialog(hDlg, IDCANCEL);
|
||
|
return TRUE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_MOUSEMOVE:
|
||
|
LPARAM2POINT(lParam, &pt );
|
||
|
|
||
|
Color_TrackMouse(hDlg, pt, pmd);
|
||
|
break;
|
||
|
|
||
|
// if button up is on the parent, leave picker up and untrammeled.
|
||
|
// otherwise, we must have "menu-tracked" to get here, so select.
|
||
|
case WM_LBUTTONUP:
|
||
|
case WM_RBUTTONUP:
|
||
|
LPARAM2POINT(lParam, &pt);
|
||
|
MapWindowPoints(hDlg, pmd->lpcpi->hwndOwner, &pt, 1);
|
||
|
if (ChildWindowFromPoint(pmd->lpcpi->hwndOwner, pt))
|
||
|
return 0;
|
||
|
pmd->capturing = TRUE;
|
||
|
pmd->justdropped = FALSE; // user could not be dragging from owner
|
||
|
ReleaseCapture();
|
||
|
pmd->capturing = FALSE;
|
||
|
fEnd = TRUE;
|
||
|
// || fall ||
|
||
|
// || through ||
|
||
|
// \/ \/
|
||
|
case WM_LBUTTONDOWN:
|
||
|
case WM_RBUTTONDOWN:
|
||
|
LPARAM2POINT(lParam, &pt);
|
||
|
hwndKid = ChildWindowFromPoint(hDlg, pt);
|
||
|
// assume it's a dismissal if we're going to close...
|
||
|
wRet = IDCANCEL;
|
||
|
|
||
|
// if not on parent, dismiss picker
|
||
|
if (hwndKid != NULL && hwndKid != hDlg)
|
||
|
{
|
||
|
id = GetWindowLong(hwndKid, GWL_ID);
|
||
|
switch (id)
|
||
|
{
|
||
|
case IDC_CPDLG_16COLORS:
|
||
|
// make sure that iCurColor is valid
|
||
|
Color_TrackMouse(hDlg, pt, pmd);
|
||
|
pmd->lpcpi->rgb = pmd->Colors[pmd->iCurColor] & 0x00FFFFFF;
|
||
|
|
||
|
//BOGUS
|
||
|
//if (pmd->iCurColor >= 16)
|
||
|
// pmd->lpcpi->rgb |= 0x02000000;
|
||
|
|
||
|
wRet = IDOK;
|
||
|
break;
|
||
|
|
||
|
case IDC_CPDLG_COLOROTHER:
|
||
|
FocusColor(hDlg, -1, pmd);
|
||
|
wRet = id; // this will fall thru to use the picker
|
||
|
fEnd = TRUE; // we have capture, the button won't click
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
// if this is a down, we will track until the up
|
||
|
// if this is an up, we will close with no change
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( fEnd )
|
||
|
{
|
||
|
EndDialog(hDlg, wRet);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
// make sure we have the capture again since we didn't close
|
||
|
pmd->capturing = TRUE;
|
||
|
SetCapture(hDlg);
|
||
|
pmd->capturing = FALSE;
|
||
|
break;
|
||
|
|
||
|
case WM_DRAWITEM:
|
||
|
Color_DrawItem(hDlg, (LPDRAWITEMSTRUCT)lParam, pmd);
|
||
|
break;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
// all commands close the dialog
|
||
|
// note IDC_CPDLG_COLOROTHER will fall through to the caller...
|
||
|
// cannot pass ok with no color selected
|
||
|
if( LOWORD(wParam) == IDOK && pmd->iCurColor < 0 )
|
||
|
*((WORD *)(&wParam)) = IDCANCEL;
|
||
|
|
||
|
EndDialog( hDlg, LOWORD(wParam) );
|
||
|
break;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL WINAPI ChooseColorMini(LPCOLORPICK_INFO lpcpi)
|
||
|
{
|
||
|
INT_PTR iAnswer;
|
||
|
|
||
|
ShowCursor(FALSE);
|
||
|
g_bCursorHidden = TRUE;
|
||
|
|
||
|
iAnswer = DialogBoxParam(HINST_THISDLL, MAKEINTRESOURCE(DLG_COLORPICK),
|
||
|
lpcpi->hwndOwner, ColorPickDlgProc, (LPARAM)lpcpi);
|
||
|
|
||
|
if (g_bCursorHidden)
|
||
|
{
|
||
|
ShowCursor(TRUE);
|
||
|
g_bCursorHidden = FALSE;
|
||
|
}
|
||
|
|
||
|
switch( iAnswer )
|
||
|
{
|
||
|
case IDC_CPDLG_COLOROTHER: // the user picked the "Other..." button
|
||
|
return UseColorPicker( lpcpi );
|
||
|
|
||
|
case IDOK: // the user picked a color in our little window
|
||
|
return TRUE;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|