|
// ToggleButton.cpp : implementation file
//
// Originally by Joseph M. Newcomer.
// Modified in Aug 01 by Jeff Mallett to display highlight color when pressed.
#include "stdafx.h"
#include "button.h"
#include "ToggleButton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CToggleButton
CToggleButton::CToggleButton()
{
depressed = FALSE;
}
CToggleButton::~CToggleButton()
{
}
BEGIN_MESSAGE_MAP(CToggleButton, CButton)
//{{AFX_MSG_MAP(CToggleButton)
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CToggleButton message handlers
/****************************************************************************
* CToggleButton::SetVPos
* Inputs:
* DWORD newstyle: Vertical style, one of BS_TOP, BS_BOTTOM, BS_VCENTER
* Result: DWORD
* Previous style
* Effect:
* Sets the style
****************************************************************************/
DWORD CToggleButton::SetVPos(DWORD newstyle)
{
DWORD style = GetStyle();
DWORD result = style;
style &= ~ (BS_TOP | BS_BOTTOM | BS_VCENTER);
style |= newstyle;
::SetWindowLong(m_hWnd, GWL_STYLE, (long)style);
InvalidateRect(NULL);
return result & (BS_TOP | BS_BOTTOM | BS_VCENTER);
} // CToggleButton::SetVPos
/****************************************************************************
* CToggleButton::SetHPos
* Inputs:
* DWORD newstyle: Horizontal style, one of BS_LEFT, BS_RIGHT, BS_CENTER
* Result: DWORD
* Previous style
* Effect:
* Sets the style
****************************************************************************/
DWORD CToggleButton::SetHPos(DWORD newstyle)
{
DWORD style = GetStyle();
DWORD result = style;
style &= ~ (BS_LEFT | BS_RIGHT | BS_CENTER);
style |= newstyle;
::SetWindowLong(m_hWnd, GWL_STYLE, (long)style);
InvalidateRect(NULL);
return result & (BS_LEFT | BS_RIGHT | BS_CENTER);
} // CToggleButton::SetHPos
void CToggleButton::DrawItem(LPDRAWITEMSTRUCT dis)
{
CDC * dc = CDC::FromHandle(dis->hDC); // Get a CDC we can use
CRect r(dis->rcItem); // Copy the button rectangle
int saved = dc->SaveDC(); // Save the DC for later restoration
CPoint pt; // left point of text
CSize sz; // size of text
CSize border(::GetSystemMetrics(SM_CXBORDER), ::GetSystemMetrics(SM_CYBORDER));
// Dimensions of a border line
// We use ::GetSystemMetrics so we work on
// hi-res displays
CPoint baseOffset(border.cx, border.cy); // Offset amount if button-down
// The three states are
// ODS_SELECTED ODS_DISABLED
// 1 n/a Button is pressed
// 0 0 Button is up
// 0 1 Button is disabled
//
dc->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
//dc->SetBkMode(TRANSPARENT);
if(dis->itemState & (ODS_DISABLED | ODS_GRAYED))
{ /* grayed */
dc->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
} /* grayed */
DWORD style = GetStyle();
style &= (BS_LEFT | BS_RIGHT | BS_CENTER);
#define MARGIN 4
CString s;
GetWindowText(s);
sz = dc->GetTextExtent(s);
UINT flags = (GetStyle() & BS_MULTILINE ? 0 : DT_SINGLELINE);
switch(style)
{ /* hstyle */
case BS_LEFT:
pt.x = MARGIN * border.cx;
flags |= DT_LEFT;
break;
case BS_RIGHT:
pt.x = r.Width() - MARGIN * border.cx - sz.cx;
flags |= DT_RIGHT;
break;
case 0:
case BS_CENTER:
pt.x = (r.Width() - sz.cx) / 2;
flags |= DT_CENTER;
break;
} /* hstyle */
style = GetStyle();
style &= (BS_TOP | BS_BOTTOM | BS_VCENTER);
switch(style)
{ /* vstyle */
case BS_TOP:
pt.y = 3 * border.cy;
flags |= DT_TOP;
break;
case BS_BOTTOM:
pt.y = r.Height() - MARGIN * border.cy - sz.cy;
flags |= DT_BOTTOM;
break;
case 0:
case BS_VCENTER:
pt.y = (r.Height() - sz.cy) / 2;
flags |= DT_VCENTER;
break;
} /* vstyle */
// Compute the focus rectangle area
CRect focus(pt.x, pt.y, pt.x + sz.cx, pt.y + sz.cy);
// For visual effect, if the button is down, shift the text over and
// down to make it look "pushed".
CPoint useOffset(0, 0);
if(depressed)
{ /* down */
useOffset = baseOffset;
} /* down */
// Draw the traditional pushbutton edge using DrawEdge
if(depressed)
{ /* down */
dc->DrawEdge(&dis->rcItem, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_SOFT);
} /* down */
else
{ /* up */
dc->DrawEdge(&dis->rcItem, EDGE_RAISED, BF_RECT | BF_MIDDLE | BF_SOFT);
} /* up */
// Fill background with highlight color
if (depressed)
{
UINT x = 3 * border.cx;
UINT y = 3 * border.cy;
CRect rect(x, y,
x + r.Width() - baseOffset.x - 4,
y + r.Height() - baseOffset.y - 4);
dc->FillSolidRect( &rect, ::GetSysColor(COLOR_BTNHIGHLIGHT));
dc->SetBkColor(::GetSysColor(COLOR_BTNHIGHLIGHT));
}
// Adjust the focus position and text position by shifting them
// right-and-down by the desired offset
focus += useOffset;
pt += useOffset;
focus.InflateRect(border.cx, border.cy);
r.InflateRect(-MARGIN * border.cx, -MARGIN * border.cy);
r += useOffset;
dc->DrawText(s, r, flags);
if(dis->itemState & ODS_FOCUS)
::DrawFocusRect(dis->hDC, &focus);
dc->RestoreDC(saved);
}
void CToggleButton::OnLButtonDown(UINT nFlags, CPoint point)
{
depressed = !depressed;
InvalidateRect(NULL);
CButton::OnLButtonDown(nFlags, point);
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.