2017-01-27 2 views
0

j'ai donc une application console et je l'ai importé RegisterRawInputDevices de user32.dllRéception d'entrée De RawInput périphériques enregistrés dans C#

Vous ne pouvez pas enregistrer un périphérique sur le gestionnaire de fenêtre de la console, donc j'ai créé un classe qui hérite de Form. C'est aussi la classe qui remplace WndProc. En ce moment tout ce que je l'ai fait faire est d'écrire un message.Msg à la console. Donc j'instancie le formulaire et passe le gestionnaire de fenêtre à RegisterRawInputDevices où il enregistre la souris et le clavier. Mais après cela, la fenêtre ne reçoit plus aucun message.
Edit: Ajout d'un code pour montrer ce que j'essaie actuellement.
Ceci est ma principale méthode (bien que j'ai une autre code qui maintient la fenêtre vivante):

Input window = new Input(); 
PS4Input.RegisterControllers(window.Handle); 

C'est la classe que j'utilise pour créer la fenêtre. Assez basique:

public class Input : Form 
{ 
    protected override void WndProc(ref Message message) 
    { 
     Console.WriteLine(message.Msg); 
     base.WndProc(ref message); 
    } 
} 

Voici comment j'enregistre mon appareil. Il dit actuellement que cela fonctionne.

[DllImport("User32.dll", SetLastError = true)] 
extern static uint GetRawInputDeviceList(IntPtr pRawInputDeviceList, ref uint uiNumDevices, uint cbSize); 

[DllImport("User32.dll", SetLastError = true)] 
extern static uint GetRawInputDeviceInfo(IntPtr hDevice, uint uiCommand, IntPtr pData, ref uint pcbSize); 

[DllImport("user32.dll", SetLastError = true)] 
static extern uint GetRawInputDeviceInfo(IntPtr hDevice, uint uiCommand, ref DeviceInfo pData, ref uint pcbSize); 

[DllImport("user32.dll", SetLastError = true)] 
static extern bool RegisterRawInputDevices(RawInputDevice[] pRawInputDevice, uint numberDevices, uint size); 

[DllImport("user32.dll", SetLastError = true)] 
internal extern static uint GetRegisteredRawInputDevices(RawInputDevice[] pRawInputDevice, ref uint puiNumDevices, uint cbSize); 

public static void RegisterControllers(IntPtr hwnd) 
{ 
    uint deviceCount = 0; 
    int dwSize = Marshal.SizeOf(typeof(RawInputDeviceList)); 

    if (GetRawInputDeviceList(IntPtr.Zero, ref deviceCount, (uint)dwSize) == 0) 
    { 
     IntPtr pRawInputDeviceList = Marshal.AllocHGlobal((int)(dwSize * deviceCount)); 
     GetRawInputDeviceList(pRawInputDeviceList, ref deviceCount, (uint)dwSize); 

     for (int i = 0; i < deviceCount; i++) 
     { 
      RawInputDeviceList rid = (RawInputDeviceList)Marshal.PtrToStructure(new IntPtr(pRawInputDeviceList.ToInt32() + (dwSize * i)), typeof(RawInputDeviceList)); 

      uint size = (uint)Marshal.SizeOf(typeof(DeviceInfo)); 
      var di = new DeviceInfo { Size = Marshal.SizeOf(typeof(DeviceInfo)) }; 

      GetRawInputDeviceInfo(rid.hDevice, (uint)RawInputDeviceInfo.RIDI_DEVICEINFO, ref di, ref size); 

      if (di.Type == DeviceType.RimTypeHid && di.HIDInfo.Usage == (ushort)HidUsage.Gamepad && di.HIDInfo.UsagePage == (ushort)HidUsagePage.GENERIC) 
      { 
       var device = new RawInputDevice(); 
       Console.WriteLine("Registering Device"); 

       device.UsagePage = di.HIDInfo.UsagePage; 
       device.Usage = (ushort)HidUsage.Keyboard; 
       device.Flags = RawInputDeviceFlags.INPUTSINK; 
       device.Target = hwnd; 

       RawInputDevice[] devices = new RawInputDevice[1]; 
       devices[0] = device; 

       if (RegisterRawInputDevices(devices, (uint)devices.Length, (uint)Marshal.SizeOf(typeof(RawInputDevice))) == false) 
       { 
        Console.WriteLine("Failure"); 
        return; 
       } 
       else 
       { 
        Console.WriteLine("Success!"); 
       } 
       break; 
      } 
     } 

     Marshal.FreeHGlobal(pRawInputDeviceList); 
    } 
    else 
    { 
     Console.WriteLine(Marshal.GetLastWin32Error()); 
    } 
} 

[StructLayout(LayoutKind.Sequential)] 
internal struct RawInputDevice 
{ 
    internal ushort UsagePage; 
    internal ushort Usage; 
    internal RawInputDeviceFlags Flags; 
    internal IntPtr Target; 

    public override string ToString() 
    { 
     return string.Format("{0}/{1}, flags: {2}, target: {3}", UsagePage, Usage, Flags, Target); 
    } 
} 

[StructLayout(LayoutKind.Sequential)] 
internal struct RawInputDeviceList 
{ 
    public IntPtr hDevice; 
    public uint dwType; 
} 

[StructLayout(LayoutKind.Explicit)] 
public struct DeviceInfo 
{ 
    [FieldOffset(0)] 
    public int Size; 
    [FieldOffset(4)] 
    public int Type; 

    [FieldOffset(8)] 
    public DeviceInfoMouse MouseInfo; 
    [FieldOffset(8)] 
    public DeviceInfoKeyboard KeyboardInfo; 
    [FieldOffset(8)] 
    public DeviceInfoHid HIDInfo; 

    public override string ToString() 
    { 
     return string.Format("DeviceInfo\n Size: {0}\n Type: {1}\n", Size, Type); 
    } 
} 

Répondre

0

Pas assez de détails, mais je pense que votre look de code comme ceci:

public static void Main(string[] args) 
{ 
    MyClass messageReciever = new MyClass(); 
    messageReciever.StartRecievingMessages(); 
    Console.WriteLine("Press Q to exit..."); 
    while (Console.ReadKey(true).Key != ConsoleKey.Q) { } 
} 

Ajouter le [STAThread] à votre point d'entrée pour garder vivante la fenêtre:

[STAThread] 
public static void Main(string[] args) 

MISE À JOUR : J'ai une solution pour vous mon ami! Dans l'entrée du programme dont vous avez besoin d'ajouter ceci:

Application.Run(window); 

Et aussi en remplacement de la classe d'entrée OnShow (pour cacher la fenêtre quand il apparaît):

protected override void OnShown(EventArgs e) 
{ 
    base.OnShown(e); 
    Hide(); 
} 

La raison en est que le formulaire doit d'abord obtenir la mise au point, seulement alors Flag - "continue de capturer en arrière-plan" fonctionne.

+0

OP modifié pour afficher le code que j'utilise actuellement. – Mystborn