From: lukkycharm1 on
On Apr 14, 1:28 am, Christian ASTOR <casto...(a)club-internet.fr> wrote:
> On 14 avr, 00:31, lukkycha...(a)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);
>         }
>
>
>
> }- 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.)
From: Sten Westerback (MVP SDK 2005-6 :) on

<lukkycharm1(a)gmail.com> wrote in message
news:b8b87e00-68b1-4595-9fb6-39e189e1b6e9(a)q10g2000prf.googlegroups.com...
On Apr 14, 1:28 am, Christian ASTOR <casto...(a)club-internet.fr> wrote:
> On 14 avr, 00:31, lukkycha...(a)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);
> }
>
>
>
> }- 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.)

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


From: jim clark on
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_UPPERCASEext-sten.westerback(a)nokia.com> wrote in message
news:1208330422.485705(a)xnews001...
>
> <lukkycharm1(a)gmail.com> wrote in message
> news:b8b87e00-68b1-4595-9fb6-39e189e1b6e9(a)q10g2000prf.googlegroups.com...
> On Apr 14, 1:28 am, Christian ASTOR <casto...(a)club-internet.fr> wrote:
>> On 14 avr, 00:31, lukkycha...(a)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);
>> }
>>
>>
>>
>> }- 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.)
>
> 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
>