Domanda

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:

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:

SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_SCREENSAVE, (LPARAM)2);
or
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 http://www.codeproject.com/Articles/1037/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?

È stato utile?

Soluzione

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 wParam, at least in this hook example in Windows 7.

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

Secondly, listening for every message catched in hook function, WM_SYSCOMMAND were appeared with LPMSG. 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_SCREENSAVE neither. In this case the only way is using LPMSG for both WM_SYSCOMMAND and SC_SCREENSAVE.

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top