Page 1 of 1

Making a C# screen saver multiple monitor support, preview, and more

#1 jacobjordan  Icon User is offline

  • class Me : Perfection
  • member icon

Reputation: 113
  • View blog
  • Posts: 1,499
  • Joined: 11-June 08

Posted 30 November 2008 - 07:07 PM

First, let me clear one thing up. A screen saver is nothing more than a standard Windows executable with the .scr extension instead of the standard .exe extension. It has the same file format as an exe, and of course, you can make a .NET screen saver. You could take any old application you have on your computer, and give it a .scr extension, and you would have a perfectly valid Windows screen saver. However, you probably wouldn't want to do that. That's because screen savers do have certain responsibilities:

When Windows runs a screen saver, it will pass certain arguments to it. These arguments are "/s" (Show the screen saver), "/p" (preview the screen saver in the small little monitor on the screen saver selection dialog), and "/c" (Show the screen saver's options, or configure it). Windows expects your application to read these arguments in your screen saver's Main method, and act on them accordingly.

A screen saver usually takes up the whole screen. Thus, you must have some sort of exit signal built into the screen saver. Traditionally, a screen saver will exit if a key is pressed, or if the mouse is moved.

A screen saver also will stay on top of all other windows, and it will hide the cursor.

Reading the arguments

The only place you can read the arguments in a C# application is in the Main() method automatically generated. Go to the solution explorer. There should be a code file called "Program.cs". Open it up in the code editor. It might look close to this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace YourApplicationNamespace
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new YourApplicationMainForm());
        }
    }
}


All we are concerned with in that is the main method:
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new YourApplicationMainForm());
}


By default, the Main() method will take no arguments. You must edit it so it will take an argument of "string[] args" that way you will be able to read the arguments passed to your application:
static void Main(string[] args)
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new YourApplicationMainForm());
}


the args parameter will now hold all the arguments passed to your application. Now, you must interpret those arguments. Only one argument should be passed to a screen saver, the argument that tells the screen saver what windows wants it to do. We could read the arguments easily with a simple if statement like so:
if (args[0].ToLower().Trim().Substring(0,2) == "/s") //show
{
    //show the screen saver
}
else if (args[0].ToLower().Trim().Substring(0,2) == "/p") //preview
{
    //preview the screen saver
}
else if (args[0].ToLower().Trim().Substring(0,2) == "/c") //configure
{
    //configure the screen saver
}


However, it is possible for no arguments to be passed to a screen saver. Thus we should probably add in another if statement
if (args.Length > 0)
{
    if (args[0].ToLower().Trim().Substring(0,2) == "/s") //show
    {
        //show the screen saver
    }
    else if (args[0].ToLower().Trim().Substring(0,2) == "/p") //preview
    {
        //preview the screen saver
    }
    else if (args[0].ToLower().Trim().Substring(0,2) == "/c") //configure
    {
        //configure the screen saver
    }
}
else
{
    //no arguments were passed (we should probably show the screen saver)
}


That way, you won't get an index out of range exception if you try to reference the first argument passed and there is nothing there.

At this stage, we must now modify our main method to look like this
static void Main(string[] args)
{
    if (args.Length > 0)
    {
        if (args[0].ToLower().Trim().Substring(0,2) == "/s") //show
        {
            //show the screen saver
        }
        else if (args[0].ToLower().Trim().Substring(0,2) == "/p") //preview
        {
            //preview the screen saver
        }
        else if (args[0].ToLower().Trim().Substring(0,2) == "/c") //configure
        {
        //configure the screen saver
        }
    }
    else
    {
        //no arguments were passed (we should probably show the screen saver)
    }
}



Setting up the screen saver

At this point, if we try to run our application, it would run through like a console application with no code because we never invoke Application.Run() anywhere in our main. After we do a few things here, that will be taken care of. Now, i have made several screen savers in C# that support multiple monitors, and i will teach you the structure i use to make them. I'm not saying my way is the best, but it works and it's organized. To make multiple monitor support, instead of simply making a main form and stretching it to fill up all the screens, i make screen savers so it will show a different main form on every screen (by the way, whenever i refer to the main form in the code, i will call it "MainForm"). To do this, the System.Windows.Forms.Screen class comes in handy. Take a look at this code
foreach (Screen screen in Screen.AllScreens)
{
    MainForm screensaver = new MainForm(screen.Bounds);
    screensaver.Show();
}


