How to draw Windows Classic style window elements

狂风中的少年 提交于 2019-12-31 01:00:14

问题


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;
}

回答1:


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 :)



来源:https://stackoverflow.com/questions/22972522/how-to-draw-windows-classic-style-window-elements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!