CEasyTip-用钩子封装的CToolTipCtrl

CEasyTip是一个基于MFC的CToolTipCtrl封装类,通过WH_MOUSE鼠标钩子来捕获并处理鼠标消息,实现简洁地为控件添加静态tooltip。只需两行代码即可轻松设置控件的tooltip信息。
摘要由CSDN通过智能技术生成

用钩子封装了一个类CEasyTip,该类继承CToolTipCtrl目的用于简化显示静态的tooltip消息:两条语句就可以为一个控件显示tooltip消息。如下所示:

*使用方法:1.创建对象2.创建窗口3.AddTool
*m_ToolTip.Create(this, TTS_ALWAYSTIP);
*m_ToolTip.AddTool(GetDlgItem(IDOK), _T("这个按钮的ID为IDOK\r\n是确认按钮重载使用这里为了测试测试多行提示消息"));
*m_ToolTip.AddTool(GetDlgItem(IDCANCEL), _T("ID CANCEL"));

CEasyTip的关键点在于用WH_MOUSE鼠标钩子捕获鼠标消息,并将消息发送给tooltip控件


CEasyTip的.h文件如下:

#pragma once


class CEasyTip : public CToolTipCtrl
{
public:
	CEasyTip();
	virtual ~CEasyTip();

protected:
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnDestroy();
	DECLARE_MESSAGE_MAP()

private:
	int FindTooltiObj(CPtrArray& TooltipObjects);

	//钩子函数,捕获鼠标消息并发送给tooltip控件
	static LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam);	
	//CEasyTip对象的计数
	static CPtrArray staticTooltipObjects;
};


/****************************************************
*使用方法:1.创建对象2.创建窗口3.AddTool
*m_ToolTip.Create(this, TTS_ALWAYSTIP);
*m_ToolTip.AddTool(GetDlgItem(IDOK), _T("这个按钮的ID为IDOK\r\n是确认按钮重载使用这里为了测试测试多行提示消息"));
*m_ToolTip.AddTool(GetDlgItem(IDCANCEL), _T("ID CANCEL"));
****************************************************/

CEasyTip的.cpp文件如下:

#include "stdafx.h"
#include "EasyTip.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//钩子句柄
static HHOOK g_hHook;

/
// CEasyTip

CPtrArray CEasyTip::staticTooltipObjects;


CEasyTip::CEasyTip()
{
}

CEasyTip::~CEasyTip()
{
}


BEGIN_MESSAGE_MAP(CEasyTip, CToolTipCtrl)
	ON_WM_CREATE()
	ON_WM_DESTROY()
END_MESSAGE_MAP()

/
// CEasyTip message handlers

//函数功能:WM_CREATE消息
int CEasyTip::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CToolTipCtrl::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	
	//设置父窗口允许显示tooltip
	GetParent()->EnableToolTips(TRUE);
	//设置tooltip为多行
	this->SetMaxTipWidth(260);

	//每一个CEasyTipd对象共用同一个钩子,当数组中元素为0,初始化staticTooltipObjects容器为空时创建钩子
	if (staticTooltipObjects.GetSize() == 0){

		g_hHook = SetWindowsHookEx(WH_MOUSE, MouseProc, AfxGetInstanceHandle(), GetCurrentThreadId());
		ASSERT(g_hHook != NULL);
	}
	
	//创建钩子成功,添加CEasyTip的指针到数组
	if (g_hHook)
		staticTooltipObjects.Add(this);

	return 0;
}

//函数功能:WM_DESTROY消息
void CEasyTip::OnDestroy()
{
	int		Index;
	
	//窗口销毁,从staticTooltipObjects中删除CEasyTip类型指针
	Index = FindTooltiObj(staticTooltipObjects);
	if (Index != -1)
		staticTooltipObjects.RemoveAt(Index);

	//staticTooltipObjects中元素个数为0时,则删除钩子
	if (g_hHook && staticTooltipObjects.GetSize() == 0)
		UnhookWindowsHookEx(g_hHook);
}

//函数功能:WH_MOUSE钩子函数
LRESULT CALLBACK CEasyTip::MouseProc(int code, WPARAM wParam, LPARAM lParam)
{
	CEasyTip	*pTooltip;
	MSG			msg;
	int			Index;

	PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
	if (msg.message == WM_MOUSEMOVE ||
		msg.message == WM_LBUTTONDOWN ||
		msg.message == WM_LBUTTONUP){

		//发送鼠标消息到tooltip控件
		for (Index = 0; Index < staticTooltipObjects.GetSize(); ++Index){
			pTooltip = (CEasyTip*)staticTooltipObjects.GetAt(Index);
			pTooltip->RelayEvent(&msg);
		}
	}
	
	return CallNextHookEx(g_hHook, code, wParam, lParam);
}

//函数功能:查找this在TooltipObjects中的位置
int CEasyTip::FindTooltiObj(CPtrArray& TooltipObjects)
{
	int		i;

	for (i = 0; i < TooltipObjects.GetSize(); ++i)
		if (TooltipObjects.GetAt(i) == this)
			return i;
	return -1;
}

完整的一个实例工程在我的资源里,点击这里




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值