2012-11-10 40 views
0

我正在使用Winform在DirectX遊戲中提供按鈕。所以我使用這個類:爲什麼按鍵一次就像反覆按下一樣?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 

namespace DirectInput 
{ 
    public class cDirectInput 
    { 
     [DllImport("user32.dll")] 
     static extern UInt32 SendInput(UInt32 nInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] pInputs, Int32 cbSize); 

     [StructLayout(LayoutKind.Sequential)] 
     struct MOUSEINPUT 
     { 
      public int dx; 
      public int dy; 
      public int mouseData; 
      public int dwFlags; 
      public int time; 
      public IntPtr dwExtraInfo; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     struct KEYBDINPUT 
     { 
      public short wVk; 
      public short wScan; 
      public int dwFlags; 
      public int time; 
      public IntPtr dwExtraInfo; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     struct HARDWAREINPUT 
     { 
      public int uMsg; 
      public short wParamL; 
      public short wParamH; 
     } 

     [StructLayout(LayoutKind.Explicit)] 
     struct INPUT 
     { 
      [FieldOffset(0)] 
      public int type; 
      [FieldOffset(4)] 
      public MOUSEINPUT mi; 
      [FieldOffset(4)] 
      public KEYBDINPUT ki; 
      [FieldOffset(4)] 
      public HARDWAREINPUT hi; 
     } 

     const int KEYEVENTF_EXTENDEDKEY = 0x0001; 
     const int KEYEVENTF_KEYUP = 0x0002; 
     const int KEYEVENTF_UNICODE = 0x0004; 
     const int KEYEVENTF_SCANCODE = 0x0008; 


     public void Send_Key(short Keycode, int KeyUporDown) 
     { 
      INPUT[] InputData = new INPUT[1]; 

      InputData[0].type = 1; 
      InputData[0].ki.wScan = Keycode; 
      InputData[0].ki.dwFlags = KeyUporDown; 
      InputData[0].ki.time = 0; 
      InputData[0].ki.dwExtraInfo = IntPtr.Zero; 

      SendInput(1, InputData, Marshal.SizeOf(typeof(INPUT))); 
     } 

    } 
} 

然後我送按鈕與此:

DirectInput.cDirectInput d = new DirectInput.cDirectInput(); 
d.Send_Key(0x11, 0x0008); 

但是,當我把它它是永久性的。當我發送w時,玩家將永遠前進。我可以通過按鍵盤上的w來停止。爲什麼它不停止?當我將它發送給編輯器時,當我停止發送時它會停止,遊戲不會停止。問題是什麼? 提前謝謝!

+0

什麼是?我什至不......你爲什麼要發鑰匙......我不知道是什麼! – LightStriker

+1

你應該看看'Send_Key'參數的含義,你所描述的聲音會發送一個按鍵事件,但你必須稍後發送一個鍵釋放事件才能停止鍵按下。 – schnaader

+0

關於Windows的關鍵事件處理的一些相關信息:如果按下一個鍵,Windows將等待(沒有事件觸發),並在一段時間後開始創建大量按鍵事件。這種模式在文本編輯器中很好用,但不適用於遊戲。因此,遊戲需要訪問較低級別的密鑰處理,以精確地知道密鑰何時處於按下狀態以及何時不處於按下狀態。在你的情況下,如果你發送按鍵事件,應用程序會認爲它被按下直到發佈事件。 – Hari

回答

2

您正在發送按鍵消息,但未發送按鍵消息。從文檔:

KEYBDINPUT.dwFlags:

  • KEYEVENTF_KEYUP(0×0002)
    如果指定,鍵被釋放。如果未指定,則正在按下該鍵。

要1秒鐘前進,嘗試:

d.Send_Key(0x11, 0x0008); 
Thread.Sleep(1000); 
d.Send_Key(0x11, 0x000A); 

注意,之所以按瓦特修復的問題是,它發送keydown事件(這會被忽略),然後keyup事件,最後釋放密鑰。

+0

謝謝,現在工作! – user1633958

相關問題