Original Post
Hey all... I'm having problems disabling the screensaver in C# code. I'm trying to make a program which disables the screensaver, launches another program, waits for that program to exit, and then re-enables the screensaver. However, the following code does not work. The program launches fine, and then my program quits after the launched program exits as it is supposed to, but it does not block the screensaver from appearing. I tried inserting a breakpoint in my code inside the PreFilterMessage method, but the breakpoint is never hit. I have also tried creating and showing a blank form, my reasoning being that maybe I needed at least one window for this to work, but that had no success. Anyone have any ideas? Thanks. - Fuzz
// App.cs
// Screen Saver Suppressor
using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
/// <summary>
/// Main application class.
/// </summary>
class App
{
/// <summary>
/// Main entry point.
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
// Check command line arguments.
if(args.Length != 1)
{
Console.WriteLine("There must be exactly one command line argument, which is the target application.");
return;
}
// Disable screensaver.
Application.AddMessageFilter(new ScreensaverFilter());
// Run target app.
Process proc = Process.Start(args[0]);
// Handle windows events.
Thread thread = new Thread(Application.Run);
thread.Start();
// Wait until target app exits.
proc.WaitForExit();
// Kill other thread.
Application.Exit();
thread.Abort();
thread.Join();
}
}
/// <summary>
/// Filters out screensaver messages.
/// </summary>
class ScreensaverFilter : IMessageFilter
{
#region Constants
private const int WM_SYSCOMMAND = 0x0112;
private const int SC_SCREENSAVE = 0xF140;
private const int SC_MONITORPOWER = 0xF170;
#endregion
#region Methods
/// <summary>
/// Returns whether the specified message should be filtered.
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public bool PreFilterMessage(ref Message m)
{
if(m.Msg == WM_SYSCOMMAND && (m.WParam.ToInt32() == SC_SCREENSAVE || m.WParam.ToInt32() == SC_MONITORPOWER))
{
// <-- BREAKPOINT HERE
m.Result = new IntPtr(0);
return true;
}
else
{
return false;
}
}
#endregion
}