2014-02-24 49 views
1
public class sendKeys { 
    [DllImport("user32.dll")] 
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 
    [DllImport("user32.dll")] 
    public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr, lParam); 

    public static void sendKeystroke(ushort k) 
     { 
      const uint WM_KEYDOWN = 0x0100; 
      const uint WM_SYSCOMMAND = 0x018; 
      const uint SC_CLOSE = 0x053; 

      IntPtr WindowToFind = FindWindow(null, "processname"); 

      IntPtr result3 = SendMessage(WindowToFind, WM_KEYDOWN, ((IntPtr)k), (IntPtr)0); 
     } 
} 

http://msdn.microsoft.com/en-us/library/windows/desktop/ms646280%28v=vs.85%29.aspx 我在上面的頁面讀取,該lParam參數應該包含所有我想送個bit參數。例如,如果我想爲ScanCode發送一個「0x2D」值,我該怎麼做?設置WM_KEYDOWN lParam的參數

+1

當你沒有真正發送指針,但實際的國際價值,你也可以使用: 函數[DllImport(「user32.dll中」) 靜extern IntPtr SendMessage(IntPtr hWnd,UInt32 Msg,Int32 wParam,Int32 lParam); 在這種情況下,您不需要投射到IntPtr。 – csgero

+0

這看起來不是正確的解決方案,但我們不能告訴你正確的解決方案,因爲你沒有告訴我們問題 –

回答

4

MSDN頁面告訴你lParam哪些位用於每個參數。所有你需要做的是一些位移位組裝lParam

uint repeatCount = 0; 
uint scanCode = 0x2D; 
uint extended = 0; 
uint context = 0; 
uint previousState = 0; 
uint transition = 0; 

// combine the parameters above according to the bit 
// fields described in the MSDN page for WM_KEYDOWN 

uint lParam = repeatCount 
    | (scanCode << 16) 
    | (extended << 24) 
    | (context << 29) 
    | (previousState << 30) 
    | (transition << 31); 
+0

完美適用於WM_KEYDOWN消息,但不適用於[WM_KEYUP](http:// msdn.microsoft.com/en-us/library/windows/desktop/ms646281%28v=vs.85%29.aspx)消息,我應該將previousState和transition設置爲1,作爲ArithmeticOverflowException拋出 – Fehniix

+1

@PhoenìxI無法重現此(它適用於我,罰款並沒有例外)。你是否使用了我上面發佈的* exact *代碼(只是將'previousState'和'transition'設置爲'1')? – TypeIA

+0

@dvnrss是的,我使用的是您發佈的相同代碼。順便說一句,如果我在函數聲明中用Int32將IntPtr替換爲csgero建議的問題,問題似乎就解決了,但是爲什麼? – Fehniix

1

下面是使用TypeIA的答案,以幫助那些有溢出問題更完整的例子。我加入了這個,因爲他的回答是我所見過的任何必要的基本內容中最正確和最直接的一個,以實際完成這項工作。


TypeIA的和Fehniix與轉換:

MSDN的頁面告訴你什麼的lParam位用於每個參數。所有你需要做的是一些位轉移到組裝lParam

const uint WM_KEYDOWN = 0x0100; 
const uint WM_SYSCOMMAND = 0x018; 
const uint SC_CLOSE = 0x053; 

[DllImport("user32.dll")] 
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 

uint repeatCount = 0; 
uint scanCode = k; 
uint extended = 0; 
uint context = 0; 
uint previousState = 0; 
uint transition = 0; 

// combine the parameters above according to the bit 
// fields described in the MSDN page for WM_KEYDOWN 

uint lParamDown = repeatCount 
    | (scanCode << 16) 
    | (extended << 24) 
    | (context << 29) 
    | (previousState << 30) 
    | (transition << 31); 

previousState = 1; 
transition = 1; 

uint lParamUp = repeatCount 
    | (scanCode << 16) 
    | (extended << 24) 
    | (context << 29) 
    | (previousState << 30) 
    | (transition << 31); 

var ipKey = (IntPtr)(int)k; 
var ipLParamDown = unchecked((IntPtr)(int)lParamDown); 
var ipLParamUp = unchecked((IntPtr)(int)lParamUp); 

IntPtr WindowToFind = FindWindow(null, "processname"); 

IntPtr result3 = SendMessage(WindowToFind, WM_KEYDOWN, ipKey, ipLParamDown); 
IntPtr result4 = SendMessage(WindowToFind, WM_KEYUP, ipKey, ipLParamUp);