C# 调整右下角无边框窗口的大小

C# 调整右下角无边框窗口的大小,c#,winforms,C#,Winforms,我希望用户调整右下角无边框窗口的大小,就像我可以调整combobox控件的自动完成窗口的大小一样 我找不到这样配置窗体的属性 也许有人能帮我解决这个问题 可在此处找到图像: 将面板或其他控件放在角落中,使用面板的MouseDown和MouseMove事件,适当调整窗体大小 在MouseDown中,我会记录坐标,然后在MouseMove中,您可以计算与原始位置的差异以调整表单大小。实现这一点的正确方法是向表单中添加消息处理程序(例如,通过重写)并处理消息。(您可以在上找到该消息的C#定义)特别是,

我希望用户调整右下角无边框窗口的大小,就像我可以调整combobox控件的自动完成窗口的大小一样

我找不到这样配置窗体的属性

也许有人能帮我解决这个问题

可在此处找到图像:


将面板或其他控件放在角落中,使用面板的MouseDown和MouseMove事件,适当调整窗体大小


在MouseDown中,我会记录坐标,然后在MouseMove中,您可以计算与原始位置的差异以调整表单大小。

实现这一点的正确方法是向表单中添加消息处理程序(例如,通过重写)并处理消息。(您可以在上找到该消息的C#定义)特别是,当您收到该消息时,计算命中测试是否针对指定用于调整大小的区域中的某个点,如果是,则返回HTBOTTOMRIGHT。默认窗口进程将为您完成其余的工作,因为它将假定用户已单击窗口边框的右下角,即使您的窗口没有边框

这种方法需要少量的Win32互操作,但它会使您的调整大小看起来与任何其他窗口调整大小完全相同

简单的方法是按照@benPearce所说的做,在角落里放一个面板,并使用宽度/高度调整表单大小。这会起作用,但调整大小不会很顺利,特别是在Vista和Win7 Basic上,在标准移动和调整大小时禁用完全重画,而在每一步都尝试重画

更新:在这两种方法中,您还必须弄清楚如何绘制夹持器。例如,您可以放置标准夹持器的位图。不过,考虑到表单没有标题和边框,所以不一定要使用标准的Windows视觉效果,您可能会选择更时髦的东西

更新2:如果您有一个覆盖整个窗口的控件,它将吃掉表单鼠标消息。您必须以某种方式将要用于调整大小的位置剪裁到该控制之外。您有几个选项来处理此问题:

  • 调整控件大小,为调整大小的夹点留出一些空间
  • 调整控制区域(通过“区域”属性)以排除调整大小夹点
  • 覆盖面板上的调整大小夹点,聆听其MouseEnter消息,并将form Capture属性设置为true,这将导致所有其他鼠标消息转到该面板注意:完成调整大小后,鼠标离开该区域后,您必须释放捕获

  • 我建议选择最简单的选项1。选项3是最复杂的,它需要关于鼠标输入在Windows中如何工作的详细信息,所以我不推荐它。选项2是选项1的一个很好的替代方案,但您必须尝试查看ListView控件对其区域调整的反应。

    以下是与Franci的解释相对应的代码,我正在编写,但他同时回答了,所以请投票支持他的解释,如果这段代码适合您的需要,这是很好的

    protected override void WndProc(ref Message m) {
        const int wmNcHitTest = 0x84;
        const int htBottomLeft = 16;
        const int htBottomRight = 17;
        if (m.Msg == wmNcHitTest) {
            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;
            if (pt.X >= clientSize.Width - 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16) {
                m.Result = (IntPtr) (IsMirrored ? htBottomLeft : htBottomRight);
                return;
            }
        }
        base.WndProc(ref m);
    }
    

    编辑:要编写夹持器,您可以初始化一个新的VisualStyleRenderer(VisualStyleElement.Status.gripper.Normal),并使用它的
    PaintBackground()
    方法。

    非常感谢您发布这个很棒的示例和解释。我在下面添加了一些其他人可能感兴趣的补充内容。这里的一些代码来自其他stackoverflow帖子,但是能够在一个代码块中看到它可能会对其他人有所帮助我希望能够在所有边框上调整窗体的大小,而不仅仅是右下角。我还希望能够拖动表单。最后,我想要一个阴影。

    //***********************************************************
    //This gives us the ability to resize the borderless from any borders instead of just the lower right corner
    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)
        {
            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;
            }
        }
        base.WndProc(ref m);
    }
    //***********************************************************
    //***********************************************************
    //This gives us the ability to drag the borderless form to a new location
    public const int WM_NCLBUTTONDOWN = 0xA1;
    public const int HT_CAPTION = 0x2;
    
    [DllImportAttribute("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
    [DllImportAttribute("user32.dll")]
    public static extern bool ReleaseCapture();
    
    private void YOURCONTROL_MouseDown(object sender, MouseEventArgs e)
    {
        //ctrl-leftclick anywhere on the control to drag the form to a new location 
        if (e.Button == MouseButtons.Left && Control.ModifierKeys == Keys.Control)
        {       
            ReleaseCapture();
            SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
        }  
    }
    //***********************************************************
    //***********************************************************
    //This gives us the drop shadow behind the borderless form
    private const int CS_DROPSHADOW = 0x20000;
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ClassStyle |= CS_DROPSHADOW;
            return cp;
        }
    }
    //***********************************************************
    
    //***********************************************************
    //这使我们能够从任何边界调整无边界的大小,而不仅仅是右下角
    受保护的覆盖无效WndProc(参考消息m)
    {
    常量int wmNcHitTest=0x84;
    常量int htLeft=10;
    常数int htRight=11;
    常数int htTop=12;
    常数int htTopLeft=13;
    常数int htTopRight=14;
    常数int htBottom=15;
    常量int htBottomLeft=16;
    const int htBottomRight=17;
    如果(m.Msg==wmNcHitTest)
    {
    intx=(int)(m.LParam.ToInt64()&0xFFFF);
    int y=(int)((m.LParam.ToInt64()&0xFFFF0000)>>16);
    点pt=点到客户端(新点(x,y));
    Size clientSize=clientSize;
    ///允许在右下角调整大小
    如果(pt.X>=clientSize.Width-16&&pt.Y>=clientSize.Height-16&&clientSize.Height>=16)
    {           
    m、 结果=(IntPtr)(IsMirrored?htBottomLeft:htBottomRight);
    返回;
    }       
    ///允许在左下角调整大小
    if(pt.X=clientSize.Height-16&&clientSize.Height>=16)
    {
    m、 结果=(IntPtr)(IsMirrored?htBottomRight:htBottomLeft);
    返回;
    }
    ///允许在右上角调整大小
    if(pt.X=clientSize.Width-16&&pt.Y=16)
    {
    m、 结果=(IntPtr)(IsMirrored?htTopLeft:htTopRight);
    返回;
    }
    ///允许在顶部边框上调整大小
    如果(第Y部分=16)
    {
    m、 结果=(IntPtr)(htTop);
    返回;
    }
    ///允许在底部边框上调整大小
    if(pt.Y>=clientSize.Height-16&&clientSize.Height>=16)
    {
    m、 结果=(IntPtr)(htBottom);
    返回;
    }
    ///允许在左边框上调整大小
    如果(pt.X=16)
    {
    m、 结果=(IntPtr)(htLeft);
    返回;
    }
    ///允许在右边框上调整大小
    如果(pt.X>=clientSize.Width-16&&clientSize.Height>=16)
    {