原理:重载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();