15,979
社区成员
发帖
与我相关
我的任务
分享
class CHotBtn : public CButton
{
DECLARE_DYNAMIC(CHotBtn)
public:
CHotBtn();
virtual ~CHotBtn();
public: //Attributs
BOOL _bMouseTrack; //是否跟踪鼠标开关变量
protected:
DECLARE_MESSAGE_MAP()
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnMouseLeave();
afx_msg void OnMouseHover(UINT nFlags, CPoint point);
};
HotBtn.cpp
IMPLEMENT_DYNAMIC(CHotBtn, CButton)
CHotBtn::CHotBtn()
{
_bMouseTrack = TRUE; //是否跟踪鼠标开关变量
}
CHotBtn::~CHotBtn()
{
}
BEGIN_MESSAGE_MAP(CHotBtn, CButton)
ON_WM_MOUSEMOVE()
ON_WM_MOUSELEAVE()
ON_WM_MOUSEHOVER()
END_MESSAGE_MAP()
// CHotBtn 消息处理程序
#define DIRTOOLMENUID 8030
void CHotBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: 添加您的代码以绘制指定项
CRect rect; //声明区域对象
GetClientRect(rect); //获得按钮的客户区域
CDC dc; //声明设备上下文
dc.Attach(lpDrawItemStruct->hDC); //设置设备上下文
//CHotBtn类中申明一个结构体和设置结构体的函数,提供外部绘制信息
//如此就可以使下面的代码通用。 注意OnMouseHover函数也要改
if(lpDrawItemStruct->CtlID == DIRTOOLMENUID/*=8030*/) //DirToolMenu控件
{
CRect rect;
GetClientRect(&rect);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
CBitmap bmpBackground;
bmpBackground.LoadBitmap(MAKEINTRESOURCE(IDB_BITMAP1));
CBitmap *pbmpOld = dcMem.SelectObject(&bmpBackground);
dc.SetStretchBltMode(COLORONCOLOR);
dc.BitBlt(0,0,66,22,&dcMem,0,2,SRCCOPY);
dcMem.SelectObject(pbmpOld);
bmpBackground.DeleteObject();
dcMem.DeleteDC();
}
}
void CHotBtn::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
TRACKMOUSEEVENT csTME;
csTME.cbSize = sizeof(csTME);
csTME.dwFlags = TME_LEAVE | TME_HOVER; //Mouse leave and hover
csTME.hwndTrack = m_hWnd; //指定要追踪的窗口
csTME.dwHoverTime = 2; //鼠标在按钮上停留超过10ms才认为状态为Hover
::_TrackMouseEvent(&csTME); //开启windows的WM_MOUSELEAVE,WM_MOUSEHOVER事件支持
_bMouseTrack = FALSE; //若已经追踪,则停止追踪
CButton::OnMouseMove(nFlags, point);
}
void CHotBtn::OnMouseLeave()
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
_bMouseTrack = TRUE;
Invalidate(TRUE);
CButton::OnMouseLeave();
}
void CHotBtn::OnMouseHover(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rect; //声明区域对象
GetClientRect(rect);
CDC dc;
CDC *getdc = GetDC(); //获得按钮的客户区域 //声明设备上下文
HDC hdc = HDC(*getdc);
dc.Attach(hdc); //设置设备上下文
CBitmap bitmap;
bitmap.LoadBitmap(MAKEINTRESOURCE(IDB_BITMAP2));
CDC *mdc = new CDC();
mdc->CreateCompatibleDC(&dc); //用hdc创建与内存兼容的设备句柄mdc
mdc->SelectObject(&bitmap);
dc.BitBlt(0,0,36,22,mdc,0,2,SRCCOPY);
delete mdc;
//MessageBox(_T("MouseHover"));
CButton::OnMouseHover(nFlags, point);
}
1 把下面代码加进对话框的WM_MOUSEMOVE的消息响应中
TRACKMOUSEEVENT tme;
tme.cbSize=sizeof(TRACKMOUSEEVENT);
tme.dwFlags=TME_HOVER | TME_LEAVE;
tme.dwHoverTime=HOVER_DEFAULT;
tme.hwndTrack=m_hWnd;
if(!_TrackMouseEvent(&tme))
AfxMessageBox("鼠标事件捕捉失败!");
2 然后你直接可以用下面代码在PreTranslateMessage函数中接收,不需要自己写WM_MOUSELEASE和WM_MOUSEHOVER消息的响应函数(当然你要自己写也行):
if(pMsg->message==WM_MOUSELEAVE)
AfxMessageBox("mouse leave");
return CDialog::PreTranslateMessage(pMsg);
或者
手动添加消息响应WM_MOUSELEASE。
.h
afx_msg LRESULT OnMouseLeave(WPARAM wParam,LPARAM lParam);
afx_msg LRESULT OnMouseHover(WPARAM wParam,LPARAM lParam);
.cpp
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER,OnMouseHover)
LRESULT CMyButton::OnMouseLeave(WPARAM wParam,LPARAM lParam)
{
m_bMouseOver=FALSE;
m_bTrack=FALSE;
InvalidateRect(NULL);
return 0;
}
LRESULT CMyButton::OnMouseHover(WPARAM wParam,LPARAM lParam)
{
m_bMouseOver=TRUE;
InvalidateRect(NULL);
return 0;
}