分享
 
 
 

在菜单条上添加泡泡提示

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

该功能的实现来源于codeproject上面的一个例子《Tooltips for Menu Item and popup menuitem》,其实例子讲的步骤很简单,不过我不打算简单的翻译一下,林语堂先生不是说:“只用一样东西,不明白它的道理,实在不高明”。

实现该功能的核心在于作者自己建立的一个MenuToolTip类,182行的代码实现了菜单提示的功能,下面我就将其一一解释开来,在每行代码的后面有具体的解释。

#ifndef _MENU_TOOLTIP //条件编译语句,判断是否定义了_MENU_TOOLTI宏

#define _MENU_TOOLTIP

//以下定义一些常量标识符

#ifndef TTS_NOANIMATE

#define TTS_NOANIMATE 0x10

#define TTS_NOFADE 0x20

#define TTS_BALLOON 0x40

#define TTS_CLOSE 0x80

#define TTM_SETTITLEA (WM_USER + 32) // wParam = TTI_*, lParam = char* szTitle

#define TTM_SETTITLEW (WM_USER + 33) // wParam = TTI_*, lParam = wchar* szTitle

#ifdef UNICODE

#define TTM_SETTITLE TTM_SETTITLEW

#else

#define TTM_SETTITLE TTM_SETTITLEA

#endif

#endif

class CMenuToolTip

{

public:

CMenuToolTip():m_hToolTip(0), m_hParent(0) {}

// 创建与菜单项相关的提示

void Create(HWND hParent, LPCTSTR sczTipText,

HINSTANCE hInstance = NULL,

DWORD dwStyle = 0,

LPCTSTR sczTipTitle = NULL);

//触发WM_MENUSELECT消息时调用此函数

void OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSubMenu);

// 显示或隐藏提示的函数

void ShowToolTip(BOOL bShow)

{

TOOLINFO ti;//TOOLINFO是一个存放控件提示信息的结构

//以下初始化该结构中的一些变量

ti.cbSize = sizeof(TOOLINFO);//设定结构的大小

ti.uFlags = TTF_IDISHWND;//指出uid成员是窗口的句柄

ti.hwnd = m_hParent;//包含提示的窗口的句柄

ti.uId = (UINT)m_hParent;//应用程序定义的标识符

//发送出现提示的消息

::SendMessage(m_hToolTip,TTM_TRACKACTIVATE,(WPARAM)bShow,(LPARAM)&ti);

}

// 设置提示出现的位置

void SetToolTipPosition(HMENU hMenu, UINT nItemID)

{

RECT rt = {0,0,0,0};

// find Item Rectangle and position

//根据菜单项的数量完成以下循环

for(int nItem = 0; nItem < ::GetMenuItemCount(hMenu); nItem++) {

UINT cmd = ::GetMenuItemID(hMenu, nItem);//将当前菜单项的标识符存放到一个变量中

//如果当前菜单项是选定的菜单项,则获取菜单项的区域

if(cmd == nItemID) {

::GetMenuItemRect(m_hParent, hMenu, nItem, &rt);

}

}

//发送消息以设定显示提示的位置

::SendMessage(m_hToolTip, TTM_TRACKPOSITION, 0,

(LPARAM)MAKELPARAM(rt.right, rt.bottom + 2));

//将提示显示在最顶层,否则的话提示箭头会出现在菜单下面,试试看:->

::SetWindowPos(m_hToolTip, HWND_TOPMOST ,0,0,0,0, SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOMOVE);

}

// 更新提示信息

void UpdateToolTipText(LPCTSTR szBuff, HINSTANCE hInstance = 0)

{

TOOLINFO ti;

ti.cbSize = sizeof(TOOLINFO);

ti.uFlags = TTF_IDISHWND;

ti.hwnd = m_hParent;

ti.uId = (UINT)m_hParent;

ti.hinst = hInstance;

ti.lpszText = const_cast<LPTSTR>(szBuff);//更新提示文本的内容

//发送更新的消息

::SendMessage(m_hToolTip,TTM_UPDATETIPTEXT,(WPARAM)0,(LPARAM)&ti);

}

//重载句柄操作符

operator HWND()

{

return m_hToolTip;

}

private:

HWND m_hToolTip;

HWND m_hParent;

TCHAR m_szDefault[_MAX_PATH] ;//存放缺省提示的串

HINSTANCE m_hInstance;

};

inline//以下内联函数创建提示控件

void CMenuToolTip::Create(HWND hParent, LPCTSTR sczTipText, HINSTANCE hInstance,

DWORD dwStyle, LPCTSTR sczTipTitle)

