windows-nt/Source/XPSP1/NT/multimedia/directx/dinput/diconfig/flexcheckbox.cpp
2020-09-26 16:20:57 +08:00

225 lines
4.9 KiB
C++

//-----------------------------------------------------------------------------
// File: flexcheckbox.cpp
//
// Desc: Implements a check box control similar to Windows check box.
// CFlexCheckBox is derived from CFlexWnd. The only place that
// uses CFlxCheckBox is in the keyboard for sorting by assigned
// keys.
//
// Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "common.hpp"
CFlexCheckBox::CFlexCheckBox() :
m_hWndNotify(NULL),
m_bChecked(FALSE),
m_rgbText(RGB(255,255,255)),
m_rgbBk(RGB(0,0,0)),
m_rgbSelText(RGB(0,0,255)),
m_rgbSelBk(RGB(0,0,0)),
m_rgbFill(RGB(0,0,255)),
m_rgbLine(RGB(0,255,255)),
m_hFont(NULL),
m_tszText(NULL)
{
}
CFlexCheckBox::~CFlexCheckBox()
{
delete[] m_tszText;
}
void CFlexCheckBox::SetText(LPCTSTR tszText)
{
LPTSTR tszTempText = NULL;
if (tszText)
{
tszTempText = new TCHAR[_tcslen(tszText) + 1];
if (!tszTempText) return;
_tcscpy(tszTempText, tszText);
}
delete[] m_tszText;
m_tszText = tszTempText;
}
void CFlexCheckBox::SetFont(HFONT hFont)
{
m_hFont = hFont;
if (m_hWnd == NULL)
return;
Invalidate();
}
void CFlexCheckBox::SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line)
{
m_rgbText = text;
m_rgbBk = bk;
m_rgbSelText = seltext;
m_rgbSelBk = selbk;
m_rgbFill = fill;
m_rgbLine = line;
Invalidate();
}
void CFlexCheckBox::SetRect()
{
if (m_hWnd == NULL)
return;
RECT rect = GetRect();
SetWindowPos(m_hWnd, NULL, rect.left, rect.top, rect.right, rect.bottom, SWP_NOZORDER | SWP_NOMOVE);
}
RECT CFlexCheckBox::GetRect(const RECT &rect)
{
int h = GetTextHeight(m_hFont);
RECT ret = {rect.left, rect.top, rect.right, rect.top + h + 2};
return ret;
}
RECT CFlexCheckBox::GetRect()
{
RECT rect;
GetClientRect(&rect);
return GetRect(rect);
}
void CFlexCheckBox::OnPaint(HDC hDC)
{
HDC hBDC = NULL, hODC = NULL;
CBitmap *pbm = NULL;
if (!InRenderMode())
{
hODC = hDC;
pbm = CBitmap::Create(GetClientSize(), RGB(0,0,0), hDC);
if (pbm != NULL)
{
hBDC = pbm->BeginPaintInto();
if (hBDC != NULL)
{
hDC = hBDC;
}
}
}
InternalPaint(hDC);
if (!InRenderMode())
{
if (pbm != NULL)
{
if (hBDC != NULL)
{
pbm->EndPaintInto(hBDC);
pbm->Draw(hODC);
}
delete pbm;
}
}
}
void CFlexCheckBox::InternalPaint(HDC hDC)
{
HGDIOBJ hBrush = (HGDIOBJ)CreateSolidBrush(m_rgbBk);
if (hBrush != NULL)
{
HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
// Erase the background first
RECT client;
GetClientRect(&client);
Rectangle(hDC, client.left, client.top, client.right, client.bottom);
// Create pen for check box
HGDIOBJ hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbLine);
if (hPen != NULL)
{
HGDIOBJ hOldPen = SelectObject(hDC, hPen);
RECT rect = {0, 0, 0, 0}, textrc;
GetClientRect(&rect);
textrc = rect;
int iBoxDim = rect.bottom - rect.top;
// Draw the square box
rect.right = rect.left + iBoxDim;
InflateRect(&rect, -2, -2);
OffsetRect(&rect, 0, -2); // Move up to align with the text
Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
// Draw the check mark if the state is checked.
if (m_bChecked)
{
HGDIOBJ hCrossPen = CreatePen(PS_SOLID, 3, m_rgbLine);
if (hCrossPen != NULL)
{
SelectObject(hDC, hCrossPen);
MoveToEx(hDC, rect.left + 2, rect.top + 2, NULL); // Upper left
LineTo(hDC, rect.right - 2, rect.bottom - 2); // Lower right
MoveToEx(hDC, rect.right - 2, rect.top + 2, NULL); // Upper right
LineTo(hDC, rect.left + 2, rect.bottom - 2); // Lower left
SelectObject(hDC, hPen);
DeleteObject(hCrossPen);
}
}
SetBkMode(hDC, TRANSPARENT);
// Draw the message text
SetTextColor(hDC, m_rgbText);
textrc.left = rect.right + 8;
DrawText(hDC, m_tszText, -1, &textrc, DT_LEFT|DT_NOPREFIX|DT_WORDBREAK);
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
SelectObject(hDC, hOldBrush);
DeleteObject(hBrush);
}
}
void CFlexCheckBox::Notify(int code)
{
if (!m_hWndNotify)
return;
PostMessage(m_hWndNotify, WM_FLEXCHECKBOX,
(WPARAM)code, (LPARAM)(LPVOID)this);
}
void CFlexCheckBox::OnClick(POINT point, WPARAM fwKeys, BOOL bLeft)
{
if (!m_hWnd)
return;
RECT rect;
GetClientRect(&rect);
rect.right = rect.left + (rect.bottom - rect.top); // Adjust the width to same as height.
InflateRect(&rect, -2, -2);
OffsetRect(&rect, 0, -2); // Move up to align with the text
if (PtInRect(&rect, point))
{
m_bChecked = !m_bChecked;
Invalidate();
Notify(m_bChecked ? CHKNOTIFY_CHECK : CHKNOTIFY_UNCHECK); // Notify the page object about the state change.
} else
{
// Unhighlight current callout
HWND hWndParent;
hWndParent = GetParent(m_hWnd);
SendMessage(hWndParent, WM_UNHIGHLIGHT, 0, 0); // Send click message to page to unhighlight callout
}
}
void CFlexCheckBox::OnMouseOver(POINT point, WPARAM fwKeys)
{
Notify(CHKNOTIFY_MOUSEOVER);
}