Q> Как запустить(придушить)
скринсэйвер
A>
Starting
The method for starting a screen saver is simple, but surprising.
You post your
own window a message ! Post yourself the WM_SYSCOMMAND message
with the
SC_SCREE
NSAVE parameter :
// Uses MFC CWnd::PostMessage
PostMessage (WM_SYSCOMMAND, SC_SCREENSAVE);
Stopping
Stopping a screen saver is somewhat more complex. The
Microsoft-documented
way of doing this is to look for the special screen-saver
desktop, enumerate
all windows on that desktop, and close them, as follows:
hdesk = OpenDesktop(TEXT("Screen-saver"),
0,
FALSE,
DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS);
if (hdesk)
{
EnumDesktopWindows (hdesk, (WNDENUMPROC)KillScreenSaverFunc, 0);
CloseDesktop (hdesk);
}
//
----------------------------------------------------------------
BOOL CALLBACK KillScreenSaverFunc (HWND hwnd, LPARAM lParam)
{
PostMessage(hwnd, WM_CLOSE, 0, 0);
return TRUE;
}
However, I can't recommend this approach. I have found when using
this code,
NT4 very occasionally seems to get confused and pass you back the
normal
desktop handle, in which case you end up trying to close all the
normal
application windows. Note, in MS' defence, that the code above
for closing
32 bit savers is derived from a sample that is only marked as
valid for
NT3.51 - there is no mention of NT4 in the sample. Unfortunately,
there is
also nothing to indicate that it doesn't work properly.
I have subsequently performed some tests, and found that the
stock screen
savers supplied with NT4 will in any case get a hit on the window
class search
normally used for 16 bit savers
("WindowsScreenSaverClass"). I don't believe
for a moment that the OpenGL savers (for example) are 16 bit, so
maybe MS are
supplying a saver window class that will give the necessary hit.
So anyway, you
can use this route :
HWND hSaver = FindWindow ("WindowsScreenSaverClass",
NULL);
if (hSaver)
PostMessage (hSaver, WM_CLOSE, 0, 0);
Yet another alternative is now available, which depends upon new
functionality
in SystemParametersInfo. This should be even more general :
BOOL bSaver;
if (::SystemParametersInfo
(SPI_GETSCREENSAVEACTIVE,0,&bSaver,0))
{
if (bSaver)
{
::PostMessage (::GetForegroundWindow(), WM_CLOSE, 0L, 0L);
}
}
So you can try that one as well. An embarassment of riches !