Скрытие клиентской области формы (но пусть строка заголовка будет видимой), когда мышь не находится над строкой заголовка - PullRequest
1 голос
/ 20 февраля 2012

Я ищу способ разработать это:

Изображение Хебергера http://img11.hostingpics.net/thumbs/mini_350415Explications.png

Когда мышь находится над строкой заголовка формы (прямоугольник 1 на рисунке), содержимое формы(прямоугольник 2) виден, и когда мышь не находится над ним, он исчезает, но прямоугольник 1 должен оставаться видимым!

Как мне это сделать?

Заранее спасибо

Ответы [ 3 ]

1 голос
/ 21 февраля 2012

Существуют некоторые события мыши, связанные с не-клиентской областью форм (WM_NCMOUSEMOVE, WM_NCMOUSELEAVE, ...), которые можно использовать для этой цели.Но это не просто, потому что они не включены в Windows Forms.Чтобы использовать это событие, вы должны переопределить 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;
    }

Putэтот раздел кода в вашем классе формы, и обо всем позаботится.

Переопределяя WndProc, мы обрабатываем необходимые события мыши.В событии WM_NCMOUSEMOVE мы вызываем метод для информирования операционной системы о том, что нас интересует событие WM_NCMOUSELEAVE, а также показываем клиентскую область формы (если ее не видно).
В событии WM_NCMOUSELEAVE мыскрыть клиентскую область формы (если курсор не находится на форме).Каждый раз, когда вызывается событие WM_NCMOUSELEAVE, все события отслеживания, запрошенные TrackMouseEvent, отменяются, поэтому мы должны вызывать функцию TrackMouseEvent каждый раз в WM_NCMOUSEMOVE.

. Имейте в виду, что максимизация формыне рассматривается в этом коде, и вы должны как-то с этим справиться.

1 голос
/ 20 февраля 2012

Я предлагаю вам создать форму без полей и использовать настраиваемый элемент управления, прикрепленный к вершине, в качестве строки заголовка. Тогда это становится так же просто, как изменение высоты формы в событиях MouseEnter и MouseLeave!

Надеюсь, это поможет!

0 голосов
/ 20 февраля 2012

Зная, что ваш 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;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...