The foreach loop you see is looping through all the screens (monitors) on the current computer. I am then creating a new main form for that monitor, passing it the bounds of that screen, and showing it. But wait a minute, that will not work because there is no constructor method in our main form that takes an argument. So, let us make one. I added this exact constructor to my main form
public MainForm(Rectangle Bounds)
{
    InitializeComponent();
    this.Bounds = Bounds;
    Cursor.Hide();
}


As you can see, it takes an argument of a System.Drawing.Rectangle (that's what bounds are) and in the constructor it would set the form's bounds to the one passed in the constructor. It would also hide the cursor, because like i said, screen savers hide the cursor.

So, to run the screen saver, we could create a method like so
void ShowScreenSaver()
{
    foreach (Screen screen in Screen.AllScreens)
    {
        MainForm screensaver = new MainForm(screen.Bounds);
        screensaver.Show();
    }
}


Typically, i will make a method like that to show the screensaver, and put that in the class my main method is in (Program). So, your Program class would now look like
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace YourApplicationNamespace
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                if (args[0].ToLower().Trim().Substring(0,2) == "/s") //show
                {
                    //show the screen saver
                }
                else if (args[0].ToLower().Trim().Substring(0,2) == "/p") //preview
                {
                    //preview the screen saver
                }
                else if (args[0].ToLower().Trim().Substring(0,2) == "/c") //configure
                {
                    //configure the screen saver
                }
            }
            else
            {
                //no arguments were passed (we should probably show the screen saver)
            }
        }

        static void ShowScreenSaver()
        {
            foreach (Screen screen in Screen.AllScreens)
            {
                MainForm screensaver = new MainForm(screen.Bounds);
                screensaver.Show();
            }
        }

    }
}

(Note we must make the ShowScreenSaver() method static when we put it in the Program class, as it is a static class)

now, let's modify our Main() method so it will actually use that method if our application was passed /s or if it was passed nothing
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace YourApplicationNamespace
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                if (args[0].ToLower().Trim().Substring(0,2) == "/s") //show
                {
                    //show the screen saver
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    ShowScreenSaver(); //this is the good stuff
                    Application.Run();
                }
                else if (args[0].ToLower().Trim().Substring(0,2) == "/p") //preview
                {
                    //preview the screen saver
                }
                else if (args[0].ToLower().Trim().Substring(0,2) == "/c") //configure
                {
                    //configure the screen saver
                }
            }
            else
            {
                //no arguments were passed (we should probably show the screen saver)
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                ShowScreenSaver(); //this is the good stuff
                Application.Run();
            }
        }

        static void ShowScreenSaver()
        {
            foreach (Screen screen in Screen.AllScreens)
            {
                MainForm screensaver = new MainForm(screen.Bounds);
                screensaver.Show();
            }
        }

    }
}


Guess what, we now have a working screen saver. Working, but not complete. We still need to make our main() method allow for /p and /c. We will now set it up for a /c (configure) argument as that is quite easy. Do you want the user to be able to choose some of the options in the screen saver? If so, simply create a form where the user can configure the options, and have your application so it will store those options in the application's settings, an ini file, the registry, or wherever. Now, we need only to modify the part of our main method that handles /c
else if (args[0].ToLower().Trim().Substring(0,2) == "/c") //configure
{
    //configure the screen saver
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new ConfigureForm()); //this is the good stuff
}

(in this code, i referred to the configuration form as "ConfigureForm", but that can be changed)

Notice i am using an Application.Run() call to start the application, and all i am doing is passing it the configuration form as the application's main form.

