[ATL/WTL]_[初级]_[窗口如何实现一个Tooltip]

本文介绍如何为WTL控件添加WM_MOUSEHOVER和WM_MOUSELEAVE事件支持,通过自定义按钮类实现鼠标悬停时背景颜色变化,并提供代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

场景:

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


未进入:

 

进入:


完整项目下载地址:

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

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白行微

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值