I need my application to respond to the SC_SCREENSAVE and SC_MONITORPOWER
events ... it plays music and I'd like it to stop whilst the screensaver is
running and also if the monitor power saving feature kicks in.
It seems that only the topmost window receives the associated
WM_SYSCOMMANDS - so I wrote a DLL hook with the intention of simply of
echoing the command parameters to my application ... but if I pass on the
WM_SYSCOMMAND to my application then my hook intercepts it and it all goes
horribly recursive and causes a system hang !
In the interim, I've introduced a user message and that all works now ...
but I'd like to understand how to reliably forward a command from a hook
such that the hook does not intercept that particular message. How ?
(I realize that the user might simply turn the monitor off ... but when
Windows initiates a monitor power save, is there any way to test the status
of the monitor ? I Googled around and found nothing !)
Thanks
Andrew
function HookCBT(code : integer; wParam: WPARAM; lParam: LPARAM): LRESULT;
const
UM_MONITORPOWER = WM_APP + 1001;
var
P1HookRec : PAJHookRec;
h1MemFile : HWND;
begin
if (code>=0) then begin
case code of
HCBT_SYSCOMMAND : if (wParam and $FFF0 = SC_SCREENSAVE) or (wParam
and $FFF0 = SC_MONITORPOWER) then begin
if OpenMMF(MapFilename, h1MemFile,
Pointer(P1HookRec)) then begin
PostMessage(P1HookRec^.aHwnd, UM_MONITORPOWER,
wParam, lParam);
UnmapViewOfFile(P1HookRec);
CloseHandle(h1MemFile);
end; {if}
end; {if}
end; {case}
end;
Result := CallNextHookEx(HookCallback, Code, wParam, lParam);
end; {HookCBT}
If the current process ID is the same as the process ID of the window
you plan to forward the message to, then don't forward it -- it's
already there. See GetCurrentProcessID and GetWindowThreadProcessID.
--
Rob
Like everything in life ... it's only easy when you know !
GetCurrentProcessID worked like a charm and no more system hangs !
You don't know how to get the monitor status by any chance or is it even
possible ?
Thanks
Andrew
> It seems that only the topmost window receives the
> associated WM_SYSCOMMANDS
Yes, it does.
> I wrote a DLL hook with the intention of simply of echoing the
> command parameters to my application ...
That won't work, as you have already discovered.
> if I pass on the WM_SYSCOMMAND to my application then
> my hook intercepts it and it all goes horribly recursive and causes
> a system hang !
Your hook itself needs to manage the messages drectly. You cannot pass them
on to the application for handling.
What you should do is define a custom message that the hook can post to the
application when needed. The hook can then ignore that message whenever it
is received. Don't pass the original messages.
> In the interim, I've introduced a user message and that all works now ...
That is what you need to do.
> I'd like to understand how to reliably forward a command from
> a hook such that the hook does not intercept that particular message.
> How ?
You can't.
> I realize that the user might simply turn the monitor off ... but when
> Windows initiates a monitor power save, is there any way to test
> the status of the monitor ? I Googled around and found nothing !
Read the documentation for SC_MONITORPOWER. It tells you the monitor state.
Gambit
>
> ...
> ...
>
> Read the documentation for SC_MONITORPOWER. It tells you the monitor
> state.
>
I seem to have achieved the impossible ... I can forward the WM_SYSCOMMAND
for SC_SCREENSAVE and SC_MONITORPOWER to my application thanks to Rob's
point about testing the current process ID.
Your point about knowing the monitor status as it is provided by
SC_MONITORPOWER doesn't help ... is there a way that I can query the monitor
status ?
Thanks
Andrew
> You don't know how to get the monitor status by any chance
> or is it even possible ?
Not directly, that I know of. Have a look at the PBT_POWERSETTINGCHANGE
notification in the WM_POWERBROADCAST message, though. Under Vista, you may
have to call RegisterPowerSettingNotification() to enable it.
Gambit