Как узнать, сколько раз ваш компьютер находился в режиме заставки или выключения монитора / экрана?

Я использую Windows 7 и VC ++. Дело в том, чтобы узнать, сколько секунд моя система была переведена в режим экранной заставки или выключен экран монитора. Чтобы добиться этого, я пытаюсь поймать события WM_SYSCOMMAND и SC_SCREENSAVE, SC_MONITORPOWER. Итак, я создал проект Win32 в Visual Studio 2008 и получаю события в функции WndProc:

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;
}
}

Он отлично работает, когда диалоговое окно находится на переднем плане, но в фоновом режиме (или, если я комментирую функцию ShowWindow), это работает только если я вручную отправляю события:

SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_SCREENSAVE, (LPARAM)2);
or
SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)2);

Таким образом, это не работает, когда конфигурация питания системы устанавливает заставку после 2 минут бездействия, и то же самое с автоматическим отключением экрана монитора. Это реальная вещь, которую я хочу, знать, когда система выключает экран или устанавливает заставку, с помощью программы фонового мониторинга.

Я также пытался использовать ловушку событий с Extern DLL. Я следовал этому примеру http://www.codeproject.com/Articles/1037/Hooks-and-DLLs добавив в функцию CALLBACK msghook () тот же код переключателя, что и в WndProc. Это не работает даже при использовании SendMessage.

После нескольких дней, застрявших в этой проблеме, поиска в Интернете, форумах … Я не знаю, что еще я могу сделать. Может кто-нибудь мне помочь?

0

Решение

Я не использовал крючки должным образом, но это было редко. Во-первых, о функции setWindowsHookEx, я прочитал, что WH_CALLWNDPROC или WH_SYSMSGFILTER должны использоваться для получения отправленных сообщений WM_SYSCOMMAND, а затем получить SC_SCREENSAVE wParam. В этом случае я не знаю, почему, и, возможно, я ошибаюсь, но, похоже, это не так.

После использования каждого возможного сообщения SetWindowsHookEx я понял, что WH_GETMESSAGE — единственный, кто отправляет SC_SCREENSAVE wParam, по крайней мере, в этом примере ловушки в Windows 7.

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

Во-вторых, при прослушивании каждого сообщения, перехваченного функцией ловушки, WM_SYSCOMMAND появились с LPMSG. Я также прочитал, что wParam должен быть объединен с 0xFFF0 для сравнения. Но wParam & 0xFFF0 == SC_SCREENSAVE не работает и wParam == SC_SCREENSAVE тоже. В этом случае единственный способ — использовать LPMSG для WM_SYSCOMMAND и 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);
}

И использование FILE для проверки событий было очень плохой идеей, я думаю, что использование MessageBox не намного лучше, но я не знаю, как правильно их проверять.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]