2011-05-13 122 views
6

我正在研究一個需要模擬按鍵以在不同應用程序中導致特定行爲的項目。發送Numpad上的特定鍵,例如+, - ,/或Enter(模擬按鍵)

所有運行良好,使用正在導入的keybd_event函數(可能有更好的方法,但它工作正常)。

現在我想爲所有的數字鍵盤添加特定的支持。

尋找e。 G。這裏http://msdn.microsoft.com/en-us/library/dd375731(v=VS.85).aspx或在System.Windows.Input.Key命名空間中,我可以輕鬆找到Num0..Num9和NumLock的鍵。但是..我找不到民/,民+,NumEnter什麼等

我寫了一個快速320交織的應用程序,以趕上keydown事件,輸出事件paramters,並得到了一些有趣的結果:

e.KeyCode NumLock e.KeyData NumLock e.KeyValue 144 e.Modifiers None 
e.KeyCode Divide e.KeyData Divide e.KeyValue 111 e.Modifiers None 
e.KeyCode Multiply e.KeyData Multiply e.KeyValue 106 e.Modifiers None 
e.KeyCode Subtract e.KeyData Subtract e.KeyValue 109 e.Modifiers None 
e.KeyCode Add e.KeyData Add e.KeyValue 107 e.Modifiers None 
e.KeyCode NumLock e.KeyData NumLock e.KeyValue 144 e.Modifiers None 
e.KeyCode NumLock e.KeyData NumLock e.KeyValue 144 e.Modifiers None 
e.KeyCode Divide e.KeyData Divide e.KeyValue 111 e.Modifiers None 
e.KeyCode Multiply e.KeyData Multiply e.KeyValue 106 e.Modifiers None 
e.KeyCode Subtract e.KeyData Subtract e.KeyValue 109 e.Modifiers None 
e.KeyCode Add e.KeyData Add e.KeyValue 107 e.Modifiers None 
e.KeyCode Return e.KeyData Return e.KeyValue 13 e.Modifiers None 

Num + Key(等等)似乎是Windows調用功能鍵的鍵(例如Num +鍵的F18)。所以......這很奇怪,但確定。

但是..我無法區分Enter鍵和NumEnter鍵。這些對於我的應用程序來說是不同的,所以我必須爲這兩者發送特定的鍵碼。

這就是我的問題:我如何發送一個普通的輸入密鑰,以及如何發送一個NumEnter密鑰?

(我不知道這有什麼差別,我是在一個德國的鍵盤佈局。)

THX的任何想法!

+1

並不十分有益的,但我可以肯定:我們有一個應用程序跟蹤用戶輸入,現在它從輸入產生相同的鍵代碼NumEnter所以我無法分辨。 – Cilvic 2011-05-13 08:46:31

回答

0

既然你是在談論一個的,另一方向的全方位解決方案,檢測的情況下,我想養它,我甚至不具有覆蓋的WndProc。我可以簡單地發送我自己的消息。

從你的解決方案,我看看SendMessage/PostMessage,然後WM_KEYDOWN和WM_KEYUP。文件實際上給你的信息(如果你真的很難看)。

http://msdn.microsoft.com/en-us/library/ms646280(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/ms646281(v=vs.85).aspx

所以我的解決辦法(編譯和現在找到合適的窗口(其中輸入文本))是這樣的:

bool keyDown = true; // true = down, false = up 
const uint WM_KEYDOWN = 0x0100; 
const uint WM_KEYUP = 0x0101; 
const int VK_RETURN = 0x0D; 

IntPtr handle = IntPtr.Zero; 
// Obtain the handle of the foreground window (active window and focus window are only relative to our own thread!!) 
IntPtr foreGroundWindow = GetForegroundWindow(); 
// now get process id of foreground window 
uint processID; 
uint threadID = GetWindowThreadProcessId(foreGroundWindow, out processID); 
if (processID != 0) 
{ 
// now get element with (keyboard) focus from process 
GUITHREADINFO threadInfo = new GUITHREADINFO(); 
threadInfo.cbSize = Marshal.SizeOf(threadInfo); 
GetGUIThreadInfo(threadID, out threadInfo); 
handle = (IntPtr)threadInfo.hwndFocus; 
} 

