Простой ScreenSaver на C#

Сегодня попытаемся написать простенькую заставку для ОС Windows на языке программирования C#. Прошу меня строго не судить, т.к. я не специализируюсь в программировании на данном языке. Иногда, для разнообразия, пишу по мелочам на нем ;-).

В качестве среды разработке мы воспользуемся Microsoft Visual Studio 2015. А также нам понадобятся такие файлы как изображение для нашего логотипа (например, размером 300×300 пикселей и в формате png) и любая иконка (16×16 пикселей) в формате ico.

Я не буду описывать все подробно, а остановлюсь лишь на важных моментах. Для удобства исходный код максимально покрою комментариями.

Итак, при первом запуске среды разработки создаем приложение типа Windows Forms Application. Для названия проекта и его решения я выбрал следующее название — SampleScreenSaver. Имя файла основной формы мы изменим на FormMain. Дополнительно добавим еще одну форму в наш проект и назовем ее как FormConfigure.

Свойства формы FormMain

Название свойства Значение свойства
(Name) frmMain
FormBorderStyle None
BackColor White
WindowState Maximized

Я не стал описывать подробнее указанные свойства, т.к. здесь все итак понятно. При возникновении вопросов всегда существует возможность воспользоваться справочной системой среды программирования (клавиша F1).

Пример ScreenSaver

Рис. 1. Пример расположения элементов управления на основной форме

Свойства элемента управления PictureBox

Название свойства Значение свойства
(Name) pbLogo
BackColor Transparent
Image ваш файл с изображением
SizeMode AutoSize

Пример моего изображения см. на рис. 1.

Свойства элемента управления Label

Название свойства Значение свойства
(Name) lblCopyright
ForeColor Silver
Text Программирование и не только

Свойства элемента управления Timer

Название свойства Значение свойства
(Name) tmrTimer
Interval 300

Свойства формы FormConfigure

Название свойства Значение свойства
(Name) FormConfigure
Icon ваш файл с иконкой
ShowInTaskbar false
Text Настройки
StartPosition CenterScreen
MaximizeBox false
MinimizeBox false

Сразу скажу, насчет формы FormConfigure, я не предусматриваю какие-либо настройки для нашей заставки. При желании вы самостоятельно сможете добавить свои настройки (например, сохранять значения настроек в реестре Windows).

Пришла очередь рассмотреть исходный код форм и нашего проекта.

Файл Program.cs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SampleScreenSaver
{
    static class Program
    {
        /// <summary>
        /// Главная точка входа для приложения.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                if (args[0].ToLower().Trim().Substring(0, 2) == "/s")
                {
                    // Отобразить заставку
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    ShowScreenSaver();
                    Application.Run();
                }
                else if (args[0].ToLower().Trim().Substring(0, 2) == "/p")
                {
                    // Предварительный просмотр заставки
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new frmMain(new IntPtr(long.Parse(args[1]))));
                }
                else if (args[0].ToLower().Trim().Substring(0, 2) == "/c")
                {
                    // Отображение окна с настройками заставки
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new FormConfigure());
                }
            }
            else
            {
                // Отобразить заставку    
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                ShowScreenSaver();
                Application.Run();
            }
        }

        // Отображение заставки
        static void ShowScreenSaver()
        {
            foreach (Screen screen in Screen.AllScreens)
            {
                frmMain screensaver = new frmMain(screen.Bounds);
                screensaver.Show();
            }
        }
    }
}

