Embedding Screensaver's in a Windows Form

Awhile ago I created the screensaver Vista Sidebar gadget and promised I would put some code up. As promised, here it is. It's actually quite easy to create something like this, and truth be told I actually had the code lying around for a few years since I wrote it for my 2nd book. Rather than confuse you with any sidebar code, I just created a simple Windows Form that hosts the screensaver UserControl (full source code can be downloaded below).

The hardest part (which is actually somewhat easy) is telling Windows to launch the screensaver within a certain window rather than fullscreen. You've seen this window in the control panel and may have wondered how it's done. To do this, you simply launch the screensaver (.scr file) and pass a command line parameter (/p for preview) and your window handle. The window handle can be accessed in a Windows Form or UserControl through the Handle property.

Below is the code that embeds a screensaver in my custom UserControl. You can see that I first check to see if a screensaver is already running and if it is, I tell it to stop (Kill). I then simply check to make sure my UserControl ScreensaverPath property is set and if it is I launch the executable using Process.Start with associated command line arguments ( /p <window handle> ).

private void LaunchScreensaver(string args)

{

    try

    {

        if (screenSaverProc != null)

        {

            screenSaverProc.Kill();

            screenSaverProc = null;

        }

 

        if (!String.IsNullOrEmpty(screenSaverPath))

        {

            this.Visible = true;

            ProcessStartInfo startInfo = new ProcessStartInfo(screenSaverPath + args, "");

 

            startInfo.UseShellExecute = false;

 

            screenSaverProc = Process.Start(startInfo);

        }

        else

        {

            this.Visible = false;

        }

    }

    catch (Exception ex)

    {

        throw new Exception("Could not launch screensaver:" + this.screenSaverPath, ex);

    }

}

To wire this up to the Windows Form, I simply expose a property named ScreensaverPath. Whenever the form sets this property, I call LaunchScreensaver and pass the appropriate command line arguments as shown below.

public string ScreensaverPath

{

    get { return screenSaverPath; }

    set

    {

        this.Visible = true;

        screenSaverPath = value;

        LaunchScreensaver(" \"/p" + this.Handle.ToString() + "\"");

    }

}

Here's a couple screenshots of the Screensaver Form project running various Vista screensavers.

bubbles skyrocket

mystify ribbons

As promised, here's the code. Also, one thing to note. Some screensavers don't play nice with the /p parameter. I haven't look into why this is, but in most cases the default Vista screensavers work just fine.