如何在C#中为WinForm创建一个框架?

3

我一直在探索如何更改 Windows 窗体的边框颜色,并发现这是由 Windows 决定的。好吧,这很合理。然后我看到之前有人问过同样的问题,被告知要去这里http://customerborderform.codeplex.com/。看起来这个网站目前无法使用。那么我是否需要自己制作边框?如果是这样,我该去哪里找相关信息呢?我正在使用 Visual Studio 2012。


在将窗体设置为DoubleBuffered后,在Paint事件中绘制边框。这里不会出现调整大小的问题。 - TaW
抱歉,我对C#还比较新,您说的paint事件是什么?我刚刚在谷歌上搜索了一下,这个链接https://msdn.microsoft.com/en-us/library/system.windows.forms.control.paint(v=vs.110).aspx是您所指的吗? - Austin Jones
是的,那(几乎)是正确的;因为你可能会从子类继承覆盖OnPaint事件更好。我已经添加了一个例子。 - TaW
3个回答

2
以下是一个自绘边框、可调整大小和移动的表单示例:
public partial class BorderForm : Form
{
    public BorderForm()
    {
        InitializeComponent();
        this.FormBorderStyle = FormBorderStyle.None;
        this.DoubleBuffered = true;
        this.SetStyle(ControlStyles.ResizeRedraw, true);
        BorderColor = Color.DarkSlateGray;
    }


    private const int hWidth = 12;        // resize handle width
    private const int bWidth = 28;        // border width
    public Color BorderColor { get; set;  }

    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();

    protected override void OnPaint(PaintEventArgs e)
    {
        // draw the border..
        using (Pen pen = new Pen(BorderColor, bWidth)
             { Alignment = System.Drawing.Drawing2D.PenAlignment.Inset})
            e.Graphics.DrawRectangle(pen, ClientRectangle);
        // now maybe draw a title text..

        base.OnPaint(e);
    }


    protected override void OnMouseDown(MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            ReleaseCapture();
            SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
        }
    }


    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x84) // Trap WM_NCHITTEST
        {  
            Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
            pos = PointToClient(pos);

            bool isTop = pos.Y <= hWidth;
            bool isBottom = pos.Y >= ClientSize.Height - hWidth;
            bool isRight = pos.X >= ClientSize.Width - hWidth;
            bool isLeft = pos.X <= hWidth;

            m.Result = (IntPtr)1;

            if (isTop) m.Result = 
                       isLeft ? (IntPtr)13 : isRight ? (IntPtr)14 : (IntPtr)12;
            else if (isBottom) m.Result = 
                 isLeft ? (IntPtr)16 : isRight ? (IntPtr)17 : (IntPtr)15;
            else if (isLeft) m.Result = (IntPtr)10;  
            else if (isRight) m.Result = (IntPtr)11;

            if ( m.Result != (IntPtr)1) return;
        }
        base.WndProc(ref m);
    }

}

WM_NCHITTEST文档向您展示如何模拟控件和调整大小框的点击,如果需要的话。当然,您还应该以某种方式绘制它们!


0

我猜你想制作自定义的winform。在这种情况下,你可能不想渲染默认的窗口。在Photoshop中绘制所需的winform,并将其用作应用程序的背景。这种方法的问题是你需要设计自己的最小化、最大化和关闭按钮。

你可以使用FormBorderStyle来使它消失。


好的,听起来很简单。 - Austin Jones

0

可能更容易在WPF中实现您想要的,因为它更现代化,您可以更轻松地设计/构建您想要的内容。另一件越来越普遍的事情是将其制作成自托管的Web应用程序,该应用程序在localhost上运行并使用The Chromium Embeded Framework,因此您基本上可以制作一个看起来像Windows程序的Web应用程序,这使得将您的程序移植到Linux和MacOS非常容易。 - Ryan Mann
你说的WPF是指Windows Presentation Foundation,对吗?抱歉,只是想确认一下。 - Austin Jones
是的,WPF = Windows Presentation Foundation。 - Ryan Mann
好的,如果我想改变边框的外观,我应该按照Mox所说的设计我的winForm并在Photoshop中使用它作为背景吗? - Austin Jones
2
如果您这样做,图像将随着表单的调整而缩小和增大。也许更好的方法是仅设计4个部分的边框。为顶部边框、左侧边框、底部边框和右侧边框制作图像。然后在顶部、左侧、右侧和底部绘制它们。这样它们就不会在表单调整大小时出现问题。您还可以在一个图像中完成这项工作,然后复制出各个部分并绘制这些部分(使用一些网站使用的概念,其中它们在一个文件中有多个图像)。 - Ryan Mann
好的,谢谢你的帮助!我一定会采用这种方法。 - Austin Jones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接