原理:重载CStatic,响应WM_CTLCOLOR消息,实现对颜色的支持;响应WM_MOUSEMOVE并跟踪WM_MOUSEHOVER和WM_MOUSELEAVE消息,实现热跟踪功能。
LabelEx.h
#ifndef __LabelEx_h__
#define __LabelEx_h__
// ############################################################################
// # Definition of CLabelEx
class CLabelEx: public CStatic
{
DECLARE_DYNAMIC(CLabelEx)
// Constructor/Destructor
public:
CLabelEx();
// Attributes
public:
void SetTextColor(COLORREF clrText);
void SetHotTextColor(COLORREF clrHotText);
void SetBgColor(COLORREF clrBack);
void EnableHotTrack(BOOL bHotTrack);
// Overloaded funtions
protected:
virtual void PreSubclassWindow();
// Member varibles
protected:
COLORREF m_clrText;
COLORREF m_clrHotText;
COLORREF m_clrBack;
CBrush m_brBkgnd;
BOOL m_bHotTrack;
BOOL m_bHover;
// Handlers of the messages
protected:
afx_msg HBRUSH CtlColor(CDC *pDC, UINT nCtlColor);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
};
// ############################################################################
#endif //__LabelEx_h__
LabelEx.cpp
#include "StdAfx.h"
#include "LabelEx.h"
IMPLEMENT_DYNAMIC(CLabelEx, CStatic)
// ############################################################################
// # Map the messages
BEGIN_MESSAGE_MAP(CLabelEx, CStatic)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
END_MESSAGE_MAP()
// ############################################################################
// ############################################################################
// # CLabelEx constructor/destructor
CLabelEx::CLabelEx()
{
m_clrHotText = m_clrText = RGB(0, 0, 0);
m_clrBack = ::GetSysColor(COLOR_3DFACE);
m_brBkgnd.CreateSolidBrush(m_clrBack);
m_bHotTrack = FALSE;
m_bHover = FALSE;
}
// ############################################################################
// ############################################################################
// # CLabelEx attributes
void CLabelEx::SetTextColor(COLORREF clrText)
{
m_clrText = clrText;
this->Invalidate();
}
void CLabelEx::SetHotTextColor(COLORREF clrHotText)
{
m_clrHotText = clrHotText;
this->Invalidate();
}
void CLabelEx::SetBgColor(COLORREF clrBack)
{
m_clrBack = clrBack;
this->Invalidate();
}
void CLabelEx::EnableHotTrack(BOOL bHotTrack)
{
m_bHotTrack = bHotTrack;
this->Invalidate();
}
// ############################################################################
// ############################################################################
// # CLabelEx overloaded functions
void CLabelEx::PreSubclassWindow()
{
DWORD dwStyle = this->GetStyle();
::SetWindowLong(this->GetSafeHwnd(), GWL_STYLE, dwStyle | SS_NOTIFY);
CStatic::PreSubclassWindow();
}
// ############################################################################
// ############################################################################
// # CLabelEx message handlers
HBRUSH CLabelEx::CtlColor(CDC *pDC, UINT nCtlColor)
{
if (m_bHover)
pDC->SetTextColor(m_clrHotText);
else
pDC->SetTextColor(m_clrText);
pDC->SetBkColor(m_clrBack);
return (HBRUSH)m_brBkgnd;
}
void CLabelEx::OnMouseMove(UINT nFlags, CPoint point)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_HOVER | TME_LEAVE;
tme.hwndTrack = m_hWnd;
tme.dwHoverTime = HOVER_DEFAULT;
_TrackMouseEvent(&tme);
if (m_bHover) // Cursor is currently over control
{
CRect rect;
GetClientRect(rect);
if (!rect.PtInRect(point))
{
m_bHover = FALSE;
this->Invalidate();
::ReleaseCapture();
}
}
else // Cursor has just moved over control
{
m_bHover = TRUE;
this->Invalidate();
this->SetCapture();
// 这儿使用了偷懒的办法,使用系统的手型光标只能在win2k或以上OS工作,如果希望能在win95或win98下工作的话最好自己创建光标资源
if (m_bHotTrack)
::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(32649)));
}
CStatic::OnMouseMove(nFlags, point);
}
LRESULT CLabelEx::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
m_bHover = FALSE;
this->Invalidate();
::ReleaseCapture();
return 0;
}
// ############################################################################