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:
- 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. -
WM_POWERBROADCAST
. I couldn't get it to work :-( - 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
#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
Module file
#include "stdafx.h"
#include "DisableScreenSave.h"
#include <../src/afximpl.h>
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++)
{
VERIFY(SystemParametersInfo (dss_GetList[x], 0,
&m_pValue[x], 0));
TRACE(_T("%d = %d\n"), dss_GetList[x], m_pValue[x]);
VERIFY(SystemParametersInfo (dss_SetList[x], 0,
NULL, 0));
}
}
CDisableScreenSave::~CDisableScreenSave()
{
for (int x=0;x<dss_ListCount;x++)
{
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 :
#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.
OS | 16-bit | 32-bit |
---|
Win95 | √ | X |
Win98 | √ | √ |
WinNT/XP | X | √ |
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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.