又是许久没有做程序员了,一个同事突然提了需求,感觉难度不大,就又又又打开我的VC6.0,工作。
一、常规的ToolTips
本节内容摘抄自这里,有改动
1、先保证你的控件有个独立的ID,比如static都是公用的ID,所以若是想为static设置ToolTips,请先设置一个独立ID,如ID_TIP;
2、在头文件中的AFX_MSG内加入一行申明,这里看需要在哪个窗口了,原文是CDialogBar,而我的是CDialog
afx_msg BOOL OnToolTip(UINT id, NMHDR* pNMHDR, LRESULT* pResult);
3、在CPP文件中的AFX_MSG_MAP内加入一行:
ON_NOTIFY_EX(TTN_NEEDTEXT,0,OnToolTip)
4、在CPP文件中的OnInitDialog()函数内加入: 很重要,我就老遗忘
EnableToolTips(TRUE);
5、在CPP文件中添加OnToolTip函数实现:
BOOL CDialogBar::OnToolTip(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pNMHDR;
UINT_PTR uID = pNMHDR->idFrom;
if(pTTT->uFlags & TTF_IDISHWND)
{
uID = ::GetDlgCtrlID((HWND)uID);
}
if (NULL == uID) { return FALSE; }
switch (uID)
{
case IDC_TIP:
pTTT->lpszText="添加你的提示内容";
break;
}
return TRUE;
}
当你写了一个超长的ToolTips,你会发现,他是单行的,比如
pTTT->lpszText= "%a:周的英文缩写形式。\n"
"%A:周的英文全名形式。\n"
"%b: 月的英文缩写形式。\n"
"%B:月的英文全名形式。\n"
"%c: 完整的日期和时间。\n"
"%d:十进制形式的日期(01-31)。\n"
"%H:24小时制的小时(00-23)。\n"
"%I: 12小时制的小时(00-11)。\n"
"%j: 十进制表示的一年中的第几天(001-366)。\n"
"%m: 月的十进制表示(01-12)。\n"
"%M:十进制表示的分钟(00-59)。\n"
"%p: 12小时制的上下午标示(AM/PM)。\n"
"%S: 十进制表示的秒(00-59)。\n"
"%U: 一年中的第几个星期(00-51),星期日是一周的第一天。\n"
"%W: 一年中的第几个星期(00-51),星期一是一周的第一天。\n"
"%w: 十进制表示的星期几(0-6)。\n"
"%Y: 十进制表示的年。";
虽然我加了 “\n",但是它不换行,怎么办?
二、网上的解决方案
其实CSDN上有了很多解决方案,有很多现成的代码下载,也有自己创建CToolTips实现的,但都没有简单的对上面方法的描述,或许在下载的代码里面有,但没有直接的文章描述。
在这篇文章里,描述了两个细节,两种方法
- 需要先设置一下ToolTips的显示宽度
m_tip.SetMaxTipWidth(100);//先设个最长显示长度.
m_tip.UpdateTipText("双击查看明细\n\r回车选中记录",pSub[0]);
- 可以在TTN_GETDISPINFO消息中发送TTM_SETMAXTIPWIDTH消息
switch (lpnmhdr->code) {
case TTN_GETDISPINFO:
lpttd = (LPNMTTDISPINFO)lpnmhdr;
SendMessage(lpnmhdr->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 300);
lpttd->lpszText = szLongMessage;
return 0;
其核心都是需要设置一下显示长度,然后就可以通过换行符“\n”来换行了。而且设置一次就可以了。
三、遗憾
通过发消息可能是处理的简单方法,但何时,在哪段代码中发送很关键。我原先设想是在OnInitDialog()函数中发送就可以了,但可惜 lpnmhdr->hwndFrom 这个玩意,我找了半天,没找到。 就知道是 “tooltips_class32”类,它的父窗口是我的CDialog对象的窗口。但尝试几回都失败了。
后来想想,还要添加好几行的代码,还不如直接发送消息得了,就是看起来比较LOW,哪位高人给我解解惑,不胜感激。
四、最终我的方法
有点强迫症,我一定要只发送一次,其实应该没那么关键,如果简单化,其实添加一行代码就变为多行提示了。当然以下是按我的想法实现的。参考第一段的代码做如下修改。
2、在头文件中的除了AFX_MSG内加入一行申明,另外增加一个变量,用来确认是否发送过消息,
//}}AFX_MSG
afx_msg BOOL OnToolTip(UINT id, NMHDR* pNMHDR, LRESULT* pResult);
DECLARE_MESSAGE_MAP()
BOOL m_bSetWindth; // 通过设置宽度,支持多行显示,(\n换行)
4、在CPP文件中的OnInitDialog()函数内加入tooltips的允许函数,及变量的初始化
m_bSetWindth = false;
EnableToolTips(TRUE);
5、在CPP文件中添加OnToolTip函数实现及消息的发送:
BOOL CDialogBar::OnToolTip(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pNMHDR;
UINT_PTR uID = pNMHDR->idFrom;
if(pTTT->uFlags & TTF_IDISHWND)
{
uID = ::GetDlgCtrlID((HWND)uID);
}
if (NULL == uID) { return FALSE; }
// 设置宽度,变为多行显示
if (!m_bSetWindth)
{
::SendMessage(pNMHDR->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 500);
m_bSetWindth = true;
}
switch (uID)
{
case IDC_TIP:
pTTT->lpszText= "%a:周的英文缩写形式。\n"
"%A:周的英文全名形式。\n"
"%b: 月的英文缩写形式。\n"
"%B:月的英文全名形式。\n"
"%c: 完整的日期和时间。\n"
"%d:十进制形式的日期(01-31)。\n"
"%H:24小时制的小时(00-23)。\n"
"%I: 12小时制的小时(00-11)。\n"
"%j: 十进制表示的一年中的第几天(001-366)。\n"
"%m: 月的十进制表示(01-12)。\n"
"%M:十进制表示的分钟(00-59)。\n"
"%p: 12小时制的上下午标示(AM/PM)。\n"
"%S: 十进制表示的秒(00-59)。\n"
"%U: 一年中的第几个星期(00-51),星期日是一周的第一天。\n"
"%W: 一年中的第几个星期(00-51),星期一是一周的第一天。\n"
"%w: 十进制表示的星期几(0-6)。\n"
"%Y: 十进制表示的年。";
break;
}
return TRUE;
}