225 lines
4.9 KiB
C++
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);
|
|
}
|