Альфа-смешанный заставка отображает мусор в XP, но работает в Win7 - PullRequest
2 голосов
/ 08 ноября 2011

У меня есть форма без полей со следующим кодом:

public partial class Splash : Form
{
    bool painted = false;

    public Splash()
    {
        InitializeComponent();

        Opacity = 0;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        //
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        if (painted)
            return;

        Graphics gfx = e.Graphics;
        gfx.CopyFromScreen(new Point(Bounds.Left, Bounds.Top),
                           Point.Empty, Bounds.Size);
        gfx.DrawImage(Properties.Resources.Splash, e.ClipRectangle);

        Opacity = 100;
        painted = true;
    }
}

На моем компьютере с Windows 7 это работает довольно хорошо, но в Windows XP вместо заставки появляется мусор (предположительно, любой не выровненный материал в буфере кадров). Иногда я могу различить сильно искаженные остатки старых окон проводника и т. Д. Внутри мусора.

Странно то, что я запускаю идентичный код в другой программе, которая имеет такой же тип 24-битного PNG и которая отлично работает на компьютере с XP.

Есть идеи, почему это может происходить?


Решение:

Добавьте Bitmap b; после строки bool painted = false; и измените OnPaintBackground на:

protected override void OnPaintBackground(PaintEventArgs e)
{
    if (!painted)
    {
        b = new Bitmap(Width, Height);
        Graphics g = Graphics.FromImage(b);

        g.CopyFromScreen(new Point(Bounds.Left, Bounds.Top),
                         Point.Empty, Bounds.Size);
        g.DrawImage(Properties.Resources.Splash, e.ClipRectangle);

        Opacity = 100;
        painted = true;

        g.Dispose();
    }

    Graphics gfx = e.Graphics;
    gfx.DrawImage(b, new Point(0, 0));
    gfx.Dispose();
}

Ответы [ 3 ]

2 голосов
/ 08 ноября 2011

Я думаю, это потому, что вы не обновляете форму после того, как нарисовали его один раз. Win XP хранит не любое графическое содержимое окон, он просто уведомляет их нарисовать себя. Ваши функции OnPaint и OnPaintBackground всегда должны обновлять окно. Я не понимаю, почему вы не используете свойство BackgroundImage вместе с Opacity. Вы можете установить растяжение, увеличение и т. Д. Вы хотите показать эффект?

1 голос
/ 08 ноября 2011

Рассматривали ли вы использование формы с .BorderStyle, установленным в None, с установленным .TransparencyKey? Это должно имитировать эффект, который вы пытаетесь получить без хлопот вызова CopyFromScreen.

отредактировано на основе комментариев

Я нашел пример исходного кода, который выполняет альфа-смешивание на пиксель, которое вы хотите, но он гораздо более сложный и включает pInvoke. Для справки вы можете найти его здесь. http://www.codeproject.com/KB/GDI-plus/perpxalpha_sharp.aspx

0 голосов
/ 08 ноября 2011

Я думаю, что Win7 хранит графическое содержимое окон и перерисовывает их автоматически.Вы можете увидеть разницу, когда окно не отвечает - в WinXP он не будет обновляться, а в Win7 он будет выглядеть нормально.А также предварительный просмотр окна при наведении курсора на панель задач и эффект «роста формы» при появлении формы.Я пишу это в отдельном ответе, потому что я не знаю, как добавить комментарий на этом сайте ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...