On the other hand, if you don't have any options the user can set, we can do something very easy like so
else if (args[0].ToLower().Trim().Substring(0,2) == "/c") //configure
{
    //nothing to configure
    MessageBox.Show("This screensaver has no options that you can set",
        "My Cool Screen Saver",
        MessageBoxButtons.OK,
        MessageBoxIcon.Information);
}


That will show a message telling the user the screen saver has no configurable options. Then, since we never invoked Appliction.Run(), the application will exit once the main method has run through, like a console application.

Now we can handle the /p (preview) argument. The preview is when Windows wants your screen saver to preview itself in the little computer monitor on the screen saver dialog. There are two ways we can go about this. Generally, i choose to screw the preview all together. By the way, if you don't want a preview, your done. You don't need any code in the section that handles the preview, so when Windows calls your application to preview, it will start, run through, and since the Application.Run() was never called, it will close in an inconceivably small amount of time like it never even ran. That was easy, however, if you so desire for your screen saver to have a preview, i will teach you how.

Setting up the preview

This is a bit tricky. It takes a few API's to do. Windows will not automatically do some voodoo magic to make your application show perfectly in the preview window, you have to do it on your own. It does, however, lend you some help. When Windows passes your application the /p command, it will also pass another argument: the handle to the preview window on the select screen saver dialog. With that, we can use a few API's to make it the parent of our screen saver's main form. This is how it will work:

1. The main function will see the first argument is /p. It then knows the second argument is the handle to the preview window.

2. The main function will run the application with MainForm as the main form using Application.Run(). It will also pass the main form the handle to the preview window.

3. The main form will configure itself so that it will show inside the preview window.

4. They all lived happily ever after.

Lets start to implement that. First, let me refresh your (and my) mind of what the section of our main routine that handles /p looks like
else if (args[0].ToLower().Trim().Substring(0,2) == "/p") //preview
{
    //preview the screen saver
}


As it is now, it is set up in a way where there will be no preview since there is no code except for that lonely little comment. We must modify that to look like this
else if (args[0].ToLower().Trim().Substring(0,2) == "/p") //preview
{
    //show the screen saver preview
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    //args[1] is the handle to the preview window
    Application.Run(new MainForm(new IntPtr(long.Parse(args[1]))));
}


Looks like that comment's not so lonely anymore. Anyway, that should be all you need to do to the main function. However, see the line
Application.Run(new MainForm(new IntPtr(long.Parse(args[1]))));


That is passing MainForm the handle to the preview window in the form of an IntPtr. However, we have no constructor made for that form that will accept an IntPtr. Well, time to make one. Guess what, you don't have to do any work again because all you have to do is use this code i've already written
        //This constructor is the handle to the select screen saver dialog preview window
        //It is used when in preview mode (/p)
        public MainForm(IntPtr PreviewHandle)
        {
            InitializeComponent();

            //set the preview window as the parent of this window
            SetParent(this.Handle, PreviewHandle);

            //make this a child window, so when the select screen saver dialog closes, this will also close
            SetWindowLong(this.Handle, -16, new IntPtr(GetWindowLong(this.Handle, -16) | 0x40000000));

            //set our window's size to the size of our window's new parent
            Rectangle ParentRect;
            GetClientRect(PreviewHandle, out ParentRect);
            this.Size = ParentRect.Size;

            //set our location at (0, 0)
            this.Location = new Point(0, 0);

            IsPreviewMode = true;
        }


In case you haven't figured out, i am making a real screen saver as i am writing this tutorial. Anyway, that is exactly what you should use. But wait a minute, that is gonna throw a whole bunch of errors at you if you try to use it right now. That's because there are four API's i'm using in there aren't in your code yet. Here they are
#region Preview API's

