Click here to Skip to main content
15,884,986 members
Articles / Desktop Programming / MFC
Article

How to programatically disable/enable screen savers/power management

Rate me:
Please Sign up or sign in to vote.
4.11/5 (5 votes)
27 Aug 20022 min read 76.9K   27   6
The article explains how to programatically disable/enable screen savers/power management and includes a class that does this for you.

Introduction

In my current project, at a certain point (during data capture) I needed to disable the screen saver and power management features of Windows. I experimented with several ways to accomplish this:

  1. Capture WS_SYSCOMMAND/SC_SCREENSAVE. This command is only sent to the window that has focus and therefore my program could miss the opportunity to reject it.
  2. WM_POWERBROADCAST. I couldn't get it to work :-(
  3. Call the SystemParametersInfo function to do the work.

I settled on 3 as it seemed to be the safest way to always work.

The class

So here is a simple class that implements my findings. It's very simple to use, whenever you need to disable screensaving/power management, add a member variable to your dialog/form class of type CDisableScreenSave and during the lifetime of that class, your computer won't screensave/shutdown. Of course this being C++, everything is automatically reset when the class destructor is called. This makes it nice and easy :-)

Code Listing

Header file

// DisableScreenSave.h
// interface for the CDisableScreenSave class.
//////////////////////////////////////////////

#if !defined(AFX_DISABLESCREENSAVE_H__94B5D6F5
        _BB06_4409_9876_1D1EB6F1480B__INCLUDED_)
#define AFX_DISABLESCREENSAVE_H__94B5D6F5
        _BB06_4409_9876_1D1EB6F1480B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


class CDisableScreenSave  
{
public:
    CDisableScreenSave();
    virtual ~CDisableScreenSave();

protected:
    int *m_pValue;
};

#endif  
        // !defined(AFX_DISABLESCREENSAVE_H__94B5D6F5
        //      _BB06_4409_9876_1D1EB6F1480B__INCLUDED_)

Module file

// DisableScreenSave.cpp 
// implementation of the CDisableScreenSave class.
//////////////////////////////////////////////////

#include "stdafx.h"
#include "DisableScreenSave.h"
#include <../src/afximpl.h>

///////////////////////////////////////////////////
// Construction/Destruction
///////////////////////////////////////////////////

static UINT dss_GetList[] = {SPI_GETLOWPOWERTIMEOUT, 
    SPI_GETPOWEROFFTIMEOUT, SPI_GETSCREENSAVETIMEOUT};
static UINT dss_SetList[] = {SPI_SETLOWPOWERTIMEOUT, 
    SPI_SETPOWEROFFTIMEOUT, SPI_SETSCREENSAVETIMEOUT};


static const int dss_ListCount = _countof(dss_GetList);


CDisableScreenSave::CDisableScreenSave()
{
    m_pValue = new int[dss_ListCount];

    for (int x=0;x<dss_ListCount;x++)
    {
        // Get the current value
        VERIFY(SystemParametersInfo (dss_GetList[x], 0, 
            &m_pValue[x], 0));

        TRACE(_T("%d = %d\n"), dss_GetList[x], m_pValue[x]);

        // Turn off the parameter
        VERIFY(SystemParametersInfo (dss_SetList[x], 0, 
            NULL, 0));
    }
}


CDisableScreenSave::~CDisableScreenSave()
{
    for (int x=0;x<dss_ListCount;x++)
    {
        // Set the old value
        VERIFY(SystemParametersInfo (dss_SetList[x], 
            m_pValue[x], NULL, 0));
    }

    delete[] m_pValue;
}

I make use of the MFC macros ASSERT and VERIFY. These I believe are very under used in most MFC programs, and recommend that if you don't know about them you find an article or person that can explain them to you. As a case in point, VERIFY immediately pointed out a simple error I made when I tried to call the SPI_GET routines in the destructor where I should have called SPI_SET!

I also make use of the undocumented _countof macro. This is defined in ../src/afximpl.h as :

// determine number of elements in an array (not bytes)
#define _countof(array) (sizeof(array)/sizeof(array[0])) 

Finally...

In a quirk of Microsoft it seems that the SPI_SETLOWPOWERTIMEOUT and SPI_SETPOWEROFFTIMEOUT are only available to certain programs.

OS16-bit32-bit
Win95X
Win98
WinNT/XPX

Another thing to mention is that if there are any SPI... parameters that I've missed out, you can just add the SPI_GET... to dss_GetList[] and SPI_SET... to dss_SetList[] and everything else will be taken care of.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralThank You Pin
EmoBemo16-Feb-10 0:32
EmoBemo16-Feb-10 0:32 
Nice and simple.
GeneralRecommended way for W2000 is: Pin
alpe29-Aug-02 0:05
alpe29-Aug-02 0:05 
GeneralRe: Recommended way for W2000 is: Pin
Obliterator30-Aug-02 0:56
Obliterator30-Aug-02 0:56 
GeneralRe: Recommended way for W2000 is: Pin
Swinefeaster2-Jan-04 11:10
Swinefeaster2-Jan-04 11:10 
GeneralRe: Recommended way for W2000 is: Pin
Swinefeaster2-Jan-04 11:48
Swinefeaster2-Jan-04 11:48 
GeneralRe: Recommended way for W2000 is: Pin
Aleksei Karimov15-Nov-07 6:01
Aleksei Karimov15-Nov-07 6:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.