用钩子封装了一个类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;
}
完整的一个实例工程在我的资源里,点击这里。