如何绘制Windows经典样式窗口元素 [英] How to draw Windows Classic style window elements

查看:99
本文介绍了如何绘制Windows经典样式窗口元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在程序中创建了一些自定义窗口",启用VisualStyles后,我们能够找到窗口的每个元素及其大小,并使用适当的渲染器自行绘制它们,包括最小化"和关闭"按钮. /p>

VisualStyles被禁用并当前绘制我们自己的窗口时,我们想做同样的事情,但是它们非常难看.是否可以在WinForms C#中绘制Windows经典样式的窗口?我已经找到了ClassicBorderDecorator,但是它是用于WPF的.

否则,我们如何通过以下方式获取窗饰的像素大小:

// Get the height of the window caption.
if (SetRenderer(windowElements["windowCaption"]))
{
  captionHeight = renderer.GetPartSize(graphics.Graphics, ThemeSizeType.True).Height;
}

// Get the thickness of the left, bottom, 
// and right window frame.
if (SetRenderer(windowElements["windowLeft"]))
{
  frameThickness = renderer.GetPartSize(graphics.Graphics, ThemeSizeType.True).Width;
}

解决方案

Windows没有提供经典风格的渲染器,您必须自己做饭.使用SystemInformation类获取指标,使用Color.FromKnownColor()获取颜色.

唯一棘手的部分是使边框按钮看起来不错.最好的办法是使用字体中的字形,而不是尝试自己绘制它们. Webdings字体是理想的选择.

我无法确定匹配的接近程度,我的机器启动Windows 8,并且不再支持经典样式.否则,强烈暗示您可能不应该在此上投入太多时间:)一些示例代码:

protected override void OnPaintBackground(PaintEventArgs e) {
    base.OnPaintBackground(e);
    var captionHeight = SystemInformation.CaptionHeight;
    int border = SystemInformation.Border3DSize.Width;
    var color1 = Color.FromKnownColor(activated ? KnownColor.ActiveCaption : KnownColor.InactiveCaption);
    var color2 = Color.FromKnownColor(activated ? KnownColor.GradientActiveCaption : KnownColor.GradientInactiveCaption);
    var captionrc = new Rectangle(0, 0, this.ClientSize.Width, captionHeight);
    using (var brush = new LinearGradientBrush(captionrc, color1, color2, 0, false)) {
        e.Graphics.FillRectangle(brush, captionrc);
    }
    int textx = border;
    if (this.Icon != null) {
        int height = SystemInformation.SmallIconSize.Height;
        var iconrc = new Rectangle(border, (captionHeight - height)/2, height, height);
        textx += height + border;
        e.Graphics.DrawIcon(this.Icon, iconrc);
    }
    var color = Color.FromKnownColor(activated ? KnownColor.ActiveCaptionText : KnownColor.InactiveCaptionText);
    using (var font = new Font(this.Font.FontFamily, SystemInformation.CaptionHeight - 4 * border, GraphicsUnit.Pixel)) {
        TextRenderer.DrawText(e.Graphics, this.Text, font, new Point(textx, border), color);
    }
    using (var font = new Font(new FontFamily("Webdings"), captionHeight - 4 * border, GraphicsUnit.Pixel)) {
        var glyphs = this.WindowState == FormWindowState.Maximized ? "\u0030\u0031\u0072" : "\u0030\u0031\u0072";
        var width = TextRenderer.MeasureText(glyphs, font).Width;
        TextRenderer.DrawText(e.Graphics, glyphs, font, 
            new Point(this.ClientSize.Width - width, border),
            Color.FromKnownColor(KnownColor.WindowFrame));
    }
}

在我的机器上看起来像这样,并不完全丑陋:)

We create a few custom 'windows' in our program and when VisualStyles are enabled we are able to find each element of the window and their size and paint them ourselves including the minimize and close buttons using the appropriate Renderers.

We'd like to do that same thing when VisualStyles are disabled and currently draw our own windows but they're quite ugly. Is it possible in WinForms C# to draw the Windows Classic style windows? I've found the ClassicBorderDecorator but it's for WPF.

Or, failing that, how can we get the pixel sizes of the window decorations which we do in the following way:

// Get the height of the window caption.
if (SetRenderer(windowElements["windowCaption"]))
{
  captionHeight = renderer.GetPartSize(graphics.Graphics, ThemeSizeType.True).Height;
}

// Get the thickness of the left, bottom, 
// and right window frame.
if (SetRenderer(windowElements["windowLeft"]))
{
  frameThickness = renderer.GetPartSize(graphics.Graphics, ThemeSizeType.True).Width;
}

解决方案

Windows doesn't provide a renderer for the classic style, you'll have to cook your own. Use the SystemInformation class to get the metrics, Color.FromKnownColor() to get colors.

The only tricky part is to get the frame buttons look good. Best thing to do is to use a glyph from a font instead of trying to paint them yourself. The Webdings font is ideal for this.

I cannot verify how close a match it will be, my machine boots Windows 8 and doesn't support classic style anymore. Otherwise a strong hint that you probably should not invest too much time into this :) Some example code:

protected override void OnPaintBackground(PaintEventArgs e) {
    base.OnPaintBackground(e);
    var captionHeight = SystemInformation.CaptionHeight;
    int border = SystemInformation.Border3DSize.Width;
    var color1 = Color.FromKnownColor(activated ? KnownColor.ActiveCaption : KnownColor.InactiveCaption);
    var color2 = Color.FromKnownColor(activated ? KnownColor.GradientActiveCaption : KnownColor.GradientInactiveCaption);
    var captionrc = new Rectangle(0, 0, this.ClientSize.Width, captionHeight);
    using (var brush = new LinearGradientBrush(captionrc, color1, color2, 0, false)) {
        e.Graphics.FillRectangle(brush, captionrc);
    }
    int textx = border;
    if (this.Icon != null) {
        int height = SystemInformation.SmallIconSize.Height;
        var iconrc = new Rectangle(border, (captionHeight - height)/2, height, height);
        textx += height + border;
        e.Graphics.DrawIcon(this.Icon, iconrc);
    }
    var color = Color.FromKnownColor(activated ? KnownColor.ActiveCaptionText : KnownColor.InactiveCaptionText);
    using (var font = new Font(this.Font.FontFamily, SystemInformation.CaptionHeight - 4 * border, GraphicsUnit.Pixel)) {
        TextRenderer.DrawText(e.Graphics, this.Text, font, new Point(textx, border), color);
    }
    using (var font = new Font(new FontFamily("Webdings"), captionHeight - 4 * border, GraphicsUnit.Pixel)) {
        var glyphs = this.WindowState == FormWindowState.Maximized ? "\u0030\u0031\u0072" : "\u0030\u0031\u0072";
        var width = TextRenderer.MeasureText(glyphs, font).Width;
        TextRenderer.DrawText(e.Graphics, glyphs, font, 
            new Point(this.ClientSize.Width - width, border),
            Color.FromKnownColor(KnownColor.WindowFrame));
    }
}

Looks like this on my machine, not entirely ugly :)

这篇关于如何绘制Windows经典样式窗口元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