2011-09-06 85 views
0

我试图做一个程序,可以关闭显示器用组合键并用另一个重新打开它。电源按钮掉下来了,所以显示器几乎停留在现在。我注意到发送一个WM_SYSCOMMAND和一个SC_MONITORPOWER的WPARAM可能会诀窍,但事实上并非如此。无法使用GetAsyncKeyState +消息泵,SC_MONITORPOWER不完全工作

首先,我试图把几个GetAsyncKeyState()在我的消息泵,但每当我试图运行它,我的按键并没有回升。

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) & 0x8000) 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 
} 

我试图消息功能之前移动所述GetAsyncKeyState()秒。我试着使用while(true)循环并在其中包含GetMessage()。

是开始工作的唯一的事情是注释掉回路中的所有消息泵引用。这样可以获得键盘按键,但按'1'(0x31)时,显示器只会在开机前变暗(电源指示灯会保持稳定)几秒钟。使用LPARAM值为1进入低功耗模式可以做同样的事情。天黑时按'2'不会做任何事情。

我给这家的理由是,因为我禁用了消息队列,DefWindowProc函数()从来没有能够处理这些消息,因此它们会产生不正确的结果。

当我按下“1”按钮时,一直关闭显示器几秒钟直到按下“2”,我想过设置一个循环,但我想我已经做了足够的坏事已经(窗口没有消息循环),并有这样的代码糟糕的会毁了点,当我很可能需要这些信息后来反正。

所有在我的窗口过程是一个WM_CLOSE与DestroyWindow(),WM_DESTROY它显示隐藏窗口并调用PostQuitMessage()和DefWindowProc。

所以基本上我的问题可以归结为“我如何使用GetAsyncKeyState我的消息泵?”。另外,我注意到WM_POWERBROADCAST也可以实现这一点。使用更好吗?

编辑:注释代码,所以你知道一点额外
编辑:RegisterHotKey()固定的一个问题,但显示器仍然只有几秒钟熄灭(电源指示灯固体)

+3

为什么不使用RegisterHotKey()? – tinman

+0

我会尝试一下,看看它是如何工作的,谢谢。如果我能做除泵中的消息处理之外的任何事情,那还是很好的。 – chris

+0

好了,让以后的工作仍然只是变暗了几秒钟,然后回到正常的(有点如果(LOWORD(lParam的== MOD_CONTROL))哈哈,括号失败我发现后):/我与运行管理员权限等任何其他人有这个问题?无论如何,我很快就要上学,所以如果我有机会,我也会在那里尝试。 – chris

回答

0

由于铁皮说,请使用RegisterHotKey

为了解决你的问题,GetAsyncKeyState读取当前国家重点。 GetMessage读取队列中的消息。他们不会同步。您应该改用与邮件队列保持同步的GetKeyState

但是啊,RegisterHotKey

+0

我会记住的,谢谢。 – chris