229 lines
5.7 KiB
C
229 lines
5.7 KiB
C
/*
|
|
* Process Hacker -
|
|
* color picker
|
|
*
|
|
* Copyright (C) 2010 wj32
|
|
*
|
|
* This file is part of Process Hacker.
|
|
*
|
|
* Process Hacker is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Process Hacker is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <ph.h>
|
|
#include <guisup.h>
|
|
#include <colorbox.h>
|
|
#include <commdlg.h>
|
|
|
|
typedef struct _PHP_COLORBOX_CONTEXT
|
|
{
|
|
COLORREF SelectedColor;
|
|
BOOLEAN Hot;
|
|
BOOLEAN HasFocus;
|
|
} PHP_COLORBOX_CONTEXT, *PPHP_COLORBOX_CONTEXT;
|
|
|
|
LRESULT CALLBACK PhpColorBoxWndProc(
|
|
_In_ HWND hwnd,
|
|
_In_ UINT uMsg,
|
|
_In_ WPARAM wParam,
|
|
_In_ LPARAM lParam
|
|
);
|
|
|
|
BOOLEAN PhColorBoxInitialization(
|
|
VOID
|
|
)
|
|
{
|
|
WNDCLASSEX c = { sizeof(c) };
|
|
|
|
c.style = CS_GLOBALCLASS;
|
|
c.lpfnWndProc = PhpColorBoxWndProc;
|
|
c.cbClsExtra = 0;
|
|
c.cbWndExtra = sizeof(PVOID);
|
|
c.hInstance = PhLibImageBase;
|
|
c.hIcon = NULL;
|
|
c.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
c.hbrBackground = NULL;
|
|
c.lpszMenuName = NULL;
|
|
c.lpszClassName = PH_COLORBOX_CLASSNAME;
|
|
c.hIconSm = NULL;
|
|
|
|
if (!RegisterClassEx(&c))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID PhpCreateColorBoxContext(
|
|
_Out_ PPHP_COLORBOX_CONTEXT *Context
|
|
)
|
|
{
|
|
PPHP_COLORBOX_CONTEXT context;
|
|
|
|
context = PhAllocate(sizeof(PHP_COLORBOX_CONTEXT));
|
|
memset(context, 0, sizeof(PHP_COLORBOX_CONTEXT));
|
|
*Context = context;
|
|
}
|
|
|
|
VOID PhpFreeColorBoxContext(
|
|
_In_ _Post_invalid_ PPHP_COLORBOX_CONTEXT Context
|
|
)
|
|
{
|
|
PhFree(Context);
|
|
}
|
|
|
|
VOID PhpChooseColor(
|
|
_In_ HWND hwnd,
|
|
_In_ PPHP_COLORBOX_CONTEXT Context
|
|
)
|
|
{
|
|
CHOOSECOLOR chooseColor = { sizeof(chooseColor) };
|
|
COLORREF customColors[16] = { 0 };
|
|
|
|
chooseColor.hwndOwner = hwnd;
|
|
chooseColor.rgbResult = Context->SelectedColor;
|
|
chooseColor.lpCustColors = customColors;
|
|
chooseColor.Flags = CC_ANYCOLOR | CC_FULLOPEN | CC_RGBINIT;
|
|
|
|
if (ChooseColor(&chooseColor))
|
|
{
|
|
Context->SelectedColor = chooseColor.rgbResult;
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
}
|
|
|
|
LRESULT CALLBACK PhpColorBoxWndProc(
|
|
_In_ HWND hwnd,
|
|
_In_ UINT uMsg,
|
|
_In_ WPARAM wParam,
|
|
_In_ LPARAM lParam
|
|
)
|
|
{
|
|
PPHP_COLORBOX_CONTEXT context;
|
|
|
|
context = (PPHP_COLORBOX_CONTEXT)GetWindowLongPtr(hwnd, 0);
|
|
|
|
if (uMsg == WM_CREATE)
|
|
{
|
|
PhpCreateColorBoxContext(&context);
|
|
SetWindowLongPtr(hwnd, 0, (LONG_PTR)context);
|
|
}
|
|
|
|
if (!context)
|
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_CREATE:
|
|
{
|
|
// Nothing
|
|
}
|
|
break;
|
|
case WM_DESTROY:
|
|
{
|
|
PhpFreeColorBoxContext(context);
|
|
SetWindowLongPtr(hwnd, 0, (LONG_PTR)NULL);
|
|
}
|
|
break;
|
|
case WM_PAINT:
|
|
{
|
|
PAINTSTRUCT paintStruct;
|
|
RECT clientRect;
|
|
HDC hdc;
|
|
|
|
if (hdc = BeginPaint(hwnd, &paintStruct))
|
|
{
|
|
GetClientRect(hwnd, &clientRect);
|
|
|
|
// Border color
|
|
SetDCPenColor(hdc, RGB(0x44, 0x44, 0x44));
|
|
|
|
// Fill color
|
|
if (!context->Hot && !context->HasFocus)
|
|
SetDCBrushColor(hdc, context->SelectedColor);
|
|
else
|
|
SetDCBrushColor(hdc, PhMakeColorBrighter(context->SelectedColor, 64));
|
|
|
|
// Draw the rectangle.
|
|
SelectObject(hdc, GetStockObject(DC_PEN));
|
|
SelectObject(hdc, GetStockObject(DC_BRUSH));
|
|
Rectangle(hdc, clientRect.left, clientRect.top, clientRect.right, clientRect.bottom);
|
|
|
|
EndPaint(hwnd, &paintStruct);
|
|
}
|
|
}
|
|
return 0;
|
|
case WM_ERASEBKGND:
|
|
return 1;
|
|
case WM_MOUSEMOVE:
|
|
{
|
|
if (!context->Hot)
|
|
{
|
|
TRACKMOUSEEVENT trackMouseEvent = { sizeof(trackMouseEvent) };
|
|
|
|
context->Hot = TRUE;
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
|
|
trackMouseEvent.dwFlags = TME_LEAVE;
|
|
trackMouseEvent.hwndTrack = hwnd;
|
|
TrackMouseEvent(&trackMouseEvent);
|
|
}
|
|
}
|
|
break;
|
|
case WM_MOUSELEAVE:
|
|
{
|
|
context->Hot = FALSE;
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
break;
|
|
case WM_LBUTTONDOWN:
|
|
{
|
|
PhpChooseColor(hwnd, context);
|
|
}
|
|
break;
|
|
case WM_SETFOCUS:
|
|
{
|
|
context->HasFocus = TRUE;
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
return 0;
|
|
case WM_KILLFOCUS:
|
|
{
|
|
context->HasFocus = FALSE;
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
return 0;
|
|
case WM_GETDLGCODE:
|
|
if (wParam == VK_RETURN)
|
|
return DLGC_WANTMESSAGE;
|
|
return 0;
|
|
case WM_KEYDOWN:
|
|
{
|
|
switch (wParam)
|
|
{
|
|
case VK_SPACE:
|
|
case VK_RETURN:
|
|
PhpChooseColor(hwnd, context);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case CBCM_SETCOLOR:
|
|
context->SelectedColor = (COLORREF)wParam;
|
|
return TRUE;
|
|
case CBCM_GETCOLOR:
|
|
return (LRESULT)context->SelectedColor;
|
|
}
|
|
|
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
}
|