[ATL/WTL]_[初级]_[窗口如何实现WM_MOUSELEAVE和WM_MOUSEHOVER]


场景:

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


my_button.cpp

#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;
}

未进入:

[ATL/WTL]_[初级]_[窗口如何实现WM_MOUSELEAVE和WM_MOUSEHOVER]_第1张图片

进入:

[ATL/WTL]_[初级]_[窗口如何实现WM_MOUSELEAVE和WM_MOUSEHOVER]_第2张图片


完整项目下载地址:

http://download.csdn.net/detail/infoworld/9252273


你可能感兴趣的:(窗口,onmouseleave,鼠标移出,OnMouseHover)