Samstag, 10. Juli 2010

Bildschirmschoner (Screensaver) erstellen

Ein Bildschirmschoner (engl. Screensaver) ist eigentlich nur eine ausführbare .exe - Datei, die als Endung .scr besitzt und ein paar besondere Programmeigenschaften hat.
Diese Tatsache nutzen wir jetzt aus, um uns mit C# selber einen Bildschirmschoner zusammenzubasteln.
Das Screensaver - Programm erwartet beim Starten einen Parameter, ob der Bildschirmschoner gestartet ("/s") oder konfiguriert ("/c") werden soll.
Da Windows Forms-Anwendungen nur schwer mit Startparametern gestartet werden können, legen wir ein neues C# - Projekt vom Typ einer Konsolenanwendung an.
Zu dem Projekt fügen wir dann ein neues Element, ein Formular (Windows Form) hinzu.
In der Main - Funktion der Konsolenanwendung fragen wir den übergebenen Parameter ab, entspricht dieser dem String "/s", starten wir das hinzugefügte Formuar (im Beispiel ist dessen Name ScreenSaverForm):

System.Windows.Forms.Application.Run(new ScreensaverForm());

Damit dieses Formular im Vollbildmodus läuft, wie man es von Bildschirmschonern gewöhnt ist, setzen wir beim Aufrufen dessen in der Funktion Load() die folgenden Eigenschaften:

        private void ScreensaverForm_Load(object sender, EventArgs e)
        {
            FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; // Rahmen entfernen
            this.Bounds = Screen.PrimaryScreen.Bounds; // Größe über kompletten Bildschirm strecken
            Cursor.Hide(); // Mauszeiger ausblenden
            TopMost = true; // Formular als oberstes Programm definieren, so wird auch die Taskleiste ausgeblendet

        }

Führt man dieses Programm in diesem Zustand testweise aus, ist die Konsolenanwendung sowie die Taskleiste immer noch sichtbar.
Dieses Problem lässt sich beheben, in dem man in den Projekteigenschaften (Rechtsklick auf das Projekt im Projektmappen - Explorer) unter "Anwendung" als Ausgabetyp "Windows-Anwendung" eingestellt.
Nun muss nur noch definiert werden, wann der Bildschirmschoner aufhören soll zu laufen, was der Fall bei irgendeiner Benutzerinteraktion ist.
In den Funktionen ScreensaverForm_KeyDown(), ScreensaverForm_MouseDown() und private void ScreensaverForm_MouseMove() führen wir also dementsprechende Aktionen aus.
Nun der komplette Quellcode, zuerst von der Konsolenanwendung StartupProgramm.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ScreenSaver
{
    class StartupProgramm
    {
        static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                // Konfiguration
                if ((args[0].ToLower().Trim().Substring(0, 2) == "/c")) // längere Umwandlung nötig da config - Parameter in der Form "/c:xxxxx" übergeben wird
                {
                    // alternativ hier Formular mit Konfigurationsmöglichkeiten laden
                    System.Windows.Forms.MessageBox.Show("Keine Einstellungen verfügbar.");
                }
                // Start
                else if (args[0].ToLower() == "/s")
                {
                    // Bildschirmschonerformular laden
                    System.Windows.Forms.Application.Run(new ScreensaverForm());
                }
            }
        }
    }
}

Und der Quellcode des Formulars ScreenSaverForm.cs:

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

namespace ScreenSaver
{
    public partial class ScreensaverForm : Form
    {

        Point PrevPos; // vorherige Position des Mauszeigers

        public ScreensaverForm()
        {
            InitializeComponent();
        }

        private void ScreensaverForm_Load(object sender, EventArgs e)
        {
            FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; // Rahmen entfernen
            this.Bounds = Screen.PrimaryScreen.Bounds; // Größe über kompletten Bildschirm strecken
            Cursor.Hide(); // Mauszeiger ausblenden
            TopMost = true; // Formular als oberstes Programm definieren, so wird auch die Taskleiste ausgeblendet

        }

        private void ScreensaverForm_MouseMove(object sender, MouseEventArgs e)
        {
            // Falls vorheriger Punkt gesetzt wurde, neue Position mit alter vergleichen.
            if (!PrevPos.IsEmpty)
            {
                // wurde die Maus bewegt, Formular beenden
                if (PrevPos.X != e.X || PrevPos.Y != e.Y)
                    Close();
            }
            // Vorherige Position setzen (ist nur beim 1. Aufruf der Fall).
            // Close() alleine als Anweisung in dieser Funktion würde den falschen Effekt erzielen,
            // da das Ergeignis MouseMove beim Starten des Formulars immer einmal ausgelöst wird.
            PrevPos = new Point(e.X, e.Y);
        }

        private void ScreensaverForm_MouseDown(object sender, MouseEventArgs e)
        {
            Close();
        }

        private void ScreensaverForm_KeyDown(object sender, KeyEventArgs e)
        {
            Close();
        }
    }
}

Das Formular ist noch leer, kann aber ganz nach Belieben mit Steuerelementen und Funktionalitäten gefüllt werden, bei der Erstellung eines Bildschirmschoners sind der Kreativität hierüber keine Grenzen gesetzt.
Damit Windows diesen Bildschirmschoner erkennt, muss die .exe - Datei des Projekts in den Ordner C:\WINDOWS\system32 kopiert werden und die Endung in ".scr" geändert werden.
Einen komplett ausgebauten Screensaver mit Konfigurationstool etc. findet ihr im nächsten Post, dort könnt ihr euch meinen selbst programmierten Matrix Screensaver herunterladen.

Kommentare:

  1. Wieso können WinForms-Anwendungen nur schwer mit Parametern gestartet werden? Im Prinzip klappt's doch genauso, wie mit Konsolenanwendungen. ;)

    private string[] args;
    private void FormMain_Load(object sender, EventArgs e)
    {
    args = Environment.GetCommandLineArgs();
    }

    AntwortenLöschen
  2. Danke, dass ist sehr hilfreich.

    AntwortenLöschen
  3. danke das was sehr hilfreich

    AntwortenLöschen
  4. Danke, ganz so einfach hätt ich mir nicht vorgestellt. Hier das resultat: http://koopakiller.ko.ohost.de/cpp-cs/scr/chars.htm

    AntwortenLöschen
  5. überhaupt nicht einfach:-( für einen grafiker und eben NICHT proger.

    AntwortenLöschen
  6. Bei mir gibt er mir immer nen Fehler, dass in der Zeile System.Windows.Forms.Application.Run(new ScreensaverForm()); ScreensaverForm nicht vorhanden wäre...

    AntwortenLöschen