[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

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

[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);

#endregion


I believe i did a fairly good job of explaining exactly what is going on in my comments, so i'll move on. Oh, and about that variable in the constructor i gave you called IsPreviewMode. That is to let the application know weather or not it is in preview mode when it's running. If you are making a screen saver as you are reading this, make a global boolean called IsPreviewMode. You will need a variable like that because when you are in preview mode, you want to disable any mouse or key events that will make the screen saver exit. For example, if you had a key down event that had code in it to exit the application, you would want to put an if statement around that to make sure your application is not in preview mode. Why? When your screen saver is previewing in the preview window on the select screen saver dialog, any time you moved your mouse over the preview window, pressed a key, or clicked the preview window, you certainly don't want the preview to go away, and that is what will happen if we don't take those precautions. You can also use the IsPreviewMode variable to make it so certain code won't run through when in preview mode, and so code will run through in preview mode that won't run in standard mode. That can be very useful.

Putting it all together

Ok, this is about what your Program.cs file should look like at this point:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace YourApplicationNamespace
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                if (args[0].ToLower().Trim().Substring(0, 2) == "/s") //show
                {
                    //run the screen saver
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    ShowScreensaver();
                    Application.Run();
                }
                else if (args[0].ToLower().Trim().Substring(0, 2) == "/p") //preview
                {
                    //show the screen saver preview
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    //args[1] is the handle to the preview window
                    Application.Run(new MainForm(new IntPtr(long.Parse(args[1]))));
                }
                else if (args[0].ToLower().Trim().Substring(0, 2) == "/c") //configure
                {
                    //Show the configuration dialog, or inform the user there are no options with a message box here
                }
                else //an argument was passed, but it wasn't /s, /p, or /c, so we don't care wtf it was
                {
                    //show the screen saver anyway
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    ShowScreensaver();
                    Application.Run();
                }
            }
            else //no arguments were passed
            {
                //run the screen saver
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                ShowScreensaver();
                Application.Run();
            }

        }

        //will show the screen saver
        static void ShowScreensaver()
        {
            //loops through all the computer's screens (monitors)
            foreach (Screen screen in Screen.AllScreens)
            {
                //creates a form just for that screen and passes it the bounds of that screen
                MainForm screensaver = new MainForm(screen.Bounds);
                screensaver.Show();
            }
        }
    }
}


And just to be clear, these are the two new constructors you should have put in your MainForm (you will only have the top one if you chose not to do a preview)
        //This constructor is passed the bounds this form is to show in
        //It is used when in normal mode
        public Form1(Rectangle Bounds)
        {
            InitializeComponent();
            this.Bounds = Bounds;
            //hide the cursor
            Cursor.Hide();
        }

        //This constructor is the handle to the select screensaver dialog preview window
        //It is used when in preview mode (/p)
        public Form1(IntPtr PreviewHandle)
        {
            InitializeComponent();

            //set the preview window as the parent of this window
            SetParent(this.Handle, PreviewHandle);

            //make this a child window, so when the select screensaver dialog closes, this will also close
            SetWindowLong(this.Handle, -16, new IntPtr(GetWindowLong(this.Handle, -16) | 0x40000000));

            //set our window's size to the size of our window's new parent
            Rectangle ParentRect;
            GetClientRect(PreviewHandle, out ParentRect);
            this.Size = ParentRect.Size;

            //set our location at (0, 0)
            this.Location = new Point(0, 0);

            IsPreviewMode = true;
        }



Now, with what we have thus far, we are pretty good to go, but there's still one more thing we need to do. We absolutely have to add in functions that will make the screen saver exit when a key is pressed, the screen saver is clicked, or if the mouse is moved significantly over the screen saver. All you really have to do is something like this

        #region User Input

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            //** take this if statement out if your not doing a preview
            if (!IsPreviewMode) //disable exit functions for preview
            {
                Application.Exit();
            }
        }

        private void Form1_Click(object sender, EventArgs e)
        {
            //** take this if statement out if your not doing a preview
            if (!IsPreviewMode) //disable exit functions for preview
            {
                Application.Exit();
            }
        }

        //start off OriginalLoction with an X and Y of int.MaxValue, because
        //it is impossible for the cursor to be at that position. That way, we
        //know if this variable has been set yet.
        Point OriginalLocation = new Point(int.MaxValue, int.MaxValue);

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            //** take this if statement out if your not doing a preview
            if (!IsPreviewMode) //disable exit functions for preview
            {
                //see if originallocation has been set
                if (OriginalLocation.X == int.MaxValue & OriginalLocation.Y == int.MaxValue)
                {
                    OriginalLocation = e.Location;
                }
                //see if the mouse has moved more than 20 pixels in any direction. If it has, close the application.
                if (Math.Abs(e.X - OriginalLocation.X) > 20 | Math.Abs(e.Y - OriginalLocation.Y) > 20)
                {
                    Application.Exit();
                }
            }
        }

        #endregion


