当鼠标不在标题栏上时,隐藏表单的客户区(但让标题栏可见)

我正在寻找一种方法来开发它:

Heberger图片http://sofzh.miximages.com/c%23/mini_350415Explications.png

当鼠标位于表单的标题栏(图片上的rectange 1)上时,表单内容(矩形2)可见,当鼠标未结束时,它会消失,但矩形1必须保持可见!

我怎么能设法做到这一点?

提前致谢

有一些鼠标事件与表格的非客户区域( WM_NCMOUSEMOVEWM_NCMOUSELEAVE ,…)相关,可用于此目的。 但这并不简单,因为它们不包含在Windows窗体中。 要使用此事件,您应该覆盖表单的WndProc 。 捕获WM_NCMOUSEMOVE事件有点简单,但WM_NCMOSUELEAVE有点棘手。 Windows通常不向鼠标发送鼠标离开事件,除非他们使用TrackMouseEvent函数明确请求它。

以下是完全符合您要求的完整代码:

  protected override void WndProc(ref Message m) { if (m.Msg == 0xA0) // WM_NCMOUSEMOVE { TrackNcMouseLeave(this); ShowClientArea(); } else if (m.Msg == 0x2A2) // WM_NCMOUSELEAVE { HideClientAreaIfPointerIsOut(); } base.WndProc(ref m); } protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); HideClientAreaIfPointerIsOut(); } private int previouseHeight; private void ShowClientArea() { if (this.ClientSize.Height == 0) this.ClientSize = new Size(this.ClientSize.Width, previouseHeight); } private void HideClientAreaIfPointerIsOut() { if (this.Bounds.Contains(Cursor.Position)) return; previouseHeight = this.ClientSize.Height; this.ClientSize = new Size(this.ClientSize.Width, 0); } public static void TrackNcMouseLeave(Control control) { TRACKMOUSEEVENT tme = new TRACKMOUSEEVENT(); tme.cbSize = (uint)Marshal.SizeOf(tme); tme.dwFlags = 2 | 0x10; // TME_LEAVE | TME_NONCLIENT tme.hwndTrack = control.Handle; TrackMouseEvent(tme); } [DllImport("user32")] public static extern bool TrackMouseEvent([In, Out] TRACKMOUSEEVENT lpEventTrack); [StructLayout(LayoutKind.Sequential)] public class TRACKMOUSEEVENT { public uint cbSize; public uint dwFlags; public IntPtr hwndTrack; public uint dwHoverTime; } 

将此代码部分放在表单类中,并处理所有内容。

通过重写WndProc我们正在处理所需的鼠标事件。 在WM_NCMOUSEMOVE事件中,我们调用一个方法来通知操作系统我们对WM_NCMOUSELEAVE事件感兴趣,并且我们还显示了表单的客户区域(如果不可见)。
WM_NCMOUSELEAVE事件中,我们隐藏表单的客户区(如果光标不在表单上)。 每次调用WM_NCMOUSELEAVE事件时, TrackMouseEvent请求的所有跟踪事件都将被取消,因此我们必须每次在WM_NCMOUSEMOVE调用TrackMouseEvent函数。

请注意,在此代码中不考虑最大化表单,您应该以某种方式处理它。

我建议您创建一个无边框表单,并使用停靠在顶部的自定义控件作为标题栏。 然后就像在MouseEnter和MouseLeave事件上更改表单的高度一样简单!

希望有所帮助!

知道你的Form BorderStyle设置为None,你可以根据鼠标的位置和矩形的大小来开发一些东西,所以你必须使用MouseEnter和MouseLeave事件作为所谓的Digvijay

这是我的示例代码:

  private void Rectangle1_MouseEnter(object sender, EventArgs e) { myForm.Height = Rectangle1.Height + Rectangle2.Height; } private void Rectangle1_MouseLeave(object sender, EventArgs e) { if (!myForm.Bounds.Contains(MousePosition)) { myForm.Height = Rectangle1.Height; } }