Экранная заставка на C#

Экран-заставка приложения

Профессиональные программные приложения .NET очень часто имеют экран-заставку, который появляется во время загрузки приложения. Экран-заставка не только дает пользователю что-то, на что можно посмотреть во время загрузки программы, но и дает профессиональную презентацию вашим приложениям C#.

Хотя приложения могут иметь очень простые экраны-заставки C#, в этой статье давайте рассмотрим компоненты создания расширенного экрана-заставки. Для теней и прозрачности потребуется несколько вызовов API для включения прозрачности в фоновом изображении формы окна.

Требуются вызовы API

Наиболее важной функцией API для создания экрана-заставки C# будет UpdateLayeredWindow. UpdateLayerWindow — очень полезная функция. Это не только позволит нашему приложению отображать фоновые изображения с трансперативностью, которая включает в себя тени.

Однако это будет не единственный вызов API, так как форма-заставка будет отображать изображение, нам нужны некоторые общие вызовы API для обработки изображений.

Все объявления включены в класс API

Расширения стиля WinForm

Существует одна последняя корректировка для установки формы Windows. Стиль Form необходимо расширить, чтобы разрешить «слои», которые будут использоваться вызовами API. Чтобы задать WS_EX_LAYERED экрана-заставки, необходимо переопределить свойство CreateParams.

В сочетании с вызовами API экран-заставка C# теперь может отображать тени и даже прозрачные области, как профессиональное программное приложение. Единственным недостатком является вызов API UpdateLayeredWindow (который отображает изображение) приводит к тому, что обычные элементы управления не отображаются. Обойти это невозможно, кроме как перейти на более новые технологии, такие как WPF.

Ниже будет представлен листинг программы, а вам остается лишь разместить картинку на форме и установить следующие свойства формы:

StartPosition-CenterScreen

FormBorderStyle-None

BackgroundImage-ваша картинка заставки

AutoScaleMode-Font

TopMost-true

//C#  www.nookery.ru
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices; 

namespace Screen
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x00080000; //Обязательно: установить расширенный стиль WS_EX_LAYERED
                return cp;
            }
        }

        //Обновляет отображение формы с помощью вызовов API
        public void UpdateFormDisplay(Image backgroundImage)
        {
            IntPtr screenDc = API.GetDC(IntPtr.Zero);
            IntPtr memDc = API.CreateCompatibleDC(screenDc);
            IntPtr hBitmap = IntPtr.Zero;
            IntPtr oldBitmap = IntPtr.Zero;

            try
            {
                //Дисплей-изображение
                Bitmap bmp = new Bitmap(backgroundImage);
                hBitmap = bmp.GetHbitmap(Color.FromArgb(0));  //Set the fact that background is transparent
                oldBitmap = API.SelectObject(memDc, hBitmap);

                //Дисплей-прямоугольник
                Size size = bmp.Size;
                Point pointSource = new Point(0, 0);
                Point topPos = new Point(this.Left, this.Top);

                //Настройка параметров наложения
                API.BLENDFUNCTION blend = new API.BLENDFUNCTION();
                blend.BlendOp = API.AC_SRC_OVER;
                blend.BlendFlags = 0;
                blend.SourceConstantAlpha = 255;
                blend.AlphaFormat = API.AC_SRC_ALPHA;

                API.UpdateLayeredWindow(this.Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, API.ULW_ALPHA);

                //Очистить
                bmp.Dispose();
                API.ReleaseDC(IntPtr.Zero, screenDc);
                if (hBitmap != IntPtr.Zero)
                {
                    API.SelectObject(memDc, oldBitmap);
                    API.DeleteObject(hBitmap);
                }
                API.DeleteDC(memDc);
            }
            catch (Exception)
            {
            }
        } 

        private void Form1_Load(object sender, EventArgs e)
        {
            UpdateFormDisplay(this.BackgroundImage);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            //Вызовите нашу функцию рисования
            UpdateFormDisplay(this.BackgroundImage);
        } 
    }

    internal class API
    {
        public const byte AC_SRC_OVER = 0x00;
        public const byte AC_SRC_ALPHA = 0x01;
        public const Int32 ULW_ALPHA = 0x00000002;

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct BLENDFUNCTION
        {
            public byte BlendOp;
            public byte BlendFlags;
            public byte SourceConstantAlpha;
            public byte AlphaFormat;
        }

        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);

        
        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern IntPtr GetDC(IntPtr hWnd);

        [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
        
        [DllImport("user32.dll", ExactSpelling = true)]
        public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

        [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern bool DeleteDC(IntPtr hdc);


        [DllImport("gdi32.dll", ExactSpelling = true)]
        public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

        [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
        public static extern bool DeleteObject(IntPtr hObject);
    }
}

 

Обновлено: 08.01.2022 — 15:11

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.