Click here to Skip to main content
15,860,861 members
Please Sign up or sign in to vote.
4.50/5 (2 votes)
I'm using Windows 7 and VC++. The business is to know how many seconds my system has been set into screen saver mode or monitor screen off. To achieve this, I'm trying to catch the events WM_SYSCOMMAND and SC_SCREENSAVE, SC_MONITORPOWER. So I have created a Win32 project in Visual Studio 2008 and I'm receiving the events in WndProc function:


C++
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	int wmId, wmEvent;
    	PAINTSTRUCT ps;
    	HDC hdc;
    
    	switch (message)
    	{
    		case WM_SYSCOMMAND:
    		{
    			switch (LOWORD(wParam))
    			{
    				case SC_SCREENSAVE:
    				{
    					FILE *fl = fopen("this_is_a_event_test.txt","a");
    					fputs("SC_SCREENSAVE\n",fl);
    					fclose(fl);
    				}
    				break;
    				case SC_MONITORPOWER:
    				{
    					FILE *fl = fopen("this_is_a_event_test.txt","a");
    					fputs("SC_MONITORPOWER\n",fl);
    					fclose(fl);
    				}
    				break;
    				default:
    				{
    				}
    			}
    		}
                break;
    	}
    }


It works fine when dialog is in foreground, but in background (or if I comment ShowWindow function) it only works if I manually send the events:

C++
SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_SCREENSAVE, (LPARAM)2);

or
C++
SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)2);


So, it is not working when system power configuration sets the screen saver after 2 minutes of inactivity, and the same thing with automatic monitor screen off. Thats the real thing I want, know when the system is turning off the screen or setting the screen saver with a background monitoring program.

I have also tried to use hook events with extern dll. I have followed this example Hooks and DLLs adding in the CALLBACK msghook() function the same switch code above in WndProc. It doesn't work even using the SendMessage.

After several days stuck with this issue, searching in the Internet, forums... I don't know what else I can do. Can anyone help me?
Posted
Updated 15-Jan-13 4:20am
v2

have u tried properly using hooks,because it works,i have done similar kind of code where my code tracks creation of window,as a reference i used SPY program By Dor ALan from this site,i used his program as a base for developing my code,you can also have a look at my code at this link,
http://www.codeproject.com/Questions/523472/Handlingpluswh_shell-27spluswindowplusdestroyplusm
Also try writing to file when the screen saver turns oFF or your moitor turns on,cause i'm guessing when you try to write using your code it causes a event and wakes up the system...
Feel free to ask if you hav any doubts
 
Share this answer
 
Hi @analogx. You are right, I were not using hooks properly, but it has been rare. Firstly, about setWindowsHookEx function, I have read WH_CALLWNDPROC or WH_SYSMSGFILTER must be used to get WM_SYSCOMMAND sent messages, and then get SC_SCREENSAVE wParam. In this case, I don't know why and maybe I'm wrong, but thats seems not to be true.

After use every possible message to SetWindowsHookEx, I realised WH_GETMESSAGE is the only one who sends SC_SCREENSAVE or SC_MONITORPOWER wParam, at least in this hook example in Windows 7.

C++
HHOOK hook;
HHOOK hook = SetWindowsHookEx(WH_GETMESSAGE,
                (HOOKPROC)msghook,
                hInst,
                0);


Secondly, listening for every message caught in hook function, WM_SYSCOMMAND were appeared only if LPMSG were used. I have read also that wParam must to be combined to 0xFFF0 to be compared. But wParam & 0xFFF0 == SC_SCREENSAVE didn't work and wParam == SC_SCREEN neither. In this case the only way is using LPMSG for both.

C++
static LRESULT CALLBACK msghook(UINT code, WPARAM wParam, LPARAM lParam)
{
     if(code < 0)
     {
         CallNextHookEx(hook, code, wParam, lParam);
         return 0;
     }

     LPMSG msg = (LPMSG)lParam;


     if(msg->message == WM_SYSCOMMAND)
     {
        if (msg->wParam == SC_SCREENSAVE)
        {
           MessageBoxA(NULL,L"SC_SCREENSAVE",L"SC_SCREENSAVE",MB_OK);
        }

        if (msg->wParam  == SC_MONITORPOWER)
        {
           MessageBoxA(NULL,L"SC_MONITORPOWER",L"SC_MONITORPOWER",MB_OK);
        }
     }
     return CallNextHookEx(hook, nCode, wParam, lParam);
}


And using FILE to test the events was a very bad idea, I think using MessageBox is not much better but I don't know how to test ir correctly.
 
Share this answer
 
v9

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900