Disable Screen Saver while running your WPF Application

I'm working on a WFP Media player application, and the first time I used it to watch a video, I just discovered I had forgotten something critical when the screen went black and a 3D stylish 'Woosh' apperead : that f***ing screen saver !

But how to disable it ?!
First I searched the Internet and found something to disable it in the registry. But I don't like this, you need rights to write the registry, and how can you turn the screen saver back if your application quit unexpectedly (Ok you'll say it won't, it's well written, but I can kill it with the task manager :-S ). No way.

Then I found something about the WM_SYSCOMMAND message. The window receives this message with a value of SC_SCREENSAVE when the screen saver should appear and you can prevent it to run by handling the message without doing anything. You can also get the SC_MONITORPOWER value when the monitor enters a low consumption state.

I like it ! But the point is how to handle this Win32 message in WPF, the no-windows-message world ?

Actually, the main WPF Window is hosted in a Win32 window, represented by a HwndSource object. You can get this object using the PresentationSource.FromVisual method. The HwndSource the provides a AddHook method that takes a Hook delegate that you can use to handle the message. It's a bit too easy.

There is just one last thing. Calling PresentationSource.FromVisual from the Window constructor will return null since the window initialization is not terminated and it's not already hosted by the Win32 host. Just call it from the SourceInitialized event.

A minimal sample to summary all we said :

    public partial class MainWindow : Window

    {

        private const int WM_SYSCOMMAND = 0x112;

        private const int SC_SCREENSAVE = 0xF140;

        private const int SC_MONITORPOWER = 0xF170;

 

        public MainWindow()

        {

            SourceInitialized += delegate

            {

                HwndSource source = (HwndSource)

                    PresentationSource.FromVisual(this);

                source.AddHook(Hook);

            };

        }

 

        private static IntPtr Hook(IntPtr hwnd,

            int msg, IntPtr wParam, IntPtr lParam,

            ref bool handled)

        {

            if (msg == WM_SYSCOMMAND &&

                ((((long)wParam & 0xFFF0) == SC_SCREENSAVE) ||

                ((long)wParam & 0xFFF0) == SC_MONITORPOWER))

                handled = true;

            return IntPtr.Zero;

        }

    }

Just notice the 0xFFF0 mask, it's because the system can use the 4 low order bits of the wParam value as stated in the MSDN library article about WM_SYSCOMMAND.

Now I can watch videos without mooving the mouse every 10 minutes ! I hope it can make your apps better to !

posted on Tuesday, February 27, 2007 11:46 PM

Feedback

# Temporarily Disable Screensaver in your WPF Code 9/26/2007 5:21 AM POKE 53280,0: Pete Brown's Blog

I wrote a small media player for my son. I wrote the original version in Silverlight, but quickly ran

# Temporarily Disable Screensaver in your WPF Code 6/29/2008 5:45 AM DEVELOPMENT SITE - NOT MY PUBLIC BLOG

<p>I wrote a small media player for my son. I wrote the original version in Silverlight, but quickly ran into a problem where no matter what I did, Silverlight wouldn&#39;t read the larger video files (encoding was fine, so I&#39;m pretty sure this is a 1.1 alpha bug). Anyway, I rewrote it as a WPF app...</p>

Title
 
Name
 
Url
Comments   
Protected by Clearscreen.SharpHIPEnter the code you see: