Dear Dr. GUI,
I would like my application to execute a function if and when the screen saver starts.
I have been searching for a way for my program to know that the screen saver has started but the only thing I could find
was SystemParametersInfo() used with the SPI_GETSCREENSAVERRUNNING action. However, this is only available for NT 5.0 or
Windows 98, and I need it for NT 4.0 and Windows 95. Can I actually get this to happen?
Dr. GUI replies:
Here's a bit of info to get you started.
When Screen Saver starts, it posts a WM_SYSCOMMAND message. So, a global WH_GETMESSAGE hook can be installed as below.
Since our goal is to give applications an easy way to know when the screen saver is about to start, we'll use a user-defined
registered window message called "Screen_Saver_Starting"�so therefore we have to register that message.
UINT WM_SCRNSVSTART = RegisterWindowMessage("Screen_Saver_Starting");
hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)HookProc, (HINSTANCE) hMod, 0);
Don't forget to uninstall the hook when by calling UnhookWindowsHookEx before you exit.
Then, in your hook procedure (you can call it anything, we called it HookProc), you can filter on the WM_SYSCOMMAND message with
wParam equal to SC_SCREENSAVE:
LRESULT CALLBACK HookProc(UINT code , WPARAM wParam, LPARAM lParam)
{
MSG *msg = (MSG *)lParam;
if ( msg->message == WM_SYSCOMMAND && msg->wParam == SC_SCREENSAVE)
{ // broadcast message to all top-level windows
// you could do other things here, too
PostMessage(HWND_BROADCAST, WM_SCRNSVSTART, 0, 0);
}
// Always call next hook in chain (if any)
return CallNextHookEx(hHook, code, wParam, lParam);
}
This code posts a "Screen_Saver_Starting" registered message to all top-level windows. You could replace the PostMessage call with
code to start an executable or do some other function.
To handle this message, your app would call RegisterWindowMessage in its initialization code and then handle the message in the
window procedure for a top-level window. An MFC app would use the ON_REGISTERED_MESSAGE message map macro in a top-level window's
message map.