How to turn on/off the monitor(s)?
I have successfully tested this on Windows XP and Windows 7:
const
MONITOR_ON = -1;
MONITOR_OFF = 2;
MONITOR_STANDBY = 1;
To turn off the monitor:
SendMessage(Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, MONITOR_OFF);
To turn on the monitor:
SendMessage(Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, MONITOR_ON);
Turn off the monitor in windows
From Fumbling around in the dark and stumbling across the wrong solution:
the desktop window is a very special window and as a rule should be avoided, since it won't behave like windows created by applications. In particular, the author tried to post a message to the desktop window. This used to work in the historically open world of the window manager, but security and robustness concerns have come to take priority over compatibility.
The real solution is to create your own window and send it the message, anything else is a hack.
If you don't mind hacks, at least try to find a suitable window:
[DllImport("user32.dll", SetLastError = false)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
const int SC_MONITORPOWER = 0xF170;
const int WM_SYSCOMMAND = 0x0112;
const int MONITOR_OFF = 2;
static void Main(string[] args)
{
IntPtr w;
for (; IntPtr.Zero == (w = GetForegroundWindow());) System.Threading.Thread.Sleep(1000);
PostMessage(w, WM_SYSCOMMAND, (IntPtr) SC_MONITORPOWER, (IntPtr) MONITOR_OFF);
}
And because it is a hack there are where times it might not work. The window you are borrowing might be destroyed before you post the message. You might not have the right to send messages to it (UAC). Or it might decide to not pass this message to DefWindowProc
.
Another slightly better hack is to create a temporary window:
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
static extern int DestroyWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError=true)]
public static extern IntPtr CreateWindowEx(uint dwExStyle, string lpClassName, IntPtr cap, uint dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
const int SC_MONITORPOWER = 0xF170;
const int WM_SYSCOMMAND = 0x0112;
const int MONITOR_OFF = 2;
static void Main(string[] args)
{
IntPtr w = CreateWindowEx(0, "Button", IntPtr.Zero, 0, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
if (w != IntPtr.Zero)
{
SendMessage(w, WM_SYSCOMMAND, (IntPtr) SC_MONITORPOWER, (IntPtr) MONITOR_OFF);
DestroyWindow(w);
}
}
This is still somewhat of a hack because it never actually pumps messages.
How do you turn on and off a monitor from within a Java application?
Assuming you deploy your Java Applications on Windows, you can use this WIN32API functions:
// turn off monitor
SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) 2);
// turn on monitor
SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) -1);
Then you write a little C-JNI wrapper to functions that call the mentioned SendMessage
and use the little wrapper to turn off the monitor from Java.
Python turn screen on and off on Windows
Not a actual solution to the issue where it just turns as soon as it turns on, but I found a way to keep it not going off.
Not a very great way but it works
import time
import ctypes
import win32api, win32con
def screen_off():
ctypes.windll.user32.SendMessageW(65535, 274, 61808, 2)
def screen_on():
ctypes.windll.user32.SendMessageW(65535, 274, 61808, -1)
move_cursor()
def move_cursor():
x, y = (0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, x, y)
screen_off()
time.sleep(3)
screen_on()
If you move the cursor or type something the screen will stay on, so
Turning off monitor in C
This does the same thing as xset dpms force off
:
#include <X11/Xlib.h>
#include <X11/extensions/dpms.h>
#include <err.h>
int main(void){
Display *dpy;
if(!(dpy = XOpenDisplay(0)))
errx(1, "cannot open display '%s'", XDisplayName(0));
DPMSEnable(dpy);
DPMSForceLevel(dpy, DPMSModeOff);
XSync(dpy, False);
}
compile it with cc xdfo.c -o xdfo -lX11 -lXext
.
xset
also sleeps 100 ms after the DPMSEnable
, I have no idea why it does that.
Turn off the monitor?
Use the SC_MONITORPOWER
parameter for the WM_SYSCOMMAND
message to turn off the monitor:
SendMessage(handle, WM_SYSCOMMAND, SC_MONITORPOWER, 2);
The argument 2
for the fourth parameter turns the monitor off.
See also https://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx
Related Topics
Weird Error Upgrading ASP.NET MVC from 4 to 5
Webdriverwait Is Not Waiting for the Element I Specify
Best Practice to Return Errors in ASP.NET Web API
Single Controller with Multiple Get Methods in ASP.NET Web API
How to Securely Save Username/Password (Local)
Why Can't I Have Abstract Static Methods in C#
System.Text.JSON.JSONelement Toobject Workaround
The Entity Type <Type> Is Not Part of the Model for the Current Context
Omitting All Xsi and Xsd Namespaces When Serializing an Object in .Net
Padding Is Invalid and Cannot Be Removed
Does the C# "Finally" Block Always Execute
Check for Column Name in a SQLdatareader Object
Generating Permutations of a Set (Most Efficiently)
"A Project with an Output Type of Class Library Cannot Be Started Directly"
Two Different Dll with Same Namespace
How to Use Openfiledialog to Select a Folder
Why Does This Async Action Hang When I Try and Access the Result Property of My Task