C# 可以向表单标题添加工具提示
在窗体上,窗体的标题是在设计器文件中设置的文本。我遇到的问题是,当标题国际化时,标题会被缩短并添加省略号。是否可以添加一个工具提示,当我们将鼠标悬停在标题上时将显示该提示?因此,如果我将鼠标悬停在“Form1”上,就会显示一个工具提示,上面写着“Form1” 表格是用C写的。由于标题不是表单中的控件,因此无法设置工具提示 有什么想法吗C# 可以向表单标题添加工具提示,c#,.net,winforms,tooltip,titlebar,C#,.net,Winforms,Tooltip,Titlebar,在窗体上,窗体的标题是在设计器文件中设置的文本。我遇到的问题是,当标题国际化时,标题会被缩短并添加省略号。是否可以添加一个工具提示,当我们将鼠标悬停在标题上时将显示该提示?因此,如果我将鼠标悬停在“Form1”上,就会显示一个工具提示,上面写着“Form1” 表格是用C写的。由于标题不是表单中的控件,因此无法设置工具提示 有什么想法吗 一种方法是: using System.Drawing; using System.Threading.Tasks; public Form1() {
一种方法是:
using System.Drawing;
using System.Threading.Tasks;
public Form1()
{
InitializeComponent();
ImplementToolBarToolTip();
}
private readonly ToolTip _toolTip1 = new ToolTip();
private async void ImplementToolBarToolTip()
{
while (!IsDisposed)
{
await Task.Delay(200);
var right = Left + Width;
var bottom = Top + 39;
var x = Cursor.Position.X;
var y = Cursor.Position.Y;
if (IsDisposed) return;
if (x > Left && x < right && y > Top && y < bottom)
{
_toolTip1.Show(Text, this, PointToClient(new Point(x, y)));
}
else _toolTip1.Hide(this);
}
}
另外,有关处理MDI子窗体相关问题的更复杂方法,请参阅Reza Aghaei的帖子,他现在也用重构实现回答了这个问题。我已经在中分享了一个示例,演示了如何为窗体的非客户端区域引发悬停事件,包括标题栏并显示标题栏的工具提示 在本文中,我将通过添加对以下事件和属性的支持来重构和扩展另一个答案:
- 当鼠标悬停在非客户端区域上时,NonClientMouseHover将引发
- NonClientMouseLeave:当鼠标离开非客户端区域时引发
- 标题栏的矩形,不包括系统菜单
BaseForm
类驱动的表单上使用工具提示组件,并处理nonclientmousehave
和nonclientmousehave
,可以轻松实现:
public partial class SampleForm : BaseForm
{
public SampleForm()
{
InitializeComponent();
}
private void SampleForm_NonClientMouseHover(object sender, EventArgs e)
{
if (TitleRectangle.Contains(Cursor.Position))
toolTip1.Show(Text, this, TitleRectangle.Left - this.Left + 1,
TitleRectangle.Top - this.Top - 2, 5000);
}
private void SampleForm_NonClientMouseLeave(object sender, EventArgs e)
{
if (!TitleRectangle.Contains(Cursor.Position))
toolTip1.Hide(this);
}
}
下面是本机方法和基类
本机方法
这些是基类中用于处理非客户端区域消息的本机方法:
using System;
using System.Drawing;
using System.Runtime.InteropServices;
public static class NativeMethods
{
public const int WM_NCMOUSEMOVE = 0xA0;
public const int WM_NCMOUSEHOVER = 0x2A0;
public const int WM_NCMOUSELEAVE = 0x2A2;
public const int TME_HOVER = 0x1;
public const int TME_LEAVE = 0x2;
public const int TME_NONCLIENT = 0x10;
[DllImport("user32.dll")]
public static extern int TrackMouseEvent(ref TRACK_MOUSE_EVENT lpEventTrack);
[DllImport("user32.dll")]
public static extern bool GetTitleBarInfo(IntPtr hwnd, ref TITLEBARINFO pti);
public static Rectangle GetTitleBarRectangle(IntPtr hwnd)
{
var info = new TITLEBARINFO()
{ cbSize = (uint)Marshal.SizeOf(typeof(TITLEBARINFO)) };
GetTitleBarInfo(hwnd, ref info);
return info.rcTitleBar.ToRectangle();
}
[StructLayout(LayoutKind.Sequential)]
public struct TRACK_MOUSE_EVENT
{
public uint cbSize;
public uint dwFlags;
public IntPtr hwndTrack;
public uint dwHoverTime;
public static readonly TRACK_MOUSE_EVENT Empty;
}
[StructLayout(LayoutKind.Sequential)]
public struct TITLEBARINFO
{
public const int CCHILDREN_TITLEBAR = 5;
public uint cbSize;
public RECT rcTitleBar;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = CCHILDREN_TITLEBAR + 1)]
public uint[] rgstate;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left, Top, Right, Bottom;
public Rectangle ToRectangle() => Rectangle.FromLTRB(Left, Top, Right, Bottom);
}
}
基本形式
这是一个引发非客户端区域事件的基本表单类:
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using static NativeMethods;
public class BaseForm : Form
{
public event EventHandler NonClientMouseHover;
public event EventHandler NonClientMouseLeave;
public event EventHandler NonClientMouseMove;
private TRACK_MOUSE_EVENT track = TRACK_MOUSE_EVENT.Empty;
public Rectangle TitleRectangle => GetTitleBarRectangle(Handle);
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_NCMOUSEMOVE)
{
track.hwndTrack = this.Handle;
track.cbSize = (uint)Marshal.SizeOf(track);
track.dwFlags = TME_HOVER | TME_LEAVE | TME_NONCLIENT;
track.dwHoverTime = 500;
TrackMouseEvent(ref track);
NonClientMouseMove?.Invoke(this, EventArgs.Empty);
}
else if (m.Msg == WM_NCMOUSEHOVER)
{
NonClientMouseHover?.Invoke(this, EventArgs.Empty);
}
else if (m.Msg == WM_NCMOUSELEAVE)
{
NonClientMouseLeave?.Invoke(this, EventArgs.Empty);
}
}
}
这篇文章回答了你的问题吗?你可能想学习如何投票和接受答案。
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using static NativeMethods;
public class BaseForm : Form
{
public event EventHandler NonClientMouseHover;
public event EventHandler NonClientMouseLeave;
public event EventHandler NonClientMouseMove;
private TRACK_MOUSE_EVENT track = TRACK_MOUSE_EVENT.Empty;
public Rectangle TitleRectangle => GetTitleBarRectangle(Handle);
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_NCMOUSEMOVE)
{
track.hwndTrack = this.Handle;
track.cbSize = (uint)Marshal.SizeOf(track);
track.dwFlags = TME_HOVER | TME_LEAVE | TME_NONCLIENT;
track.dwHoverTime = 500;
TrackMouseEvent(ref track);
NonClientMouseMove?.Invoke(this, EventArgs.Empty);
}
else if (m.Msg == WM_NCMOUSEHOVER)
{
NonClientMouseHover?.Invoke(this, EventArgs.Empty);
}
else if (m.Msg == WM_NCMOUSELEAVE)
{
NonClientMouseLeave?.Invoke(this, EventArgs.Empty);
}
}
}