【问题标题】:How to make a frame for WinForm, C#?如何为 WinForm、C# 制作框架?
【发布时间】:2016-05-07 22:37:59
【问题描述】:

我一直在研究改变windows窗体边框的颜色,发现它是由windows决定的,好吧,这是有道理的,所以我看到以前问过这个问题的人被告知去这里@ 987654321@ 该网站目前似乎无法使用。那么我必须自己制作框架吗?如果是这样,我会去哪里解决这个问题?我正在使用 Visual Studio 2012。

【问题讨论】:

  • 使Form DoubleBuffered 后在Paint 事件中绘制边框。这里没有调整大小的问题..
  • 抱歉,我是 C# 的新手,绘画事件?我刚刚google了一下,你指的是msdn.microsoft.com/en-us/library/…吗?
  • 是的,这(几乎)是对的;因为您可能会优先选择覆盖 OnPaint 事件的子类形式。我添加了一个例子..

标签: c# winforms frame


【解决方案1】:

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

您可以使用FormBorderStyle 使其消失。

【讨论】:

  • 好的,听起来很简单
【解决方案2】:

它确实涉及,但如果您愿意,您可以创建自己的 Windows 窗体库,即根本不使用 Windows 窗体项目。使用 Windows GDI 文档和 PInvoke.Net 调用 GDI API 函数来创建窗口等并设计您自己的表单系统。

您要查看的具体部分是窗口函数:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms632679(v=vs.85).aspx

【讨论】:

  • 虽然在 WPF 中实现你想要的可能会更容易,它更现代,你可能更容易设计/构建你想要的。另一件变得越来越普遍的事情是让它成为一个在 localhost 上运行并使用 Chromium 嵌入式框架的自托管 Web 应用程序,因此您基本上可以创建一个运行并且看起来像 Windows 程序的 Web 应用程序,这使得移植您的程序变得非常容易到 Linux 和 MacOS。
  • WPF 你的意思是Windows Presentation Foundation,对吗?抱歉,只是想确定一下。
  • 是的,WPF = Windows Presentation Foundation
  • 好的,所以为了改变边框外观,我应该按照 Mox 所说的在 photoshop 中设计我的 winForm 并将其用作我的背景吗?
  • 如果你这样做,图像会随着表单大小的调整而缩小和增长。也许更好的方法是将边框设计成 4 块。为上边框、左边框、下边框和右边框制作图像。然后在顶部、左侧、右侧和底部绘制它们。这样他们就不会在表单调整大小时搞砸了。您也可以在一张图片中执行此操作,然后复制各个部分并绘制这些部分(使用一些网站使用的概念,它们在一个文件中有多个图像)。
【解决方案3】:

这是一个绘制自己的边框的表单示例,可以调整大小和移动..:

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 文档向您展示了如何模拟点击控件并在需要时调整框的大小。当然,您也应该以某种方式绘制它们!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-21
    • 2016-02-14
    • 2017-06-24
    相关资源
    最近更新 更多