Now, you obviously can't just copy/paste that because you have to make those functions event handlers. Anyway, that won't be hard at all. Note that i used an Application.Exit() call instead of a this.close() because, though i call it MainForm, it really isn't a "Main Form" because if it is closed the application will still keep on running. To fix that, we simply use the Application.Exit() call. Now, there's only one thing you have left to do: change the extension of your build application from .exe to .scr, and if you want to use it as a screen saver on your computer, copy it into the system32 directory and set it as your screen saver.

I said i was making a real screen saver as i was writing this tutorial, and it's only fair i give it to you as an example. The screen saver i made shows a fake, but highly authentic blue screen of death, like the BSOD screen saver on SysInternals. Anyway, that's not the point. The point is that it demonstrates everything i have said. It also has a preview.

Attached File  Blue_Screen_saver.zip (98.3K)
Number of downloads: 3224

Is This A Good Question/Topic? 2
  • +

Replies To: Making a C# screen saver

#2 Bit-Smacker  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 26-June 09

Posted 26 June 2009 - 01:51 PM

Has anyone else been able to get the download? Its preferences show 91.0 KB (93,244 bytes), but the archive is corrupt. I tried using a repair tool and it says "Archive incomplete."
Was This Post Helpful? 0
  • +
  • -

#3 jacobjordan  Icon User is offline

  • class Me : Perfection
  • member icon

Reputation: 113
  • View blog
  • Posts: 1,499
  • Joined: 11-June 08

Posted 29 June 2009 - 04:15 PM

Downloads and extracts fine for me.

If for some reason it's still corrupt, you can also download it at http://www.codeproje...creen_saver.zip.
Was This Post Helpful? 0
  • +
  • -

#4 ondra.cifka  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 01-August 09

Posted 01 August 2009 - 08:35 AM

How do you make the configuration window modal or make it close when the Windows Screen Saver dialog closes? When I click the Settings Button in the Screen Saver dialog, the configuration is shown but I can still access the Windows dialog. I can't click the Settings button or the Preview button, but I can close it. When I open it again, I can run the screensaver or open a new instance of the configuration window although the original window is still running.
I've noticed that other screen savers' config windows are modal. Do I also receive a pointer to the parent window with the /c argument? How do I make my window modal then?
Was This Post Helpful? 0
  • +
  • -

#5 dimapasko  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 04-August 09

Posted 04 August 2009 - 04:57 AM

You can use NConsoler for Command arguments parsing
Was This Post Helpful? 0
  • +
  • -

#6 Notorion  Icon User is offline

  • D.I.C Regular

Reputation: 35
  • View blog
  • Posts: 378
  • Joined: 17-February 09

Posted 09 August 2009 - 06:50 AM

