问题描述
我正在寻找一种方式来开发这样的:
I'm looking for a way to develop this:
的
当鼠标在窗体的标题栏(在图片上rectange 1)形式的内容(矩形2)是可见的放大器;当鼠标还没有结束,它就会消失,但矩形1必须保持可见!
When the mouse is over the form's title bar (rectange 1 on the picture) the form content (the rectangle 2) is visible & when the mouse is not over, it disappears but the rectangle 1 must remain visible!
我怎么能设法做到的?
在此先感谢
推荐答案
有相关的形式非客户区(有些鼠标事件 WM_NCMOUSEMOVE
, WM_NCMOUSELEAVE
,...),可用于这一目的。但是,这并不简单,因为他们没有在Windows窗体包括在内。要使用此活动,您应该重写的WndProc
的形式。醒目 WM_NCMOUSEMOVE
事件是有点简单,但 WM_NCMOSUELEAVE
是有点棘手。 Windows是否正常不发送鼠标离开事件窗口,除非他们提出要求明确使用 TrackMouseEvent
功能。
There are some mouse events related to the non-client area of the forms (WM_NCMOUSEMOVE
, WM_NCMOUSELEAVE
, ...) that can be used for this purpose. But this is not simple, because they are not included in Windows Forms. To use this events, you should override WndProc
of your form. Catching WM_NCMOUSEMOVE
event is somehow simple, but WM_NCMOSUELEAVE
is a little tricky. Windows normally does not send mouse leave events to windows, unless they request it explicitly using TrackMouseEvent
function.
下面是完整的代码,不正是你想要什么:
Here is the complete code that does exactly what you want:
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;
}
把你的窗体类的代码部分,而完成所有的操作。
Put this code section in your form class, and that takes care of everything.
通过覆盖的WndProc
我们正在处理需要鼠标事件。在 WM_NCMOUSEMOVE
事件中,我们调用一个方法来告知操作系统,我们感兴趣的是 WM_NCMOUSELEAVE
事件,我们也显示窗体的客户区域(如果不可见)。结果
在 WM_NCMOUSELEAVE
事件,我们隐藏了窗体的客户区域(如果光标不在在窗体上)。每次 WM_NCMOUSELEAVE
事件被称为,由 TrackMouseEvent
要求所有跟踪事件都取消了,所以我们必须调用 TrackMouseEvent
功能 WM_NCMOUSEMOVE
每次
By overriding WndProc
we are handling required mouse events. In WM_NCMOUSEMOVE
event, we call a method to inform the operating system that we are interested in WM_NCMOUSELEAVE
event, and also we show the client area of the form (if not visible).
In WM_NCMOUSELEAVE
event we hide the client area of the form (if the cursor is not on the form). Every time the WM_NCMOUSELEAVE
event is called, all tracking events requested by TrackMouseEvent
are canceled, so we must call the TrackMouseEvent
function every time in WM_NCMOUSEMOVE
.
请注意,最大化形式是不是在这个代码考虑,你应该以某种方式处理它。
Be aware that maximizing the form is not considered in this code and you should handle it somehow.
这篇关于隐藏窗体的客户区(但让标题栏是可见的),当鼠标不在标题栏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!