开发者

Can't Use GetAsyncKeyState + Message Pump, SC_MONITORPOWER not Fully Working

I'm trying to make a program that can turn off the monitor with a key combination and turn it back on with another. The power button fell off, so the monitor pretty much stays on now. I noticed sending a WM_SYSCOMMAND with a WPARAM of SC_MONITORPOWER would probably do the trick, but in reality it wasn't.

First, I tried putting a few GetAsyncKeyState()s in my message pump, but whenever I tried to run it, my keystrokes were not picked up.

while (GetMessage(&Msg, NULL, 0, 0) > 0) // main message pump
{
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);

    if (GetAsyncKeyState (0x31) & 0x8000) SendMessage (hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, 2); // turn monitor off if '1' is pressed
    if (GetAsyncKeyState (0x32) & 0x8000) SendMessage (hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, -1); // turn monitor on if '2' is pressed
    if (GetAsyncKeyState (0x33) & 0x80开发者_高级运维00) PostMessage (cmd, WM_CLOSE, 0, 0); // close console window if '3' is pressed (it even comes with the windows projects for some reason so I just hide it+deal with it
}

I tried moving the GetAsyncKeyState()s before the message functions. I tried using a while (true) loop and including GetMessage() in it.

The only thing that started to work was commenting out all message pump references in the loop. This would pick up the keystrokes, but when pressing '1' (0x31), the monitor would only go dark (the power light would stay solid) for a few seconds before turning on. Using a value of 1 for LPARAM to go into low-power mode would do the same thing. Pressing '2' while it was dark would not do anything.

My reasoning for this is that since I disabled the message queue, DefWindowProc() was never able to handle these messages and thus they would produce incorrect results.

I thought about setting up a loop when '1' is pressed to keep turning the monitor off for a few seconds at a time until '2' is pressed, but I figured I've done enough bad things to the code already (window with no message loop) and having code this bad would kind of ruin the point when I'll most likely need this information later anyways.

All that's in my window procedure is a WM_CLOSE with DestroyWindow(), WM_DESTROY which shows the hidden window and calls PostQuitMessage(), and DefWindowProc.

So basically my question comes down to "How can I use GetAsyncKeyState with my message pump?". Also, I noticed WM_POWERBROADCAST can achieve this too. Is one better to use?

EDIT: commented the code so you know a bit extra

EDIT: RegisterHotKey() fixed one problem, but the monitor still only goes dark for a few seconds (power light solid)


As tinman said, use RegisterHotKey.

To address your question, GetAsyncKeyState reads the current key state. GetMessage reads messages in a queue. They won't be synchronized. You should instead use GetKeyState which stays in sync with the message queue.

But yea, RegisterHotKey.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