Find out if monitor is off

825 views
Skip to first unread message

lukky...@gmail.com

unread,
Apr 13, 2008, 2:27:32 PM4/13/08
to
Hi everyone:


I've been directed to this thread from the win32.programmer.kernel
with the following question:

Is there a way to tell if a computer monitor is off (from a program)?


This looks like a trivial task, but I can't seem to find a documented
solution from MS. I tried Win32_DesktopMonitor WMI class, which
returned the same (wrong) results under Win XP, and now someone
suggested me to refer to undocumented APIs. At this point I reached a
deadend, so any help would be greatly appreciated.

Sebastian G.

unread,
Apr 13, 2008, 2:47:30 PM4/13/08
to
lukky...@gmail.com wrote:


> I've been directed to this thread from the win32.programmer.kernel
> with the following question:
>
> Is there a way to tell if a computer monitor is off (from a program)?


Unless the power button becomes part of the data that can be queried via
DDI, the answer is no.

Christian ASTOR

unread,
Apr 13, 2008, 3:51:10 PM4/13/08
to
lukky...@gmail.com wrote:

> Is there a way to tell if a computer monitor is off (from a program)?

If you're talking about monitor power :
On Vista, normally WM_POWERBROADCAST.
Otherwise, there is NtGetDevicePowerState(), which works for me (tested
on XP SP2) - PowerDeviceD0 : On, PowerDeviceD3 : Off, but may not work
depending on the video driver.
Another simple method is to compare SPI_GETPOWEROFFTIMEOUT (if ACTIVE)
with the current idle time (GetLastInputInfo())

lukky...@gmail.com

unread,
Apr 13, 2008, 6:31:57 PM4/13/08
to
On Apr 13, 12:51 pm, Christian ASTOR <casto...@club-internet.fr>
wrote:


Thanks a lot, Christian. I see your point with SPI_GETPOWEROFFTIMEOUT
and GetLastInputInfo, but I'd really like to try the
NtGetDevicePowerState() method. Unfortunately I'm not very good with
NT kernel mode programming and I can't find any info on it. Can you
please post a small sample of how you use it to get monitor power
state? I tried a more documented GetDevicePowerState but I can't get a
monitor handle for it.

Thanks in advance.

Christian ASTOR

unread,
Apr 14, 2008, 4:28:38 AM4/14/08
to
On 14 avr, 00:31, lukkycha...@gmail.com wrote:

> Thanks a lot, Christian. I see your point with SPI_GETPOWEROFFTIMEOUT and GetLastInputInfo, but I'd really like to try the NtGetDevicePowerState() method. Unfortunately I'm not very good with
> NT kernel mode programming and I can't find any info on it. Can you
> please post a small sample of how you use it to get monitor power
> state? I tried a more documented GetDevicePowerState but I can't get a monitor handle for it.

I test it like this =>

// ...
#include <ntsecapi.h> // for NTSTATUS
// ...
typedef NTSTATUS (WINAPI *NTGETDEVICEPOWERSTATE)(HANDLE hDevice,
PDEVICE_POWER_STATE pPowerState );
NTGETDEVICEPOWERSTATE pNtGetDevicePowerState;

// ...

HANDLE hDevice;
hDevice = CreateFile("\\\\.\\LCD", GENERIC_READ, FILE_SHARE_READ,NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
if (hDevice != INVALID_HANDLE_VALUE)
{
DEVICE_POWER_STATE PowerState = PowerDeviceUnspecified;
HMODULE hNTDLL = GetModuleHandle ("NTDLL.DLL");
if (hNTDLL)
{
pNtGetDevicePowerState =
(NTGETDEVICEPOWERSTATE)GetProcAddress(hNTDLL,
"NtGetDevicePowerState");
if (pNtGetDevicePowerState)
{
NTSTATUS nStatus = pNtGetDevicePowerState(hDevice, &PowerState);
if (nStatus == 0)
{
if (PowerState != PowerDeviceD0)
{
//....
}
}
}
FreeLibrary(hNTDLL);
}
}

lukky...@gmail.com

unread,
Apr 14, 2008, 5:33:07 AM4/14/08
to
> }- Hide quoted text -
>
> - Show quoted text -


Thanks, Christian. A very good piece of code! Unfortunately it didn't
work for me as I hoped. At the same time I came across the same-
looking piece of code, where an author called CreateFile with "\\.
\DISPLAY#", (where # stands for a display number) but to everyone's
chagrin it always returned error with the ACCESS_DENIED code. Your way
of calling it with \\.\LCD lets CreateFile to succeed but
unfortunately on my both PCs (XP SP2, LCD and CRT monitors) the
pNtGetDevicePowerState() always returned PowerDeviceD0 (even when a
monitor was in a power saving mode). Damn it! I was so hoping for it.

It looks like I will have to stick with your other proposed method
(SPI_GETPOWEROFFTIMEOUT and GetLastInputInfo), which unfortunately
isn't bullet-proof either (example, what if one of the apps is
blocking the WM_SYSCOMMAND, SC_SCREENSAVE notification thus preventing
the screen from going into a power saving mode. This will not reset
the idle counter but will keep the screen on.)

Sten Westerback (MVP SDK 2005-6 :)

unread,
Apr 16, 2008, 3:20:22 AM4/16/08
to

<lukky...@gmail.com> wrote in message
news:b8b87e00-68b1-4595...@q10g2000prf.googlegroups.com...

Firstly i can't think of a reason why any code would block on WM_SYSCOMMAND.
One should always process WM_SYS* messages ASAP by posting a message to
yourself or setting some flag/event if you need more time.

Also, there is a SC_MONITORPOWER but my local reference didn't say when it
has been introduced.

- Sten


jim clark

unread,
Apr 16, 2008, 10:46:20 AM4/16/08
to
You can get this information using the Setup API - You need to enumerate all
'monitor' devices and find the power state. This works on XP and later (the
information is the same as that shown in Device Manager). As noted already
you can't open \\.\DISPLAY although this would work with just about every
other device. Obviously the information returned is only as a good as what
Windows 'thinks' the power state is.

James


"Sten Westerback (MVP SDK 2005-6 :)"
<REMOVE_UPPERCASEe...@nokia.com> wrote in message
news:1208330422.485705@xnews001...

Reply all
Reply to author
Forward
0 new messages