2012-04-23 159 views
5

我試圖用SendMessage發送一個按鍵,並不真正瞭解lParam。我知道不同的位代表每個參數,並且他們需要按順序排列。如何創建lParam的SendMessage WM_KEYDOWN

我讀過this question & this,所以我知道這責令位需要在,我只是不知道該怎麼辦呢?

我將如何創建以下lParam的?

repeat cound = 0, 
scan code = {Don't know what this is?}, 
extended key = 1, 
reserved = 0, 
context code = 0, 
previous key state = 1, 
transition state = 0 
+0

作爲鏈接後國家,不要使用SendMessage函數發送鍵擊,使用SendInput代替。 http://blogs.msdn.com/b/oldnewthing/archive/2005/05/30/423202.aspx – 2012-04-23 11:56:40

+1

@RussC:謝謝,但它需要與SendMessage完成,因爲我想將密鑰發送到其他窗口比活動的。真的,我只需要知道如何構建這個lParam。 – Drahcir 2012-04-23 12:13:41

+0

我已在下面更新了我的答案。你能澄清你將發送WM_KEYDOWN消息給SendMessage嗎? – 2012-04-23 12:32:38

回答

8

我意識到AutoIT有我需要的功能,所以有看了看source文件sendKeys.cpp,發現該功能下面的C++代碼片段,這將是很容易轉化爲C#:

scan = MapVirtualKey(vk, 0); 

// Build the generic lparam to be used for WM_KEYDOWN/WM_KEYUP/WM_CHAR 
lparam = 0x00000001 | (LPARAM)(scan << 16);   // Scan code, repeat=1 
if (bForceExtended == true || IsVKExtended(vk) == true) 
    lparam = lparam | 0x01000000;  // Extended code if required 

if ((m_nKeyMod & ALTMOD) && !(m_nKeyMod & CTRLMOD)) // Alt without Ctrl 
    PostMessage(m_hWnd, WM_SYSKEYDOWN, vk, lparam | 0x20000000); // Key down, AltDown=1 
else 
    PostMessage(m_hWnd, WM_KEYDOWN, vk, lparam); // Key down 

掃描代碼可以根兒ated與MapVirtualKey

C#翻譯:

public static void sendKey(IntPtr hwnd, VKeys keyCode, bool extended) 
{ 
    uint scanCode = MapVirtualKey((uint)keyCode, 0); 
    uint lParam; 

    //KEY DOWN 
    lParam = (0x00000001 | (scanCode << 16)); 
    if (extended) 
    { 
     lParam |= 0x01000000; 
    } 
    PostMessage(hwnd, (UInt32)WMessages.WM_KEYDOWN, (IntPtr)keyCode, (IntPtr)lParam); 

    //KEY UP 
    lParam |= 0xC0000000; // set previous key and transition states (bits 30 and 31) 
    PostMessage(hwnd, WMessages.WM_KEYUP, (uint)keyCode, lParam); 
} 

[DllImport("user32.dll", CharSet = CharSet.Auto)] 
private static extern uint MapVirtualKey(uint uCode, uint uMapType);