如何使用窗体边框上的控件调整无边框窗体大小?

时间:2015-07-11 03:45:18

标签: c# window window-resize borderless

我有一个无边框的winForm,我需要调整大小,我设法这样做:

protected override void WndProc(ref Message m)
    {
        const int wmNcHitTest = 0x84;
        const int htLeft = 10;
        const int htRight = 11;
        const int htTop = 12;
        const int htTopLeft = 13;
        const int htTopRight = 14;
        const int htBottom = 15;
        const int htBottomLeft = 16;
        const int htBottomRight = 17;

        if (m.Msg == wmNcHitTest)
        {
            Console.Write(true + "\n");
            int x = (int)(m.LParam.ToInt64() & 0xFFFF);
            int y = (int)((m.LParam.ToInt64() & 0xFFFF0000) >> 16);
            Point pt = PointToClient(new Point(x, y));
            Size clientSize = ClientSize;
            ///allow resize on the lower right corner
            if (pt.X >= clientSize.Width - 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
            {
                m.Result = (IntPtr)(IsMirrored ? htBottomLeft : htBottomRight);
                return;
            }
            ///allow resize on the lower left corner
            if (pt.X <= 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
            {
                m.Result = (IntPtr)(IsMirrored ? htBottomRight : htBottomLeft);
                return;
            }
            ///allow resize on the upper right corner
            if (pt.X <= 16 && pt.Y <= 16 && clientSize.Height >= 16)
            {
                m.Result = (IntPtr)(IsMirrored ? htTopRight : htTopLeft);
                return;
            }
            ///allow resize on the upper left corner
            if (pt.X >= clientSize.Width - 16 && pt.Y <= 16 && clientSize.Height >= 16)
            {
                m.Result = (IntPtr)(IsMirrored ? htTopLeft : htTopRight);
                return;
            }
            ///allow resize on the top border
            if (pt.Y <= 16 && clientSize.Height >= 16)
            {
                m.Result = (IntPtr)(htTop);
                return;
            }
            ///allow resize on the bottom border
            if (pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
            {
                m.Result = (IntPtr)(htBottom);
                return;
            }
            ///allow resize on the left border
            if (pt.X <= 16 && clientSize.Height >= 16)
            {
                m.Result = (IntPtr)(htLeft);
                return;
            }
            ///allow resize on the right border
            if (pt.X >= clientSize.Width - 16 && clientSize.Height >= 16)
            {
                m.Result = (IntPtr)(htRight);
                return;
            }
        }
        else
        {
            Console.Write(false + "\n");
        }
        base.WndProc(ref m);
    }

问题是我的表单的左边框和右边框有控件,因此上面代码中使用的调整大小覆盖不适用于有任何类型控件的区域。

以下是一个例子:

Resize problem

在上图中,您可以看到标记区域内的标签位于表单的左边框,不会让我调整大小。

有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:3)

这里的问题是它是Label控件获取鼠标通知,而不是无边框形式。到目前为止,解决此问题的最佳方法是使标签对鼠标透明。你已经知道如何做到这一点,WM_NCHITTEST也允许返回HTTRANSPARENT。 Windows一直在寻找通知的下一个候选者,它将是标签的父级。

标签特别容易,因为您通常根本不会使用鼠标事件:

frmContact

适用于任何Control类,如果它是一个按钮,你会想要更有选择性。可能是你需要的一切,但是如果你有很多不同类型的控制靠近边缘,那么仍然很尴尬。您可以使用的另一种技术在本机Windows编程中称为“子类”。通常在Winforms中用于为本机Windows控件创建包装.NET类。它在这里也运行良好,您可以查看任何控件的消息并以这种方式拦截WM_NCHITTEST:

document.getElementById("frmContact").addEventListener("submit", function(event) {
    if (document.getElementById("email").value == "Your Email") {
        // Show message
        event.preventDefault(); // Prevent form from submitting
    }
});

只需为靠近窗口边缘的每个控件创建一个MouseFilter实例:

using System;
using System.Windows.Forms;

public class LabelEx : Label {
    protected override void WndProc(ref Message m) {
        const int wmNcHitTest = 0x84;
        const int htTransparent = -1;
        if (!DesignMode && m.Msg == wmNcHitTest) m.Result = new IntPtr(htTransparent);
        else base.WndProc(ref m);
    }
}