ToolTip在Windows中是一个常用的显示信息的手段。当ToolTip的信息很长的时候,我们最好能够显示为多行。也就是当ToolTip的信息的长度超过某一阈值的时候,最好显示为多行。Windows是提供了这样的API。非常遗憾的是,Winforms到目前为止暂时还不支持多行的ToolTip。如何在Winforms中设置ToolTip的最大长度,是Winforms程序员经常问到的一个问题。
Windows是通过发送TTM_SETMAXTIPWIDTH消息来设置ToolTip的最大长度的。因此,我们在Winforms中可以先得到一个ToolTip的句柄,然后向该句柄发送消息。这里我们需要做两件事:
1. 得到ToolTip的句柄。由于Handle是ToolTip的一个internal属性,在ToolTip的外部不能直接得到。好在.Net提供了反射机制,我们可以用反射来得到一个ToolTip的句柄。
2. 给ToolTip发送消息。Winforms没有直接提供发送消息的方法,因此我们必须通过P/Invoke调用Windows API SendMessage。
做好了这两方面的准备,我们就可以写出如下的代码:
internal class Utility
{
private const int TTM_SETMAXTIPWIDTH = (0x400 + 24);
[DllImport("User32.dll")]
private static extern IntPtr SendMessage(HandleRef hwd,
int msg,
int wParam,
int lParam);
// Handle is an internal property of ToolTip,
// so we need reflection to get a toolTip's Handle
private static IntPtr GetToolTipHandle(ToolTip toolTip)
{
Type type = typeof(ToolTip);
BindingFlags flags = BindingFlags.GetProperty
| BindingFlags.NonPublic
| BindingFlags.Instance;
Object obj = type.InvokeMember("Handle", flags, null, toolTip, null);
if ((IntPtr)obj == null)
throw new InvalidProgramException();
return (IntPtr)obj;
}
// send a TTM_SETMAXTIPWIDTH message to a toolTip,
// to set its maximum length
public static void SetToolTipMaxLength(ToolTip toolTip, int maxLength)
{
IntPtr toolTipHandle;
toolTipHandle = GetToolTipHandle(toolTip);
Utility.SendMessage(new HandleRef(toolTip, toolTipHandle),
TTM_SETMAXTIPWIDTH,
0,
maxLength);
}
}
接下来我们创建一个Winforms项目来验证我们的办法是不是有效,步骤如下:
1. 创建一个新Winforms项目;
2. 为Form1添加一个按钮,button1,和一个ToolTip,toolTip1;
3. 打开属性窗口;
4. 选择button1,为属性ToolTop on toolTip1设置一个比较长的字符串;
5. 在属性窗口选择事件页面,为button1添加MouseEnter事件处理器;
6. 编辑Button1_MouseEnter的代码如下:
const int maxLength = 200;
private void button1_MouseEnter(object sender, EventArgs e)
{
Utility.SetToolTipMaxLength(toolTip1, maxLength);
}
7. 编译并运行;
8. 把鼠标停在button1上,我们发现很长的ToolTip已经显示为多行,如下面的截图所示: