268 lines
5.6 KiB
C++
268 lines
5.6 KiB
C++
//
|
|
// WGRP.CPP
|
|
// Widths Group
|
|
//
|
|
// Copyright Microsoft 1998-
|
|
//
|
|
|
|
// PRECOMP
|
|
#include "precomp.h"
|
|
|
|
|
|
static const TCHAR szWGClassName[] = "WB_WGRP";
|
|
|
|
|
|
WbWidthsGroup::WbWidthsGroup()
|
|
{
|
|
int i;
|
|
|
|
m_hwnd = NULL;
|
|
m_uLast = 0;
|
|
|
|
//
|
|
// Calculate the height of each item in the list--it's the max of the
|
|
// pen widths + slop space
|
|
//
|
|
m_cyItem = 0;
|
|
for (i = 0; i < NUM_OF_WIDTHS; i++)
|
|
{
|
|
m_cyItem = max(m_cyItem, g_PenWidths[i]);
|
|
}
|
|
m_cyItem += 2 * ::GetSystemMetrics(SM_CYEDGE);
|
|
}
|
|
|
|
|
|
WbWidthsGroup::~WbWidthsGroup()
|
|
{
|
|
if (m_hwnd != NULL)
|
|
{
|
|
::DestroyWindow(m_hwnd);
|
|
ASSERT(m_hwnd == NULL);
|
|
}
|
|
|
|
::UnregisterClass(szWGClassName, g_hInstance);
|
|
}
|
|
|
|
|
|
|
|
BOOL WbWidthsGroup::Create(HWND hwndParent, LPCRECT lprect)
|
|
{
|
|
WNDCLASSEX wc;
|
|
|
|
// Register our class
|
|
ZeroMemory(&wc, sizeof(wc));
|
|
wc.cbSize = sizeof(wc);
|
|
wc.style = 0;
|
|
wc.lpfnWndProc = WGWndProc;
|
|
wc.hInstance = g_hInstance;
|
|
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
|
|
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
|
|
wc.lpszClassName = szWGClassName;
|
|
|
|
if (!::RegisterClassEx(&wc))
|
|
{
|
|
ERROR_OUT(("WbWidthsGroup::Create register class failed"));
|
|
return(FALSE);
|
|
}
|
|
|
|
ASSERT(!m_hwnd);
|
|
|
|
if (!::CreateWindowEx(WS_EX_STATICEDGE, szWGClassName, NULL,
|
|
WS_CHILD | WS_CLIPSIBLINGS, lprect->left, lprect->top,
|
|
lprect->right - lprect->left, lprect->bottom - lprect->top,
|
|
hwndParent, (HMENU)IDM_WIDTH, g_hInstance, this))
|
|
{
|
|
ERROR_OUT(("Can't create WbWidthsGroup"));
|
|
return(FALSE);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// WGWndProc()
|
|
// Message handler for width window
|
|
//
|
|
LRESULT CALLBACK WGWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LRESULT lResult = 0;
|
|
WbWidthsGroup * pwg = (WbWidthsGroup *)::GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
|
|
|
switch (message)
|
|
{
|
|
case WM_NCCREATE:
|
|
pwg = (WbWidthsGroup *)(((LPCREATESTRUCT)lParam)->lpCreateParams);
|
|
ASSERT(pwg);
|
|
|
|
pwg->m_hwnd = hwnd;
|
|
::SetWindowLongPtr(hwnd, GWLP_USERDATA, (LPARAM)pwg);
|
|
goto DefWndProc;
|
|
break;
|
|
|
|
case WM_NCDESTROY:
|
|
ASSERT(pwg);
|
|
pwg->m_hwnd = NULL;
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
ASSERT(pwg);
|
|
pwg->OnPaint();
|
|
break;
|
|
|
|
case WM_LBUTTONDOWN:
|
|
ASSERT(pwg);
|
|
pwg->OnLButtonDown((short)LOWORD(lParam), (short)HIWORD(lParam));
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
// Pass up to main window
|
|
lResult = ::SendMessage(g_pMain->m_hwnd, message, wParam, lParam);
|
|
break;
|
|
|
|
default:
|
|
DefWndProc:
|
|
lResult = DefWindowProc(hwnd, message, wParam, lParam);
|
|
break;
|
|
}
|
|
|
|
return(lResult);
|
|
}
|
|
|
|
|
|
|
|
void WbWidthsGroup::GetNaturalSize(LPSIZE lpsize)
|
|
{
|
|
lpsize->cy = ::GetSystemMetrics(SM_CYEDGE) +
|
|
(NUM_OF_WIDTHS * m_cyItem);
|
|
|
|
if (m_hwnd != NULL)
|
|
{
|
|
RECT rect;
|
|
|
|
::GetWindowRect(m_hwnd, &rect);
|
|
rect.right -= rect.left;
|
|
lpsize->cx = max(WIDTHBAR_WIDTH, rect.right);
|
|
}
|
|
else
|
|
{
|
|
lpsize->cx = WIDTHBAR_WIDTH;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WbWidthsGroup::PushDown(UINT uiIndex)
|
|
{
|
|
if( (uiIndex < NUM_OF_WIDTHS))
|
|
{
|
|
//
|
|
// We really should just invalidate the last selected item, if one,
|
|
// and the new selected item, if one. But heck, there are only 4
|
|
// items, no big deal to paint.
|
|
//
|
|
m_uLast = uiIndex;
|
|
::InvalidateRect(m_hwnd, NULL, TRUE);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void WbWidthsGroup::OnPaint(void)
|
|
{
|
|
PAINTSTRUCT ps;
|
|
int i;
|
|
RECT rect;
|
|
int cx, cy;
|
|
int nPenWidth;
|
|
HBRUSH hOldBrush;
|
|
|
|
::BeginPaint(m_hwnd, &ps);
|
|
|
|
::GetClientRect(m_hwnd, &rect);
|
|
cx = ::GetSystemMetrics(SM_CXEDGE);
|
|
cy = m_cyItem / 2;
|
|
|
|
// First, fill the background of the selected item
|
|
hOldBrush = SelectBrush(ps.hdc, ::GetSysColorBrush(COLOR_3DHILIGHT));
|
|
|
|
::PatBlt(ps.hdc, rect.left, m_uLast * m_cyItem,
|
|
rect.right - rect.left, m_cyItem, PATCOPY);
|
|
|
|
rect.right -= rect.left + 2*cx;
|
|
|
|
// Now, use the black brush
|
|
SelectBrush(ps.hdc, ::GetStockObject(BLACK_BRUSH));
|
|
|
|
for (i = 0; i < NUM_OF_WIDTHS; i++)
|
|
{
|
|
nPenWidth = g_PenWidths[i];
|
|
|
|
::PatBlt(ps.hdc, cx, rect.top + (m_cyItem - nPenWidth) / 2,
|
|
rect.right, nPenWidth, PATCOPY);
|
|
|
|
rect.top += m_cyItem;
|
|
}
|
|
|
|
SelectBrush(ps.hdc, hOldBrush);
|
|
|
|
// Finish painting
|
|
::EndPaint(m_hwnd, &ps);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// ItemFromPoint()
|
|
// Returns which item, in the client, is under the point.
|
|
//
|
|
int WbWidthsGroup::ItemFromPoint(int x, int y) const
|
|
{
|
|
int iItem;
|
|
|
|
iItem = y / m_cyItem;
|
|
|
|
// If it's in the border above the first item, pin it.
|
|
if (iItem < 0)
|
|
iItem = 0;
|
|
|
|
// If it's in the border below the last item, pin it.
|
|
if (iItem >= (IDM_WIDTHS_END - IDM_WIDTHS_START))
|
|
iItem = (IDM_WIDTHS_END - IDM_WIDTHS_START - 1);
|
|
|
|
return(iItem + IDM_WIDTHS_START);
|
|
}
|
|
|
|
|
|
//
|
|
// GetItemRect()
|
|
// Gets the client-relative rectangle of an item
|
|
//
|
|
void WbWidthsGroup::GetItemRect(int iItem, LPRECT lprc) const
|
|
{
|
|
::GetClientRect(m_hwnd, lprc);
|
|
|
|
lprc->top = (iItem - IDM_WIDTHS_START) * m_cyItem;
|
|
lprc->bottom = lprc->top + m_cyItem;
|
|
}
|
|
|
|
|
|
//
|
|
// OnLButtonDown()
|
|
//
|
|
void WbWidthsGroup::OnLButtonDown(int x, int y)
|
|
{
|
|
int iItem;
|
|
|
|
iItem = ItemFromPoint(x, y);
|
|
::PostMessage(g_pMain->m_hwnd, WM_COMMAND,
|
|
(WPARAM)MAKELONG(iItem, BN_CLICKED),
|
|
(LPARAM)m_hwnd);
|
|
}
|
|
|
|
|
|
|
|
|