Click here to Skip to main content
12,450,089 members (54,080 online)
Click here to Skip to main content
Add your own
alternative version


203 bookmarked

How to develop a screen saver in C#

, 12 Nov 2004
Rate this:
Please Sign up or sign in to vote.
An article explaining how to develop a screensaver in C#, with a ready-to-code-screensaver source.

Issues covered

This article explains:

  • the basics of a screensaver
  • loading a screensaver
  • filling the whole screen
  • handling multiple monitors
  • handling events
  • some little intricacies

Additionally, the code provides a basic screensaver framework which you could use easily to create screensavers on your own.


A screensaver in Windows® is simply an executable file with the extension .scr. The only difference between a normal executable and a screensaver is that a screensaver does some specific things, viz:

  • parses the command line to find out what Windows® wants it to do
  • loads the screensaver appropriate to that request
  • ends the screensaver (usually), when the user uses the mouse or the keyboard

The arguments Windows® passes to a screensaver are:

  • /s - load the screensaver
  • /c - load the configuration screen
  • /p - load the preview

Once we determine the argument passed, we load the screensaver appropriately. When there is some kind of activity, you end the screensaver or do something else.

The code explained

Step 1: Making the Main method accept command-line arguments

The first step in developing a screensaver in C# is to modify the Main method so that it could accept command-line arguments. The default Main method is like this:

static void Main() 

As you can see, this Main method accepts no parameters. So, we add a string array parameter like this:

static void Main(string[] args) 

Step 2: Checking the arguments

Now we need to find out what arguments were passed.

First, we check whether Windows did pass some arguments, by checking whether the length of the string array is zero or not. If it's zero, there were no arguments. A typical scenario where no arguments are passed to a screensaver is when users just double click on your screensaver file.

Secondly, if there indeed were arguments, we catch them. Windows may pass arguments in either the lower case or the upper case. So it's a good idea to induce generalization of some sort. We do this by changing the arguments to lower case (or upper case) first and then checking them. The complete Main method would look something like:

static void Main(string[] args) 
  if (args.Length > 0)
    // load the config stuff
    if (args[0].ToLower().Trim().Substring(0,2) == "/c") 
    else if (args[0].ToLower() == "/s") // load the screensaver
    else if (args[0].ToLower() == "/p") // load the preview
  else // there are no arguments...nevertheless, do something!

Quite straight forward, isn't it? The only code you need to add here is what you would like to do for each argument.

Step 3: Invoking the screensaver

To run the screensaver, you call the System.Windows.Forms.Application.Run method. You pass a new form object as the argument. The code will look like:

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

where frmScreenSaver is the main screensaver form.

When the screensaver loads, we want it to fit the entire screen. For this, we need to figure out which screen our screensaver is running in right now and its dimensions. To access screens, we use the Screen class. Using the PrimaryScreen property of this class, we could access the primary screen of the system as well as its properties. Among those properties is Bounds, representing the size of the screen. What we do is set the form's Bounds property to that of this screen so that the form would be resized to occupy the entire screen. This procedure is usually executed in the form's Load event, for example:

private void frmScreenSaver_Load(object sender, System.EventArgs e)
  Bounds = Screen.PrimaryScreen.Bounds;

We need to address one possibility though - the user may be using more than one screen. If that's true, and if we load the screensaver only on one screen, the whole point of using this screensaver is lost. Hence, we find out the number of screens available, and load the screensaver in each of them. To do this, we iterate through all the available screens in the Main method, where we repeatedly call the form's constructor passing the screen's index. The set of all screens available in the system is listed in the AllScreens property of the Screen class. Thus the code in the Main method invoking the screensaver will have to be modified as:

for (int i = Screen.AllScreens.GetLowerBound(0); 
     i <= Screen.AllScreens.GetUpperBound(0); i++)
  System.Windows.Forms.Application.Run(new frmScreenSaver(i));

Note the change in the main screensaver form's constructor - it accepts an int parameter, which represents the screen's index onto which the screensaver is to be run. In response to this, we modify the form's class by adding an int member variable which will store the screen index. The form's constructor will then be modified to initialize this variable, like this:

public frmScreenSaver(int scrn)
  ScreenNumber = scrn;

where ScreenNumber is the int member variable.

After this, the Load event handler will have to be modified to resize the form to the bounds of not the primary screen, but that of the screen represented by the index, like this:

private void frmScreenSaver_Load(object sender, System.EventArgs e)
  Bounds = Screen.AllScreens[ScreenNumber].Bounds;

Once this is done, we have added multiple screen display functionality to our screensaver.

You will want to make the form topmost and hide the cursor. Just call the additional methods in the Load handler like this:

private void frmScreenSaver_Load(object sender, System.EventArgs e)
  Bounds = Screen.AllScreens[ScreenNumber].Bounds;
    TopMost = true;

Step 4: Handling events

Once you have loaded your screensaver, you have to handle events. This is because when the user uses the mouse or hits the keyboard, you probably want to do something, like ending the screensaver. To do this, you add event handlers to the KeyDown, MouseMove and MoveDown events of the screensaver form. In the event handlers, you could use the form's Close method to end the screensaver.

