2013-08-01 65 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); 
    } 
} 
相關問題