处理表单标题栏上的鼠标悬停 - 在工具提示中显示最小化 MDI 的标题 Child
Handle Mouse Hover on Titlebar of Form - Show Title of a Minimized MDI Child in ToolTip
我正在寻找类似 WM_NCMOUSEMOVE
的消息,表示鼠标悬停在表单的标题栏上。
目前我已经将此代码放入 child 表单中,但问题是它们有很多 child 表单,而且它不处理标题栏上的鼠标悬停:
Private Const WM_NCMOUSEMOVE = &HA0
Dim stado_min As Boolean
Protected Overrides Sub DefWndProc(ByRef m As System.Windows.Forms.Message)
If stado_min AndAlso CLng(m.Msg) = WM_NCMOUSEMOVE Then
form_principal.ToolTipTitulo.SetToolTip(Me, Label1.Text)
End If
MyBase.DefWndProc(m)
End Sub
Private Sub schanged() Handles MyBase.SizeChanged
stado_min = (Me.WindowState = FormWindowState.Minimized)
End Sub
事实上,我正在寻找一种解决方案,当鼠标悬停在最小化的 MDI child 上时,在工具提示中显示 MDI child 的标题。我该怎么做?
要处理鼠标悬停在 non-client 区域上,您可以捕获 WM_NCMOUSEHOVER
in WndProc
。
如文档中所述,当生成此消息时,悬停跟踪将停止。如果应用程序需要进一步跟踪鼠标悬停行为,则必须再次调用 TrackMouseEvent
。
NonClientMouseHover 事件实现
在下面的代码中,通过捕获 WM_NCMOUSEHOVER
引发了 NonClientMouseHover
。您可以像处理任何其他形式的事件一样处理 NonClientMouseHover
事件:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class SampleForm : Form
{
[DllImport("user32.dll")]
private static extern int TrackMouseEvent(ref TRACK_MOUSE_EVENT lpEventTrack);
[StructLayout(LayoutKind.Sequential)]
private struct TRACK_MOUSE_EVENT {
public uint cbSize;
public uint dwFlags;
public IntPtr hwndTrack;
public uint dwHoverTime;
public static readonly TRACK_MOUSE_EVENT Empty;
}
private TRACK_MOUSE_EVENT track = TRACK_MOUSE_EVENT.Empty;
const int WM_NCMOUSEMOVE = 0xA0;
const int WM_NCMOUSEHOVER = 0x2A0;
const int TME_HOVER = 0x1;
const int TME_NONCLIENT = 0x10;
public event EventHandler NonClientMouseHover;
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_NONCLIENT;
track.dwHoverTime = 500;
TrackMouseEvent(ref track);
}
if (m.Msg == WM_NCMOUSEHOVER) {
var handler = NonClientMouseHover;
if (handler != null)
NonClientMouseHover(this, EventArgs.Empty);
}
}
}
例子
根据您的问题,您似乎对最小化 mdi child window 的事件感兴趣。该事件还会针对最小化的 mdi child 表单引发,因此如果出于任何原因您想在鼠标悬停在最小化的 mdi child 的标题栏上时执行某些操作,您可以检查 if(((Form)sender).WindowState== FormWindowState.Minimized)
。另外 ((Form)sender).Text
是引发事件的表单的文本。
public partial class Form1 : Form
{
ToolTip toolTip1 = new ToolTip();
public Form1()
{
//InitializeComponent();
this.Text = "Form1";
this.IsMdiContainer = true;
var f1 = new SampleForm() { Text = "Some Form", MdiParent = this };
f1.NonClientMouseHover += child_NonClientMouseHover;
f1.Show();
var f2 = new SampleForm() { Text = "Some Other Form", MdiParent = this };
f2.NonClientMouseHover += child_NonClientMouseHover;
f2.Show();
}
void child_NonClientMouseHover(object sender, EventArgs e)
{
var f = (Form)sender;
var p = f.PointToClient(f.Parent.PointToScreen(f.Location));
p.Offset(0, -24);
toolTip1.Show(f.Text, f, p, 2000);
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
toolTip1.Dispose();
base.OnFormClosed(e);
}
}
注:感谢Bob for his post here。用于处理 WM_NCMOUSEHOVER
的初始代码取自那里并进行了一些更改并删除了一些部分。
我正在寻找类似 WM_NCMOUSEMOVE
的消息,表示鼠标悬停在表单的标题栏上。
目前我已经将此代码放入 child 表单中,但问题是它们有很多 child 表单,而且它不处理标题栏上的鼠标悬停:
Private Const WM_NCMOUSEMOVE = &HA0
Dim stado_min As Boolean
Protected Overrides Sub DefWndProc(ByRef m As System.Windows.Forms.Message)
If stado_min AndAlso CLng(m.Msg) = WM_NCMOUSEMOVE Then
form_principal.ToolTipTitulo.SetToolTip(Me, Label1.Text)
End If
MyBase.DefWndProc(m)
End Sub
Private Sub schanged() Handles MyBase.SizeChanged
stado_min = (Me.WindowState = FormWindowState.Minimized)
End Sub
事实上,我正在寻找一种解决方案,当鼠标悬停在最小化的 MDI child 上时,在工具提示中显示 MDI child 的标题。我该怎么做?
要处理鼠标悬停在 non-client 区域上,您可以捕获 WM_NCMOUSEHOVER
in WndProc
。
如文档中所述,当生成此消息时,悬停跟踪将停止。如果应用程序需要进一步跟踪鼠标悬停行为,则必须再次调用 TrackMouseEvent
。
NonClientMouseHover 事件实现
在下面的代码中,通过捕获 WM_NCMOUSEHOVER
引发了 NonClientMouseHover
。您可以像处理任何其他形式的事件一样处理 NonClientMouseHover
事件:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class SampleForm : Form
{
[DllImport("user32.dll")]
private static extern int TrackMouseEvent(ref TRACK_MOUSE_EVENT lpEventTrack);
[StructLayout(LayoutKind.Sequential)]
private struct TRACK_MOUSE_EVENT {
public uint cbSize;
public uint dwFlags;
public IntPtr hwndTrack;
public uint dwHoverTime;
public static readonly TRACK_MOUSE_EVENT Empty;
}
private TRACK_MOUSE_EVENT track = TRACK_MOUSE_EVENT.Empty;
const int WM_NCMOUSEMOVE = 0xA0;
const int WM_NCMOUSEHOVER = 0x2A0;
const int TME_HOVER = 0x1;
const int TME_NONCLIENT = 0x10;
public event EventHandler NonClientMouseHover;
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_NONCLIENT;
track.dwHoverTime = 500;
TrackMouseEvent(ref track);
}
if (m.Msg == WM_NCMOUSEHOVER) {
var handler = NonClientMouseHover;
if (handler != null)
NonClientMouseHover(this, EventArgs.Empty);
}
}
}
例子
根据您的问题,您似乎对最小化 mdi child window 的事件感兴趣。该事件还会针对最小化的 mdi child 表单引发,因此如果出于任何原因您想在鼠标悬停在最小化的 mdi child 的标题栏上时执行某些操作,您可以检查 if(((Form)sender).WindowState== FormWindowState.Minimized)
。另外 ((Form)sender).Text
是引发事件的表单的文本。
public partial class Form1 : Form
{
ToolTip toolTip1 = new ToolTip();
public Form1()
{
//InitializeComponent();
this.Text = "Form1";
this.IsMdiContainer = true;
var f1 = new SampleForm() { Text = "Some Form", MdiParent = this };
f1.NonClientMouseHover += child_NonClientMouseHover;
f1.Show();
var f2 = new SampleForm() { Text = "Some Other Form", MdiParent = this };
f2.NonClientMouseHover += child_NonClientMouseHover;
f2.Show();
}
void child_NonClientMouseHover(object sender, EventArgs e)
{
var f = (Form)sender;
var p = f.PointToClient(f.Parent.PointToScreen(f.Location));
p.Offset(0, -24);
toolTip1.Show(f.Text, f, p, 2000);
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
toolTip1.Dispose();
base.OnFormClosed(e);
}
}
注:感谢Bob for his post here。用于处理 WM_NCMOUSEHOVER
的初始代码取自那里并进行了一些更改并删除了一些部分。