2013-08-01 95 views
0

我正在使用winapi的Win32应用程序,我很好奇在应用程序没有对焦/无窗口时是否有办法接收键盘事件。在后台接收按键

最初我正在阅读应用程序消息队列并检查WM_KEYDOWN消息,但消息只在窗口处于焦点时发送给应用程序。我知道可以使用DirectInput,但如果可能的话,我想避免让我的应用程序需要DirectX。

除了使用DirectInput之外,还有其他方式可以在窗口焦点不清的情况下接收键盘按键吗?

编辑:不,你问之前我不写一个键盘记录。应用程序需要在后台响应某些可重新绑定的键盘快捷键。

回答

0

最好你可以实现这种行为的方式就是钩住键盘。

这是一个方便的教程说明的基础知识:codeguru
它还区分钩类型分为特定系统范围过程。

0

稍后编辑:如果窗口没有对焦,即使WM_KILLFOCUS被忽略,它也不能处理WM_KEYDOWN消息。因此您需要定期检查并分别检查GetAsyncKeyState()

您可以绕过您的WndProc()消息中的WM_KILLFOCUS,以便应用程序不会失去焦点。它仍然可以处理任何按键。

喜欢的东西:

LRESULT CALLBACK WndProc(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 

    switch (msg) 
    { 

    /* cases blah blah */ 

    case WM_KILLFOCUS: 
     return 0; 

    /* other cases' blah blah */ 

    } 
    return DefWindowProc(hWindow, msg, wParam, lParam); 
} 
+0

其实,这会更容易。但是安全吗?如果其他应用程序试图获得重点会怎样? –

+0

这不会阻止任何其他应用程序获得重点吗?这个想法是,应用程序应该能够在其他应用程序正常运行时在后台接收按键。 –

+0

@笨蛋你应该钩住键盘。徘徊在未知行为之地并不理想。 –

0

Microsoft DirectX库包含一个可用于获取键盘状态的函数。它是DirectInput API的一部分。下面的代码演示了如何轮询键盘的关键状态信息。必须添加额外的逻辑来检测何时按下/释放按键并将其转换为字符。

请注意,这需要Microsoft DirectX SDK进行编译。

//Public domain: no attribution required 
#include "stdafx.h" 
#include "dxlog.h" 

#pragma comment(lib, "dinput8") 
#pragma comment(lib, "dxguid") 

LPDIRECTINPUT8 din; 
LPDIRECTINPUTDEVICE8 dinkbd; 
BYTE keystate[256]; 
DIDATAFORMAT dfi; 

void init_dinput(HINSTANCE hInst, HWND hWnd) 
{ 
    HRESULT hr; 
    hr = DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void **)&din, NULL); 
    hr = din->CreateDevice(GUID_SysKeyboard, &dinkbd, NULL); 
    hr = dinkbd->SetDataFormat(&c_dfDIKeyboard); 
    // share the keybdb and collect even when not the active application 
    hr = dinkbd->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); 
} 

void detect_input(void) 
{ 
    dinkbd->Acquire(); 
    dinkbd->GetDeviceState(256, keystate); 
} 

void clean_dinput(void) 
{ 
    dinkbd->Unacquire(); 
    din->Release(); 
} 

void print_state() 
{ 
    WCHAR pState[4096] = L""; 
    WCHAR temp[32]; 

    for (int i = 0; i < 256; i++) 
    { 
     if (keystate[i] != 0) 
     { 
      wsprintf (temp, L"%d(%d) ", i, keystate[i]); 
      lstrcat(pState, temp); 
     } 
    } 
    if (lstrlen(pState) != 0) 
    { 
     lstrcat(pState, L"\n"); 
     OutputDebugString(pState); 
    } 
} 
相关问题