Program slowing system clock

This topic is 4248 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I have this handy little tool I wrote that runs in the background and detects when my screen saver comes up. When that happens, it activates my away message on AIM, and when the screen saver stops, it removes my away message. However, I only recently discovered that it's causing my system clock to slow down. I never really noticed it since my clock synchronizes with the internet once a week, and the slow down isn't extreme. Anyways, what I'm doing is creating a 5 second timer with SetTimer(), and then sitting in the typical GetMessage() loop, waiting for messages so it doesn't eat up the CPU. Then, on WM_TIMER, I'm doing:
case WM_TIMER:
{
if(wparam == 0)
{
BOOL isScreenSaverRunning;

SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &isScreenSaverRunning, 0);

if((pApp->wasScreenSaverRunning) && (!isScreenSaverRunning))
pApp->DeactivateAwayMessage();
else if((!pApp->wasScreenSaverRunning) && (isScreenSaverRunning))
pApp->ActivateAwayMessage();

pApp->wasScreenSaverRunning = isScreenSaverRunning;

return 0;
}

break;
}


Where pApp is a pointer to my application object. Anyways, if I open up my system clock and watch when the seconds tick off, there's a slight but noticeable delay every 5 seconds - it'll tick off 4 seconds, and the fifth second will take about 1.1 seconds or so. Does anyone know what could be causing this? Are Windows timers just really stupid? If so, is there a better way to go about doing this?

Share on other sites
Hi Aprosenf, it sounds like every 5 seconds you want to check if your screen saver is running, and then do the appropriate action. You should create a new thread that does a Sleep(5000); and then do your check in that thread. This will make your thread take no CPU cycles and it's accurate +- 10 ms.

Apprently SetTimer does mess with the system clock, but I've personally never used it.

Share on other sites
Can you also please explain to me how you were able to hook into AIM and display the message? I know of several methods but I'm always curious to learn of another.

Share on other sites
I seem to remember there's a window message you get when the screensaver comes on, WM_SCREENSAVE or something. Then again, maybe not.

EDIT: I can't seem to find anything on MSDN, I think I'm wrong...
EDIT 2: Gottit: WM_SYSCOMMAND:
Quote:
 wParamSpecifies the type of system command requested. This parameter can be one of the following values.[snip]SC_SCREENSAVE Executes the screen saver application specified in the [boot] section of the System.ini file.
If you just wait for that message, you don't need to use a timer at all, and can just sit in a GetMessage() loop. Windows will let you know when the screensaver is comming on.

Share on other sites
I have definately run into this before. Though in my case it happened when playing a sound over and over. FYI, it was an alarm sound in our access control software. Perhaps a scrensaver was active a lot of that time, I don't know.

This caused unbelieveable clock lag on certain PCs. We're talking many hours lost per day. It worked fine on some similiarly spec'd PCs, and after a while the common factor seemed to be that the ones which had the problem just had crap motherboards.

Share on other sites
Quote:
 Original post by ordered_disorderHi Aprosenf, it sounds like every 5 seconds you want to check if your screen saver is running, and then do the appropriate action. You should create a new thread that does a Sleep(5000); and then do your check in that thread. This will make your thread take no CPU cycles and it's accurate +- 10 ms. Apprently SetTimer does mess with the system clock, but I've personally never used it.

I'll give that a try, but threading is ugly in Win32.

Quote:
 Original post by ordered_disorderCan you also please explain to me how you were able to hook into AIM and display the message? I know of several methods but I'm always curious to learn of another.

It's a bit of a hack actually. I call EnumWindows and search for a window with the title "<my screenname>'s Buddy List Window". I then grab the main menu with GetMenu, get the 0th submenu (My AIM) with GetSubMenu, the 4th submenu there (Away Message), and the 5th menu item there (Default Away Message) with GetMenuItemID. If no error occurred, I send a WM_COMMAND to the AIM window with that menu item ID to activate the away message. To deactivate it, I call EnumWindows again and search for a window with the title "<my screenname> - Default Away Message" and send it a WM_CLOSE message. Like I said, it's a hack, but it works.

Quote:
Original post by Evil Steve
I seem to remember there's a window message you get when the screensaver comes on, WM_SCREENSAVE or something. Then again, maybe not.

EDIT: I can't seem to find anything on MSDN, I think I'm wrong...
EDIT 2: Gottit: WM_SYSCOMMAND:
Quote:
 wParamSpecifies the type of system command requested. This parameter can be one of the following values.[snip]SC_SCREENSAVE Executes the screen saver application specified in the [boot] section of the System.ini file.
If you just wait for that message, you don't need to use a timer at all, and can just sit in a GetMessage() loop. Windows will let you know when the screensaver is comming on.

Thanks Steve. Unfortunately, that doesn't seem to work for me. If I read the docs right, it only sends the SC_SCREENSAVE message to the application that is in the foreground, and my program is definitely not in the foreground. Also, even if it did work, it doesn't seem like it sends a message when the screensaver deactivates, though.

Share on other sites

This topic is 4248 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Create an account

Register a new account

• Forum Statistics

• Total Topics
628699
• Total Posts
2984278

• 20
• 10
• 13
• 13
• 11