How to Force a ScreenSaver to Close Once Started in Windows NT

Last reviewed: April 11, 1996
Article ID: Q140723
The information in this article applies to:
  • Microsoft Win32 Application Programming Interface (API) included with Microsoft Windows NT versions 3.1, 3.5, 3.51

SUMMARY

Sometimes applications need to terminate a screensaver that is already running. In Windows 3.1 or Windows 95, a screensaver could be terminated easily by posting a WM_CLOSE message to the currently active screensaver window as in this example:

    PostMessage (GetActiveWindow(), WM_CLOSE, 0, 0L);

Windows NT, however, introduces the concept of separate desktops, so that applications can run on one, and screen savers can run on another. This makes screensaver termination under Windows NT a bit more difficult.

MORE INFORMATION

Under Windows NT, obtaining a handle to the currently active screensaver window is not as straightforward as it is in Windows 3.1 and Windows 95. Calling GetForegroundWindow() returns NULL because the screensaver is running on a different desktop than the calling application. Similarly, calling FindWindow ("WindowsScreenSaverClass", NULL) to determine if the screen saver is currently active won't work either.

The way to do it is to get a handle to the screen saver's desktop, enumerate that desktop's windows, and then post a WM_CLOSE to the screen saver window.

The following code demonstrates how to do this. Note that if a screen saver password is set, the following code brings up the password dialog box, prompts the user for a password, and then actually terminating the screen saver application.

   BOOL CALLBACK KillScreenSaverFunc(HWND hwnd, LPARAM lParam)
   {
      PostMessage(hwnd, WM_CLOSE, 0, 0);
      return TRUE;
   }

   HDESK hdesk;

   hdesk = OpenDesktop(TEXT("Screen-saver"),
                       0,
                       FALSE,
                       DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS);
   if (hdesk)
   {
      EnumDesktopWindows(hdesk, KillScreenSaverFunc, 0);
      CloseDesktop(hdesk);
   }

Note that terminating a screensaver that is already running as demonstrated above is totally separate from disabling the screen saver altogether, so that no screen saver starts after the designated time period expires. This can be done easily using:

   SystemParametersInfo( SPI_SETSCREENSAVEACTIVE,
                         FALSE,
                         0,
                         SPIF_SENDWININICHANGE
                       );

This method works well for terminating the currently running screen saver. However, one problem that you might encounter is that the system will not restart the screen saver unless the user moves the mouse or presses a key. If you need the screen saver to start up again, you'll need to reinitialize the time-out period. Do this by:
  • Calling SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_SENDWININICHANGE).

    -or-

  • Using SetCursorPos() to simulate user input.

Both of these methods will cause the system to restart the time-out counter for the screen saver.


Additional reference words: 3.10 3.50 deactivate disable stop running
turn off
KBCategory: kbgraphic kbhowto kbcode
KBSubcategory: GdiScrSav


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: April 11, 1996
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.