windows-nt/Source/XPSP1/NT/enduser/netmeeting/ui/wb/wgrp.cpp
2020-09-26 16:20:57 +08:00

268 lines
5.6 KiB
C++

//
// WGRP.CPP
// Widths Group
//
// Copyright Microsoft 1998-
//
// PRECOMP
#include "precomp.h"
static const TCHAR szWGClassName[] = "T126WB_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, (LONG_PTR)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);
}