There is one point to note here. When an application is executed, the current mouse parameters are passed to it by Windows. This naturally triggers a mouse event, which would close the screensaver. To handle this, add a Point variable in the class, initialize it when the application executes, and check the mouse position and mouse clicks when mouse events occur. If there happens to be any change, then call Close. The code would look something like:

private void OnMouseMove(object sender, 
                         System.Windows.Forms.MouseEventArgs e)
  if (!MouseXY.IsEmpty)
    if (MouseXY != new Point(e.X, e.Y))
  MouseXY = new Point(e.X, e.Y);

where MouseXY is the Point variable we use to store the initial mouse position temporarily. Initially, MouseXY is null; and thus is assigned the current mouse position through this code. In the next call of this event handler, MouseXY is not empty; so we check whether the position has changed; if yes, close the form.

As mentioned earlier, you should handle both MouseMove and MouseDown events in a screensaver. But since both have the same arguments, you could use the same event handler for handling both events. Such a code would look like:

private void OnMouseEvent(object sender, 
                          System.Windows.Forms.MouseEventArgs e)
  if (!MouseXY.IsEmpty)
    if (MouseXY != new Point(e.X, e.Y))
    if (e.Clicks > 0)
  MouseXY = new Point(e.X, e.Y);

where OnMouseEvent is the event handler which is called on mouse move as well as mouse down events.

Step 5: Finally...

The last step of developing a screensaver is short and sweet...rename the file to an .scr extension. Smile | :)

You are done!

Using the bundled code

The code provided just loads a black form. To change it and implement your own features, follow these simple steps:

  1. Change the code in the Main method to handle different arguments
  2. Add a configuration form if necessary, and add the code to load it in the Main method
  3. Modify the main screensaver form so as to display what you want it to
  4. Rename the extension from .exe to .scr.
  5. Go!


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Rakesh Rajan
Web Developer
India India
Rakesh Rajan is a Software Engineer from India working at Technopark, Trivandrum in Kerala. He is a Microsoft MVP and an MCSD (.NET) with a few other certifications, and had been working in .NET for the past 3 years. He graduated majoring in Computer Science during his memorable days at Ooty (a wonderful hill station in Southern India). You can find him posting at newgroups, writing articles, working on his own projects or taking some time off by listening to music by Enya or Yanni, or reading an Archer or Sheldon.

Find his online publications here.

Rakesh blogs at and maintains a site
He used to blog at

Drop him a mail at rakeshrajan {at} mvps {dot} org.

You may also be interested in...


Comments and Discussions