{

INITCOMMONCONTROLSEX icex;//在公用控件的动态链接库中注册公用控件类

TOOLINFO ti;

// Load the ToolTip class from the DLL.

icex.dwSize = sizeof(icex);

icex.dwICC = ICC_BAR_CLASSES;

//如果注册失败,则返回

if(!InitCommonControlsEx(&icex))

return;

m_hParent = hParent;

m_hInstance = hInstance;

// 创建提示控件

m_hToolTip = ::CreateWindow(TOOLTIPS_CLASS, TEXT(""),

WS_POPUP| dwStyle,

CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT,

NULL, (HMENU)NULL, hInstance,

NULL);

// 设置控件的一些初始参数

ti.cbSize = sizeof(TOOLINFO);

ti.uFlags = TTF_IDISHWND | TTF_TRANSPARENT | TTF_TRACK | TTF_ABSOLUTE;//TTF_CENTERTIP

ti.hwnd = hParent;

ti.uId = (UINT)hParent;

ti.hinst = hInstance;

ti.lpszText = const_cast<LPTSTR>(sczTipText);

if(sczTipText != LPSTR_TEXTCALLBACK) {

//以下设定缺省提示文本

if(sczTipText) {//如果当前菜单存在提示文本,则将其存放到m_szDefault

_tcscpy(m_szDefault, sczTipText);

}

else {//如果不存在提示文本,则显示以下字符串

_tcscpy(m_szDefault, _T("No Text associated"));

}

}

ti.rect.left = ti.rect.top = ti.rect.bottom = ti.rect.right = 0;

//把提示添加到控件中

::SendMessage(m_hToolTip,TTM_ADDTOOL,0,(LPARAM)&ti);

::SendMessage(m_hToolTip, TTM_SETMAXTIPWIDTH, 0, 300);

if(sczTipTitle) {

::SendMessage(m_hToolTip, TTM_SETTITLE, 1, (LPARAM)sczTipTitle);

}

}

inline //以下内联函数设定在选定菜单时所做的操作

void CMenuToolTip::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSubMenu)

{

if(nFlags & MF_POPUP

|| (nFlags == 0xFFFF && hSubMenu == NULL)) { // 菜单关闭时不出现提示

ShowToolTip(FALSE);

}

if(!(nFlags & MF_POPUP)) {

// 设置提示的位置

SetToolTipPosition(hSubMenu, nItemID);

// 更新提示的文本

TCHAR szBuff[256];//定义一个存放提示文本的字符数组

szBuff[0] = 0;

//将指定的提示文本存放到预先设定的缓冲区中

int nRet = ::LoadString(m_hInstance, nItemID, szBuff, 256);

#if 0

for(int i = 0; i < nRet; i++)

{

if(szBuff[i] == _T('\n'))

{

szBuff[i] = 0;

break;

}

}

#endif

//以下部分主要用于更新提示文本,否则文本是固定的

if(szBuff[0] != 0) {

UpdateToolTipText(szBuff);

}

else {

UpdateToolTipText(m_szDefault);

}

ShowToolTip(TRUE);//设定需要显示提示

}

}

#endif _MENU_TOOLTIP

上面的注释写的比较详细了,您可以在相应的地方做修改,以更改提示的位置和内容,将上面的代码存为一个名为menutooltip.h的头文件,将其加入到您的工程当中,然后在需要处理提示信息的类的初始函数(如对话框的OnInitDialog函数或者是类的构造函数)中添加如下语句:

myMenuToolTip.Create(m_hWnd, _T("Sample Menu Text"), AfxGetResourceHandle()

,TTS_NOPREFIX | TTS_BALLOON

, _T("My Best Tool Tip Title")

);

同时在相应的类中创建OnMenuSelect函数如下:

void CMenuItemToolTipDlg::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSubMenu)

{

myMenuToolTip.OnMenuSelect(nItemID, nFlags, hSubMenu);

CWnd::OnMenuSelect(nItemID, nFlags, hSubMenu);

}

同时不要忘了加入上述头文件,并定义一个提示信息类的变量

#include "MenuToolTip.h"

CMenuToolTip myMenuToolTip;

最后在消息循环中加入ON_WM_MENUSELECT()

一切ok了。

Ps:在这里显示的提示信息都是您在定义菜单资源时设定的,也就是在定义一个菜单项时,右键选定属性,在general中有一个prompt文本框,用于设定提示文本,如果文本过长,可以在其中加上“\r\n”进行换行。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有