My compiler (C# Express 2008) doesn't recognize using System.Windows.Forms;

It also reads that "Application" does not exist in this context.
Anyone know how to fix as I am new to c#?
Was This Post Helpful? 0
  • +
  • -

#7 ondra.cifka  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 01-August 09

Posted 09 August 2009 - 08:02 AM

View Postdimapasko, on 4 Aug, 2009 - 03:57 AM, said:

You can use NConsoler for Command arguments parsing

I know how to parse arguments. But how to use the parsed handle to create a modal window?
Was This Post Helpful? 0
  • +
  • -

#8 debjit625  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 51
  • View blog
  • Posts: 446
  • Joined: 06-September 08

Posted 28 August 2009 - 01:40 PM

Everybody is just saying about their problems,who will say that this tutorial is cool? ,offcourse... thats me, man this is cool and also hot.
Was This Post Helpful? 1
  • +
  • -

#9 SamuelHenderson  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 11
  • Joined: 31-August 09

Posted 31 August 2009 - 02:05 PM

I'm having some problems getting this to run properly with multiple monitors. The screen saver runs fine on the first monitor but is not shown at all on the second.

I downloaded the sample and tried that and found the same issue.

Under the 'Settings' tab in 'Display Properties' I have two displays listed:

1. Plug and Play Monitor on 256mb ATI Radeon X600
2. Plug and Play Monitor on 256mb ATI Radeon X600 Secondary

Also,

When trying to use the Visual Studio debugger I find I can step through the code to here:
static void ShowScreenSaver()
{
	foreach (Screen screen in Screen.AllScreens)
	{
		ScreenSaverForm screenSaver = new ScreenSaverForm(screen.Bounds);
		screenSaver.Show();  // Seems to hang on entering this method.	
	 }
}



when the screen becomes unresponsive and the mouse is hidden. It almost seems like the ScreenSaver is in fact running, but hasn't drawn anything to screen. And the keyboard & mouse don't stop the screen saver. If I bring up the taskmanager I can kill the screen saver vshost process and everything goes back to normal.

For reference, I used the Visual Studio 2005's "C# Screen Saver Starter Kit" and modified the ShowScreenSaver() and ScreenSaverForm() methods accordingly.

Does anyone know whats wrong? The default screen savers included with Windows XP are working fine with Dual Monitors...
Was This Post Helpful? 0
  • +
  • -

#10 SamuelHenderson  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 11
  • Joined: 31-August 09

Posted 08 September 2009 - 08:50 AM

View PostSamuelHenderson, on 31 Aug, 2009 - 01:05 PM, said:

I'm having some problems getting this to run properly with multiple monitors. The screen saver runs fine on the first monitor but is not shown at all on the second.

I downloaded the sample and tried that and found the same issue.

Under the 'Settings' tab in 'Display Properties' I have two displays listed:

1. Plug and Play Monitor on 256mb ATI Radeon X600
2. Plug and Play Monitor on 256mb ATI Radeon X600 Secondary

Also,

When trying to use the Visual Studio debugger I find I can step through the code to here:
static void ShowScreenSaver()
{
	foreach (Screen screen in Screen.AllScreens)
	{
		ScreenSaverForm screenSaver = new ScreenSaverForm(screen.Bounds);
		screenSaver.Show();  // Seems to hang on entering this method.	
	 }
}



when the screen becomes unresponsive and the mouse is hidden. It almost seems like the ScreenSaver is in fact running, but hasn't drawn anything to screen. And the keyboard & mouse don't stop the screen saver. If I bring up the taskmanager I can kill the screen saver vshost process and everything goes back to normal.

For reference, I used the Visual Studio 2005's "C# Screen Saver Starter Kit" and modified the ShowScreenSaver() and ScreenSaverForm() methods accordingly.

Does anyone know whats wrong? The default screen savers included with Windows XP are working fine with Dual Monitors...


Just in case anyone stumbles across this tutorials and is experiencing the same problem I was having, the solution can be found in this forum thread

This post has been edited by SamuelHenderson: 08 September 2009 - 08:51 AM

Was This Post Helpful? 0
  • +
  • -

#11 Vermiculus  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 10
  • View blog
  • Posts: 314
  • Joined: 26-February 09

Posted 03 December 2009 - 07:47 PM

View PostBit-Smacker, on 26 Jun, 2009 - 12:51 PM, said:

Has anyone else been able to get the download? Its preferences show 91.0 KB (93,244 bytes), but the archive is corrupt. I tried using a repair tool and it says "Archive incomplete."


The file likely did not complete downloading (it is 98.3 KB [100,660b]) If it never reached an end of file marker, that would make sense.

Hopefully you tried re-downloading?
Was This Post Helpful? 0
  • +
  • -

#12 Guest_Gecko*


Reputation:

Posted 16 February 2010 - 01:05 AM

If I have 5 pictures in my drive, how can I make that pictures to be my screen saver?
Was This Post Helpful? 0

Page 1 of 1