场景:
1. WTL的控件默认不支持进入和移出的 WM_MOUSEHOVER ,WM_MOUSELEAVE 事件, 即使写了映射也没用, 必须要使用函数
_TrackMouseEvent 添加监听.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms645615(v=vs.85).aspx
2. 默认的Window窗口如果有子窗口时, 当进入子窗口时, 会对父窗口调用WM_MOUSELEAVE, 因为子窗口默认会拦截消息, 因为子窗口也得处理自己的MOUSEMOVE事件.
如果想全权处理子窗口的消息, 那么需要自己处理所有鼠标事件,这里没找到方法. 如果想自己处理子窗口的进入移除事件, 可以在父窗口绘制子窗口的按钮.
my_button.h
#ifndef __MY_BUTTON_H #define __MY_BUTTON_H #include <Windows.h> #include <string> #include "atlframe.h" class MyButton : public CWindowImpl<MyButton> { public: MyButton(){} ~MyButton(){} BEGIN_MSG_MAP_EX(MyButton) MESSAGE_HANDLER(WM_PAINT,OnPaint) MESSAGE_HANDLER(WM_CREATE,OnCreate) MESSAGE_HANDLER(WM_LBUTTONDOWN,OnLButtonDown) MESSAGE_HANDLER(WM_MOUSEMOVE,OnMouseMove) MESSAGE_HANDLER(WM_MOUSEHOVER,OnMouseHover) MESSAGE_HANDLER(WM_MOUSELEAVE,OnMouseLeave) REFLECT_NOTIFICATIONS() END_MSG_MAP() protected: LRESULT OnEraseBkgnd(UINT uMsg,WPARAM wparam,LPARAM lparam,BOOL& bHandled); LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnPaint(UINT uMsg,WPARAM nnwparam,LPARAM lparam,BOOL& bHandled); LRESULT OnCreate(UINT uMsg,WPARAM nnwparam,LPARAM lparam,BOOL& bHandled); LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnMouseHover(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnMouseLeave(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); private: CToolTipCtrl tooltip_; CButton button_; bool m_bTracking_; HBRUSH bg_color_brush_; HBRUSH bg_white_brush_; HBRUSH bg_brush_; CRect button_rect_; }; #endif
#include "stdafx.h" #include "my_button.h" LRESULT MyButton::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { POINT pt = { LOWORD(lParam), HIWORD(lParam) }; if (PtInRect(&button_rect_, pt)) { } return 0; } LRESULT MyButton::OnMouseHover(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { bg_brush_ = bg_color_brush_; Invalidate(0); return 0; } LRESULT MyButton::OnMouseLeave(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { bg_brush_ = bg_white_brush_; Invalidate(0); m_bTracking_ = false; return 0; } LRESULT MyButton::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { MSG msg; msg.message = WM_MOUSEMOVE; msg.hwnd = m_hWnd; msg.lParam = lParam; msg.wParam = wParam; tooltip_.RelayEvent(&msg); if (!m_bTracking_) { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_LEAVE | TME_HOVER;//要触发的消息类型 tme.hwndTrack = m_hWnd; tme.dwHoverTime = 10;// 如果不设此参数,无法触发mouseHover if (::_TrackMouseEvent(&tme)) //MOUSELEAVE|MOUSEHOVER消息由此函数触发. { m_bTracking_ = true; } } return 0; } LRESULT MyButton::OnCreate(UINT uMsg,WPARAM nnwparam,LPARAM lparam,BOOL& bHandled) { m_bTracking_ = false; bg_white_brush_ = AtlGetStockBrush(BLACK_BRUSH); bg_color_brush_ = AtlGetStockBrush(GRAY_BRUSH); tooltip_.Create(m_hWnd,NULL,NULL,TTS_NOPREFIX); tooltip_.AddTool(m_hWnd,L"tooltip"); bg_brush_ = bg_white_brush_; button_.Create(m_hWnd,CRect(20,20,120,40),L"Open",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON); return 0; } LRESULT MyButton::OnEraseBkgnd(UINT uMsg,WPARAM wparam,LPARAM lparam,BOOL& bHandled) { return (LRESULT)1; } LRESULT MyButton::OnPaint(UINT uMsg,WPARAM nnwparam,LPARAM lparam,BOOL& bHandled) { CPaintDC hdc(m_hWnd); CRect client_rect; GetClientRect(&client_rect); CMemoryDC mdc(hdc,client_rect); mdc.SetBkMode(TRANSPARENT); Gdiplus::Graphics graphics(mdc); mdc.FillRect(client_rect,bg_brush_); return 0; }
进入:
完整项目下载地址:
http://download.csdn.net/detail/infoworld/9252273