📄 calendar_btn.cpp
字号:
// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - -
// - File: calendar_btn.cpp. -
// - -
// - Contents: Implementation of class CCalBtn. -
// - -
// - Purpose: Ownerdrawn button specially made for calendar usage. -
// - -
// - Remarks: - -
// - -
// - Originator: Michael Mogensen, MM-IT Consult 2003. -
// - -
// - Compiler: MS Visual C++ ver6.0. -
// - -
// - Period: 29.04.03 - 00.00.00. -
// - -
// - Version: 1.00. -
// - -
// ------------------------------------------------------------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - Miscellaneous. -
// ------------------------------------------------------------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - Header(s). -
// ------------------------------------------------------------------------------------------------------------------------------------------------------
#pragma once
#include "stdafx.h"
#include "calendar_btn.h" // Self.
// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - Miscellaneous. -
// ------------------------------------------------------------------------------------------------------------------------------------------------------
#define new DEBUG_NEW
// ------------------------------------------------------------------------------------------------------------------------------------------------------
// - CCalBtn. -
// ------------------------------------------------------------------------------------------------------------------------------------------------------
const UINT CCalBtn::WM_BTN =
::RegisterWindowMessage(_T("CalBtn_Msg"));
const UINT CCalBtn::WM_BTN_RADIO =
::RegisterWindowMessage(_T("CalBtn_Radio_Msg"));
const UINT CCalBtn::WM_BTN_ONHOVER =
::RegisterWindowMessage(_T("CalBtn_Hovered"));
IMPLEMENT_DYNCREATE(CCalBtn, CButton)
BEGIN_MESSAGE_MAP(CCalBtn, CButton)
// System.
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_DRAWITEM()
ON_WM_KEYDOWN()
ON_WM_MOUSEWHEEL()
ON_WM_NCHITTEST()
ON_WM_TIMER()
// Reflect normal btn. clicked.
ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
END_MESSAGE_MAP()
// 1. Object. (alphabetical).
CCalBtn::CCalBtn(
const enum EGraph iType,
const enum EStyle iStyle,
const enum EBehaviour iBehaviour) :
m_iAutoRepeat(-1), // Meaning don't use autorepeat by default.
m_bIsHovered(false),
m_bIsPressed(false),
m_iBehaviour(iBehaviour),
m_iCheckState(I_MF_UNCHECKED),
m_iStyle(iStyle),
m_iState(eST_Normal),
m_iType(iType),
m_pFont(NULL),
m_uTextAlign(TA_CENTER),
CButton()
// Create.
{
ResourcesCreate();
}
CCalBtn::~CCalBtn()
// Kill.
{
ResourcesDestroy();
}
// 2. Event's. (alphabetical).
void CCalBtn::DrawItem(LPDRAWITEMSTRUCT lpdis)
// Draw button.
{
CDC dc;
dc.Attach(lpdis->hDC);
CShadowDC dc_shadow(&dc);
// Set pressed state.
m_bIsPressed = ((lpdis->itemState & ODS_SELECTED) == 1);
const CRectEx irClient(lpdis->rcItem);
Draw_Button(dc_shadow, irClient);
}
void CCalBtn::OnClicked()
// Btn. was pressed.
{
if(m_iState == eST_Disabled || m_iBehaviour == eBE_Static)
return;
CFrameWnd *pParent = static_cast<CFrameWnd*>(GetParent());
if(pParent)
pParent->SendMessage(WM_BTN, (WPARAM)this, 0L);
}
int CCalBtn::OnCreate(LPCREATESTRUCT lpcs)
// The framework calls this member function when an application requests that the Windows window be created by calling the Create or CreateEx member function.
{
if(CButton::OnCreate(lpcs) == -1)
return -1;
Init();
return 0;
}
void CCalBtn::OnDestroy()
// The framework calls this member function to inform the CWnd object that it is being destroyed.
{
CButton::OnDestroy();
}
void CCalBtn::OnKeyDown(UINT uChar, UINT uRepeat, UINT uFlag)
// The framework calls this member function when a nonsystem key is pressed. A nonsystem key is a
// keyboard key that is pressed when the ALT key is not pressed or a keyboard key that is pressed
// when CWnd has the input focus.
{
CButton::OnKeyDown(uChar, uRepeat, uFlag);
CFrameWnd *pParent = static_cast<CFrameWnd*>(GetParent());
if(pParent)
pParent->SendMessage(WM_KEYDOWN, (LONG)uChar, 0L);
}
BOOL CCalBtn::OnMouseWheel(UINT uFlag, short sDelta, CPoint ipMouse)
// The framework calls this member function as a user rotates the mouse wheel and encounters the wheel's next notch.
{
// For Windows NT 4.0 and up.
BOOL bResult = CButton::OnMouseWheel(uFlag, sDelta, ipMouse);
CFrameWnd *pParent = static_cast<CFrameWnd*>(GetParent());
if(pParent)
pParent->SendMessage(WM_MOUSEWHEEL, (LONG)sDelta, 0L);
return bResult;
}
UINT CCalBtn::OnNcHitTest(CPoint ipMouse)
// The framework calls this member function for the CWnd object that contains the cursor (or the CWnd object that used the SetCapture member function to capture the mouse input) every time the mouse is moved.
{
UINT uHit = CButton::OnNcHitTest(ipMouse);
if(m_iStyle == eS_Flat)
{
if(!m_bIsHovered) // To avoid flicker.
{
if(uHit == HTCLIENT)
{
Timer_Create(ID_TIMER_HOVER, I_TIMEOUT_HOVER);
// Set hovered state.
m_bIsHovered = true;
Invalidate();
}
}
}
return uHit;
}
void CCalBtn::OnTimer(UINT uIdEvent)
// The framework calls this member function after each interval specified in the SetTimer member function used to install a timer.
{
CButton::OnTimer(uIdEvent);
CFrameWnd *pParent = static_cast<CFrameWnd*>(GetParent());
if(m_iStyle == eS_Flat) // Autorepeat is for flat buttons only (for now).
{
if(IsHovered())
{
pParent->SendMessage(WM_BTN_ONHOVER, (WPARAM)&m_cstrHint, 0L);
if(m_bIsPressed)
{
// If autorepeat is used: Wait until timeout is 0 before start.
if(m_iAutoRepeat > -1)
{
if(!m_iAutoRepeat)
{
// Fire!!!
pParent->SendMessage(WM_COMMAND, GetDlgCtrlID());
}
else
{
if(!(m_iAutoRepeat = max(m_iAutoRepeat - I_TIMEOUT_HOVER, 0)))
{
// Begin.
Timer_Create(ID_TIMER_AUTOREPEAT, I_TIMEOUT_AUTOREPEAT);
}
}
}
}
else
{
// If autorepeat is used: Kill autorepeat.
if(m_iAutoRepeat > -1)
{
// End.
m_iAutoRepeat = I_COUNTDOWN_AUTOREPEAT;
Timer_Destroy(ID_TIMER_AUTOREPEAT);
}
}
}
else
{
// If autorepeat is used: Kill autorepeat.
if(m_iAutoRepeat > -1)
{
// End.
m_iAutoRepeat = I_COUNTDOWN_AUTOREPEAT;
Timer_Destroy(ID_TIMER_AUTOREPEAT);
}
Timer_Destroy(ID_TIMER_HOVER);
// Set hovered state.
m_bIsHovered = false;
Invalidate();
}
}
}
// 4. Slaves. (alphabetical).
const void CCalBtn::CreateFont(int iPointSize, LPCTSTR lpszFaceName)
// Create new font.
{
m_pFont = new CFont();
ASSERT(m_pFont);
if(iPointSize == 0 || !lpszFaceName)
{
// Default font is native message bar font.
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICS);
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
m_pFont->CreateFontIndirect(&ncm.lfMessageFont);
}
else
{
// Non native font.
m_pFont->CreatePointFont(iPointSize, lpszFaceName);
}
}
const void CCalBtn::Draw_ArrowHead(
CShadowDC &dc_shadow,
const CRectEx &irArrow,
const enum EArrowDirection iDirection)
// Draw arrow on btn.
{
COLORREF crArrow = 0L;
if(m_bIsPressed)
{
crArrow = (m_iState == eST_Disabled ? m_crBtn_Internals_Disabled : m_crBtn_Internals_Pressed);
}
else
{
if(m_bIsHovered)
{
crArrow = (m_iState == eST_Disabled ? m_crBtn_Internals_Disabled : m_crBtn_Internals_Raised);
}
else
{
crArrow = (m_iState == eST_Disabled ? m_crBtn_Internals_Disabled : m_crBtn_Internals_Sleeping);
}
}
CPen Pen(PS_SOLID, 1, crArrow);
CPen *pPen_Old = dc_shadow.SelectObject(&Pen);
CRectEx irArrowEx(irArrow);
switch(iDirection)
{
case eAE_North:
{
irArrowEx.bottom--;
do
{
dc_shadow.MoveTo(irArrowEx.left, irArrowEx.bottom);
dc_shadow.LineTo(irArrowEx.right, irArrowEx.bottom--);
}
while(++irArrowEx.left < --irArrowEx.right);
break;
}
case eAE_East:
{
do
{
dc_shadow.MoveTo(irArrowEx.left, irArrowEx.top);
dc_shadow.LineTo(irArrowEx.left++, irArrowEx.bottom);
}
while(++irArrowEx.top < --irArrowEx.bottom);
break;
}
case eAE_South:
{
do
{
dc_shadow.MoveTo(irArrowEx.left, irArrowEx.top);
dc_shadow.LineTo(irArrowEx.right, irArrowEx.top++);
}
while(++irArrowEx.left < --irArrowEx.right);
break;
}
case eAE_West:
{
irArrowEx.right--;
do
{
dc_shadow.MoveTo(irArrowEx.right, irArrowEx.top);
dc_shadow.LineTo(irArrowEx.right--, irArrowEx.bottom);
}
while(++irArrowEx.top < --irArrowEx.bottom);
break;
}
}
dc_shadow.SelectObject(pPen_Old);
}
const void CCalBtn::Draw_Box(
CShadowDC &dc_shadow,
const CRectEx &irBox)
// Draw box on btn.
{
COLORREF crBox = 0L;
if(m_bIsPressed)
{
crBox = (m_iState == eST_Disabled ? m_crBtn_Internals_Disabled : m_crBtn_Internals_Pressed);
}
else
{
if(m_bIsHovered)
{
crBox = (m_iState == eST_Disabled ? m_crBtn_Internals_Disabled : m_crBtn_Internals_Raised);
}
else
{
crBox = (m_iState == eST_Disabled ? m_crBtn_Internals_Disabled : m_crBtn_Internals_Sleeping);
}
}
CPen Pen(PS_SOLID, 1, crBox);
CPen *pPen_Old = dc_shadow.SelectObject(&Pen);
CBrush Brush;
Brush.CreateSolidBrush(crBox);
dc_shadow.FillRect(irBox, &Brush);
}
const void CCalBtn::Draw_Button(
CShadowDC &dc_shadow,
const CRectEx &irClient)
// Draw first externals then internals.
{
Draw_Button_Externals(dc_shadow, irClient);
Draw_Button_Internals(dc_shadow, irClient);
}
const void CCalBtn::Draw_Button_Externals(
CShadowDC &dc_shadow,
const CRectEx &irClient)
// Draw bkgnd. and bounding rect. of btn.
{
CBrush *pbrBtnBackground = CBrush::FromHandle(m_hbrBtn_Externals_Background);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -