2016-07-16 48 views
0

Also ich habe diese C++ Funktion in einem DLLP/Invoke ändert die Werte der übergebenen Argumente

__declspec(dllexport) MOUSERAWDATA __stdcall GetMouseRawData(LPARAM lParam) 
{ 
    UINT bufferSize = 0; 
    BYTE *buffer = new BYTE[bufferSize]; 
    GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER)); 
    GetRawInputData((HRAWINPUT)lParam, RID_INPUT, (LPVOID)buffer, &bufferSize, sizeof(RAWINPUTHEADER)); 
    RAWINPUT *raw = (RAWINPUT*)buffer; 
    MOUSERAWDATA data; 
    if (raw->header.dwType == RIM_TYPEMOUSE) 
    { 
     data.longX = raw->data.mouse.lLastX; 
     data.longY = raw->data.mouse.lLastY; 
    } 
    return data; 
} 

und folgenden in meinem C# -Projekt:

[DllImport("RawInput.dll", CallingConvention = CallingConvention.StdCall)] 
private static extern MouseRawData GetMouseRawData(IntPtr lParam); 
. 
. 
. 
protected override void WndProc(ref Message m) 
{ 
    switch(m.Msg) 
    { 
     case WM_CREATE: 
      if (AttachMouseListener(this.Handle)) 
       Console.WriteLine("It works!"); 
      break; 
     case WM_INPUT: 
      MouseRawData data = GetMouseRawData(m.LParam); 
      break; 
     default: 
      base.WndProc(ref m); 
      break; 
    } 
} 

Wenn ich diesen Code ausführen, der folgende Wert wird auf die GetMouseRawData geben

The value being passed

Aber für einige reas auf den Wert von lParam auf der C++ Seite ist immer anders.

enter image description here

ich diesen Fall 0x004fe95c = 5237084

Wer weiß, warum dies geschieht?

+1

Ihre pinvoke Erklärung nicht mit Funktion Ihre C. Wahrscheinlich haben wir aufgrund der MouseRawData-Deklaration den Vorteil, sie nicht zu sehen, Funktionen, die eine Struktur zurückgeben, sind immer schwierig. Favor bool GetMouseRawData (LPARAM LParam, MOUSERAWDATA * Daten) stattdessen. –

Antwort

1

Sie reservieren einen Puffer der Länge 0. Dann "fragt" nach welcher Größe der Puffer sein soll. Und dann lügen Sie GetRawInputData, indem Sie ihnen sagen, dass Ihr Puffer die richtige Größe hat. Verschieben Sie Ihre Pufferzuweisung an den Punkt nach dem ersten Aufruf, bei dem Sie die erforderliche Größe des Puffers kennen gelernt haben.

UINT bufferSize = 0; 
BYTE *buffer = new BYTE[bufferSize]; 
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER)); 
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, (LPVOID)buffer, &bufferSize, sizeof(RAWINPUTHEADER)); 
RAWINPUT *raw = (RAWINPUT*)buffer; 

Sie müssen delete[] Ihren Puffer, um ein Leck zu verhindern. Sie müssen data (MOUSERAWDATA) initialisieren, um zu verhindern, dass es bedingt Müll enthält. Wie wird der Anrufer wissen, dass raw->header.dwType == RIM_TYPEMOUSE wahr oder falsch war?

Haben Sie darüber nachgedacht nur pinvoking GetRawInputData() direkt per Microsoft guidance:

public static extern int GetRawInputData(IntPtr hRawInput, RawInputCommand uiCommand, out RAWINPUT pData, ref int pcbSize, int cbSizeHeader); 

protected override void WndProc(ref Message m) 
{ 
    if (m.Msg == (int)WindowMessages.RawInput) // WindowMessages.RawInput = 0x00FF (WM_INPUT) 
    { 
     RAWINPUT input = new RAWINPUT(); 
     int outSize = 0; 
     int size = Marshal.SizeOf(typeof(RAWINPUT)); 

     outSize = Win32API.GetRawInputData(m.LParam, RawInputCommand.Input, out input, ref size, Marshal.SizeOf(typeof(RAWINPUTHEADER))); 
     if (outSize != -1) 
     { 
      if (input.Header.Type == RawInputType.Mouse) 
      { 
       //input.Mouse.LastX; 
       //input.Mouse.LastY; 
      } 
     } 
    } 
    base.WndProc(ref m); 
} 
+0

Danke für die Eingabe. Aber Ihre Antwort sagt mir nicht, warum sich der Wert ändert. – Abhinav

+0

Können Sie bestätigen, dass Sie Ihr .NET und Ihr C++ mit der gleichen Bitness erstellen? Beide 64-Bit oder beide 32-Bit. IntPtr wird eine andere Größe haben. –