int lParam = 1 << 24; // this specifies NumPad key (extended key) 
lParam |= (keyDown) ? 0 : (1 << 30 | 1 << 31); // mark key as pressed if we use keyup message 
PostMessage(handle, (keyDown) ? WM_KEYDOWN : WM_KEYUP, VK_RETURN, lParam); // send enter 

希望這是對別人有用以及。正如Vendetta對我的提示。

而且..如果你有更好的解決方案,請這麼說!

3

我發現這個here適合我!

protected override void WndProc(ref Message m) 
{ 
    if (m.Msg == 256 && m.WParam.ToInt32() == 13) 
    { // WM_KEYDOWN == 256, Enter == 13 
     if ((m.LParam.ToInt32() >> 24) == 0) 
     { 
      MessageBox.Show("main enter pressed!"); 
     } 
     else 
     { 
      MessageBox.Show("numpad enter pressed!"); 
     } 
     } 
     else 
     { 
     base.WndProc(ref m); 
     } 
} 
+0

Thx很多,這真的很有幫助。 雖然它是我尋找的其他方式:)它擁有解決我的問題的所有信息。 我會馬上寫出一個答案。 – 2011-05-13 09:24:02

+0

Thx對你的答案很重要! 特別是對於你的想法,仇殺隊! 由於您正在討論其他方式的解決方案,檢測事件,並且我想提高它,所以我甚至不必重寫WndProc。我可以簡單地發送我自己的消息。 從你的解決方案,我看看SendMessage,然後WM_KEYDOWN和WM_KEYUP。文件實際上給你的信息(如果你真的很難看)。 http://msdn.microsoft.com/en-us/library/ms646280(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/ms646281(v=vs .85).aspx – 2011-05-13 09:34:57

+0

所以我的解決方案(編譯但未測試)是這樣的: enter bool keyDown; // true = down,false = up const uint WM_KEYDOWN = 0x0100; const uint WM_KEYUP = 0x0101; const int VK_RETURN = 0x0D; //獲取活動窗口的句柄。 IntPtr handle = GetForegroundWindow(); int lParam = 1 << 24; //這指定了NumPad鍵(擴展鍵) lParam | =(keyDown)? 0:(1 << 30 | 1 << 31);如果我們使用鍵入消息,則將鍵標記爲按下 PostMessage(handle,(keyDown)?WM_KEYDOWN:WM_KEYUP,VK_RETURN,lParam); – 2011-05-13 09:35:25

1

感謝安德烈提供解決方案的開始。這裏有一個更完整的版本:

[DllImport("user32.dll")] 
private static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 
[DllImport("user32.dll")] 
private static extern IntPtr GetForegroundWindow(); 
[DllImport("user32.dll")] 
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); 
[DllImport("user32.dll")] 
private static extern bool GetGUIThreadInfo(uint idThread, out GUITHREADINFO lpgui); 

public struct GUITHREADINFO 
{ 
    public int cbSize; 
    public int flags; 
    public int hwndActive; 
    public int hwndFocus; 
    public int hwndCapture; 
    public int hwndMenuOwner; 
    public int hwndMoveSize; 
    public int hwndCaret; 
    public System.Drawing.Rectangle rcCaret; 
} 

private void sendNumpadEnter() 
{ 
    bool keyDown = true; // true = down, false = up 
    const uint WM_KEYDOWN = 0x0100; 
    const uint WM_KEYUP = 0x0101; 
    const int VK_RETURN = 0x0D; 

    IntPtr handle = IntPtr.Zero; 
    // Obtain the handle of the foreground window (active window and focus window are only relative to our own thread!!) 
    IntPtr foreGroundWindow = GetForegroundWindow(); 
    // now get process id of foreground window 
    uint processID; 
    uint threadID = GetWindowThreadProcessId(foreGroundWindow, out processID); 
    if (processID != 0) 
    { 
     // now get element with (keyboard) focus from process 
     GUITHREADINFO threadInfo = new GUITHREADINFO(); 
     threadInfo.cbSize = Marshal.SizeOf(threadInfo); 
     GetGUIThreadInfo(threadID, out threadInfo); 
     handle = (IntPtr)threadInfo.hwndFocus; 
    } 

    int lParam = 1 << 24; // this specifies NumPad key (extended key) 
    lParam |= (keyDown) ? 0 : (1 << 30 | 1 << 31); // mark key as pressed if we use keyup message 

    PostMessage(handle, (keyDown) ? WM_KEYDOWN : WM_KEYUP, VK_RETURN, lParam); // send enter 
}