Introduction
I have looked for a way to turn off the display when I lock the computer but I only found some solutions that use custom libraries or applications that are running in the background and waiting for the respective event to happen.
I think that these approaches are overcomplicating things so I have written a simple Windows application which does this task by using two APIs from user32.dll.
Background
- Managed code can make calls to unmanaged code using the '
DllImport
' attribute. [More] - Windows applications are event-driven and use messages to communicate with the system.
title="About Messages and Message Queues">[More]
Using the code
Locking up the PC can be achieved by calling the LockWorkStation
method from 'user32.dll', while powering off the display can be realised by sending the corresponding
Windows message using the PostMessage
or SendMessage
functions also from 'user32.dll'.
In order to be able to access these functions, the DllImport
attribute must be used:
[DllImport("user32.dll")]
private static extern void LockWorkStation();
[DllImport("user32.dll", SetLastError = true)]
private static extern bool PostMessage(IntPtr hWnd, uint msg,
IntPtr wParam, IntPtr lParam);
Now that we have access to them, we can use the PostMessage
function to place our message in the queue.
The PostMessage
function posts a message in the message queue and returns immediately (unlike SendMessage
which waits for the message to be processed).
Here are the parameters needed for shutting off the display:
- handler to the window which should receive the
msg
- set this to broadcast (0xFFFF) - message type - this should be set to system command (0x0112)
wParam
- type of system command requested - the needed type is (0xF170
), this sets the state of the displaylParam
- should be 2 (the display is being shut off).
You can find more information about this type of message
title="More info about WM_SYSCOMMAND message">here.
private const int WmSyscommand = 0x0112;
private const int ScMonitorpower = 0xF170;
private const int HwndBroadcast = 0xFFFF;
private const int ShutOffDisplay = 2;
The only thing left to do is calling the function with the previous parameters, as follows :
PostMessage((IntPtr)HwndBroadcast, (uint)WmSyscommand,
(IntPtr)ScMonitorpower, (IntPtr)ShutOffDisplay);
Here is everything put together:
namespace Lock_Display
{
static class Program
{
private const int WmSyscommand = 0x0112;
private const int ScMonitorpower = 0xF170;
private const int HwndBroadcast = 0xFFFF;
private const int ShutOffDisplay = 2;
[DllImport("user32.dll")]
private static extern void LockWorkStation();
[DllImport("user32.dll", SetLastError = true)]
private static extern bool PostMessage(IntPtr hWnd, uint msg,
IntPtr wParam, IntPtr lParam);
private static void TurnOffDisplay()
{
PostMessage((IntPtr)HwndBroadcast, (uint)WmSyscommand,
(IntPtr)ScMonitorpower, (IntPtr)ShutOffDisplay);
}
[STAThread]
static void Main()
{
LockWorkStation();
TurnOffDisplay();
}
}
}