Turn On/Off Monitor

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



Leave a reply



Submit