General/c not working for configuration on WinXP Pin
CoffeeZombie18-Dec-04 7:16
memberCoffeeZombie18-Dec-04 7:16 
GeneralCalling Alternate Screensaver Pin
Shindigo19-Nov-04 5:32
memberShindigo19-Nov-04 5:32 
GeneralRe: Calling Alternate Screensaver Pin
Rakesh Rajan28-Nov-04 15:01
memberRakesh Rajan28-Nov-04 15:01 
AnswerRe: License/Copyright? Pin
Rakesh Rajan19-Nov-04 4:52
memberRakesh Rajan19-Nov-04 4:52 
QuestionLicense/Copyright? Pin
Timothy Almond18-Nov-04 23:37
memberTimothy Almond18-Nov-04 23:37 
GeneralLaunching independent Process from screensaver Pin
matmupp11-Oct-04 2:33
membermatmupp11-Oct-04 2:33 
GeneralRe: Launching independent Process from screensaver Pin
Rakesh Rajan28-Nov-04 15:00
memberRakesh Rajan28-Nov-04 15:00 
GeneralMulti-screen saver... Pin
Anonymous7-Jul-04 8:16
sussAnonymous7-Jul-04 8:16 
GeneralRe: Multi-screen saver... Pin
Mingming Lu14-Jul-04 15:22
memberMingming Lu14-Jul-04 15:22 
GeneralRe: Multi-screen saver... Pin
Y-30331-Jul-04 17:18
sussY-30331-Jul-04 17:18 
GeneralRe: Multi-screen saver... Pin
MichaelCoder26-Sep-04 8:30
memberMichaelCoder26-Sep-04 8:30 
GeneralRe: Multi-screen saver... Pin
Y-30328-Mar-05 9:20
sussY-30328-Mar-05 9:20 
GeneralRe: Multi-screen saver... Pin
MichaelCoder30-Mar-05 10:15
memberMichaelCoder30-Mar-05 10:15 
QuestionRe: Multi-screen saver... the preview window Pin
Y-3039-Nov-05 4:13
memberY-3039-Nov-05 4:13 
GeneralHandling the config and mini-preview. Pin
Garryfre25-May-05 20:21
memberGarryfre25-May-05 20:21 
GeneralProblem with Win98 Pin
woolf446-Jun-04 6:02
memberwoolf446-Jun-04 6:02 
GeneralRe: Problem with Win98 Pin
woolf447-Jun-04 7:49
memberwoolf447-Jun-04 7:49 
GeneralUndapps... Pin
Anonymous4-Apr-04 20:28
sussAnonymous4-Apr-04 20:28 
Question.config-files? Pin
utomjording3-Mar-04 5:04
memberutomjording3-Mar-04 5:04 
AnswerRe: .config-files? Pin
Rakesh Rajan3-Mar-04 17:15
memberRakesh Rajan3-Mar-04 17:15 
GeneralRe: .config-files? Pin
Flanakin28-Oct-04 10:10
memberFlanakin28-Oct-04 10:10 
GeneralScreen Saver in C# Pin
Deepthi Devalarazu31-Jan-04 17:05
memberDeepthi Devalarazu31-Jan-04 17:05 
GeneralRe: Screen Saver in C# Pin
Flanakin28-Oct-04 10:40
memberFlanakin28-Oct-04 10:40 
General.Net Compact Framework Pin
nvaidya19-Jan-04 11:36
membernvaidya19-Jan-04 11:36 
GeneralRe: .Net Compact Framework Pin
Rakesh Rajan19-Jan-04 16:38
memberRakesh Rajan19-Jan-04 16:38 
General&quot;.exe&quot; to &quot;.scr&quot; Pin
Tiruvan3-Dec-03 12:29
memberTiruvan3-Dec-03 12:29 
GeneralRe: &quot;.exe&quot; to &quot;.scr&quot; Pin
Rakesh Rajan5-Dec-03 5:50
memberRakesh Rajan5-Dec-03 5:50 
GeneralRe: &amp;quot;.exe&amp;quot; to &amp;quot;.scr&amp;quot; [modified] Pin
D11131-May-06 7:42
memberD11131-May-06 7:42 
GeneralRe: &quot;.exe&quot; to &quot;.scr&quot; Pin
Cobler26-Jan-04 6:09
memberCobler26-Jan-04 6:09 
GeneralRe: &quot;.exe&quot; to &quot;.scr&quot; Pin
Rakesh Rajan28-Jan-04 0:18
memberRakesh Rajan28-Jan-04 0:18 
GeneralRe: &quot;.exe&quot; to &quot;.scr&quot; Pin
Cobler28-Jan-04 2:28
memberCobler28-Jan-04 2:28 
GeneralRe: &quot;.exe&quot; to &quot;.scr&quot; Pin
CoffeeZombie18-Dec-04 7:03
memberCoffeeZombie18-Dec-04 7:03 
GeneralRe: &quot;.exe&quot; to &quot;.scr&quot; Pin
leonluftwaffel31-Jan-05 10:18
memberleonluftwaffel31-Jan-05 10:18 
GeneralI must be missing something Pin
sysko27-Oct-03 6:47
membersysko27-Oct-03 6:47 
GeneralRe: I must be missing something Pin
Rakesh Rajan27-Oct-03 8:12
memberRakesh Rajan27-Oct-03 8:12 
GeneralRe: I must be missing something Pin
sysko27-Oct-03 11:29
membersysko27-Oct-03 11:29 
General!!! Pin
sysko27-Oct-03 11:41
membersysko27-Oct-03 11:41 
GeneralRe: !!! Pin
Rakesh Rajan27-Oct-03 21:13
memberRakesh Rajan27-Oct-03 21:13 
GeneralMissing information Pin
Michael Starr16-Oct-03 7:44
sussMichael Starr16-Oct-03 7:44 
GeneralRe: Missing information Pin
Rakesh Rajan24-Oct-03 7:49
memberRakesh Rajan24-Oct-03 7:49 
GeneralRe: Missing information Pin
Michael Starr24-Oct-03 8:16
sussMichael Starr24-Oct-03 8:16 
Questionamzing,is that realy all ??? Pin
Anonymous1-Oct-03 14:19
sussAnonymous1-Oct-03 14:19 
AnswerRe: amzing,is that realy all ??? Pin
Rakesh Rajan3-Oct-03 2:43
memberRakesh Rajan3-Oct-03 2:43 
QuestionProcess Priority? Pin
tonymudd4-Sep-03 22:14
membertonymudd4-Sep-03 22:14 
AnswerRe: Process Priority? Pin
Rakesh Rajan9-Sep-03 3:22
memberRakesh Rajan9-Sep-03 3:22 
GeneralRe: Process Priority? Pin
ForogarTree24-Nov-04 4:51
memberForogarTree24-Nov-04 4:51 
GeneralTHANK YOU! Pin
Anonymous2-Sep-03 14:16
sussAnonymous2-Sep-03 14:16 
GeneralRe: THANK YOU! Pin
Rakesh Rajan2-Sep-03 20:20
memberRakesh Rajan2-Sep-03 20:20 
GeneralGreat! Couple Questions Pin
alternex21-Aug-03 3:15
sussalternex21-Aug-03 3:15 
GeneralRe: Great! Couple Questions Pin
Rakesh Rajan21-Aug-03 3:42
memberRakesh Rajan21-Aug-03 3:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.160826.1 | Last Updated 12 Nov 2004
Article Copyright 2003 by Rakesh Rajan
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid