Советы по Delphi

         

Как запустить или закрыть скринсэйвер?


Nomadic приводит сиплюсплюсное решение:

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_SCREENSAVE 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 ! //***************************************************************************// [001585]



Содержание раздела