Как нарисовать элементы окна в классическом стиле Windows

Мы создаем несколько пользовательских "окон" в нашей программе и когда VisualStyles Если мы активированы, мы можем найти каждый элемент окна и его размер и нарисовать их сами, включая кнопки свертывания и закрытия, используя соответствующие средства визуализации.

Мы хотели бы сделать то же самое, когда VisualStyles отключены и в настоящее время рисуют наши собственные окна, но они довольно уродливы. Можно ли в WinForms C# рисовать окна в стиле Windows Classic? Я нашел 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;
}

1 ответ

Решение

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

Выглядит так на моей машине, не совсем некрасиво:)

введите описание изображения здесь

Другие вопросы по тегам