原理:重载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; }
// ############################################################################

|