Файл FormMain.cs.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SampleScreenSaver
{
    public partial class frmMain : Form
    {
        [DllImport("user32.dll")]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32.dll")]
        static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
        static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        static extern bool GetClientRect(IntPtr hWnd, out Rectangle lpRect);

        // Флаг предварительного просмотра
        private bool IsPreviewMode;

        Graphics graph;
        Pen pen;

        // Цвет фона
        SolidBrush bg;

        // Цвет фигуры
        SolidBrush figure;

        // Величина радиуса
        int radius;

        Random rnd;

        // Координаты для рисования
        Point OriginalLocation = new Point(int.MaxValue, int.MaxValue);

        public frmMain(Rectangle Bounds)
        {
            InitializeComponent();

            this.Bounds = Bounds;

            // Скрыть отображение курсора мышки
            Cursor.Hide();
        }

        // Дескриптор для отображения диалогового окна
        // с предвартельным просмотром заставки
        public frmMain(IntPtr PreviewHandle)
        {
            InitializeComponent();

            // Окно предварительного просмотра в качестве родительского
            SetParent(this.Handle, PreviewHandle);

            // сделать дочерним окном, когда диалог выбора заставки
            // закроется, то оно также закроется
            SetWindowLong(this.Handle, -16,
              new IntPtr(GetWindowLong(this.Handle, -16) | 0x40000000));
       
            // установить размер окна в соответствии с размером вашего 
            // нового родительского окна
            Rectangle ParentRect;
            GetClientRect(PreviewHandle, out ParentRect);
            this.Size = ParentRect.Size;

            this.Location = new Point(0, 0);

            IsPreviewMode = true;
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            // Выравнивание изображения по середине
            pbLogo.Left = Bounds.Width / 2 - pbLogo.Width / 2;
            pbLogo.Top = Bounds.Height / 2 - pbLogo.Height / 2;

           lblCopyright.Font = new Font("Microsoft Sans Serif", 10F);

            // Выравнивание текста в нижнем правом углу окна
            lblCopyright.Left = Bounds.Right - lblCopyright.Width;
            lblCopyright.Top = Bounds.Bottom-20;

            graph = this.CreateGraphics();

            pen = new Pen(Color.Green);                   // Цвет границы окружности
            figure = new SolidBrush(Color.Transparent);   // Цвет окружности
            bg = new SolidBrush(Color.White);             // Фон вокруг окружности

            rnd = new Random();
            radius = rnd.Next(4, 18);                     // Радиус окружности
            int x, y;

            for (int i = 0; i < 24; i++)
            {
                x = rnd.Next(this.Width);
                y = rnd.Next(this.Height);

                // вызываем функцию для прорисовки круга случайным образом,
                // выбрав перед этим координаты центра
                DrawCircle(x, y);
            }

            tmrTimer.Enabled = true;
        }

        // Рисование окружности по координатам его центра
        private void DrawCircle(int x, int y)
        {
            int xC, yC;
            xC = x - radius;
            yC = y - radius;
            graph.FillEllipse(figure, xC, yC, radius, radius);
            graph.DrawEllipse(pen, xC, yC, radius, radius);
        }

        private void tmrTimer_Tick(object sender, EventArgs e)
        {
            int x, y;

            // Очистить область рисования заливкой цветом фона
            graph.FillRectangle(bg, 0, 0, this.Width, this.Height);

            // случайным образом выбираем координаты центров кругов и рисуем их
            for (int i = 0; i < 15; i++)
            {
                x = rnd.Next(this.Width);
                y = rnd.Next(this.Height);
                DrawCircle(x, y);
            }
        }

        private void CloseWindowMouseMove(MouseEventArgs e)
        {
            // Если не предварительный просмотр заставки
            if (!IsPreviewMode)
            {
                // смотрим, было ли установлено оригинальное местоположение
                if (OriginalLocation.X == int.MaxValue &
                    OriginalLocation.Y == int.MaxValue)
                {
                    OriginalLocation = e.Location;
                }
            
                // смотрим, переместился ли указатель мыши более чем на 20 пикселей
                if (Math.Abs(e.X - OriginalLocation.X) > 20 |
                    Math.Abs(e.Y - OriginalLocation.Y) > 20)
                {
                    Application.Exit();
                }
            }
        }

        private void frmMain_MouseMove(object sender, MouseEventArgs e)
        {
            this.CloseWindowMouseMove(e);
        }

        private void pbLogo_MouseMove(object sender, MouseEventArgs e)
        {
            this.CloseWindowMouseMove(e);
        }

        private void frmMain_Click(object sender, EventArgs e)
        {
            if (!IsPreviewMode)
            {
                Application.Exit();
            }
        }

        private void pbLogo_Click(object sender, EventArgs e)
        {
            if (!IsPreviewMode)
            {
                Application.Exit();
            }
        }

        private void frmMain_KeyDown(object sender, KeyEventArgs e)
        {
            if (!IsPreviewMode)
            {
                Application.Exit();
            }
        }
    }
}

Файл FormConfigure.cs.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SampleScreenSaver
{
    public partial class FormConfigure : Form
    {
        public FormConfigure()
        {
            InitializeComponent();
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            lnkAuthor.LinkVisited = true;
            System.Diagnostics.Process.Start("https://sitkodenis.ru");
        }
    }
}

Сразу размещаю исходный код полного проекта SampleScreenSaver.

Последним этапом останется выполнить вашу программу и перейти в директорию с проектом, затем в папку obj, а потом в Debug. Внутри каталога Debug найти EXE-файл и переименовать его расширение в SCR (в моем случае это файл с именем SampleScreenSaver.exe).

Вот такой получился небольшой пример по созданию скринсейвера на языке программирования C#. Конечно же, я предполагаю, что многие вещи можно было бы сделать более элегантно, но не судите строго, т.к. в этом вопросе я не являюсь экспертом. В то же время постарался изложить материал так, чтобы было понятно многим.

Спасибо за внимание и до новых встреч.

 

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

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

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: