Hide a form's client area (but let the title bar be visible) when mouse is not over the title bar

元气小坏坏 提交于 2019-12-06 14:12:50

问题


I'm looking for a way to develop this:


(source: hostingpics.net)

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!

How could i manage to do that ?

Thanks in advance


回答1:


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.

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.




回答2:


I suggest that you make a borderless form and use a custom control docked to the top as the title bar. Then it becomes as simple as changing the height of the form on MouseEnter and MouseLeave events!

Hope that helps!




回答3:


Knowing that your Form BorderStyle is set on None, you can develop something based on the position of the mouse and the size of your rectangles, so you must use the MouseEnter and MouseLeave event as said Digvijay.

Here is my sample code:

    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;
        }
    }


来源:https://stackoverflow.com/questions/9359484/hide-a-forms-client-area-but-let-the-title-bar-be-visible-when-mouse-is-not-o

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!