Захват джойстика - PullRequest
       29

Захват джойстика

2 голосов
/ 11 декабря 2010

Я хочу захватить ввод с джойстика с помощью Winmm DLL. У меня нет особых знаний об импорте и работе с DLL.

Я пытался это сделать, но понятия не имею, как это сделать ..

[DllImport("winmm.dll")]
public static extern string joyGetPosEx(uint dev, JoyinfoEx ) //Something Similar

Как мне получить структуру joyinfoEx из DLL и поместить ее в JoygetPosEx ..? : S

Ответы [ 2 ]

4 голосов
/ 11 декабря 2010

Как показывает ваш вопрос, вы должны импортировать функцию joyGetPosEx из wimmm.dll.Это часто называется P / Invoking , потому что вы вызываете функцию из нативного Win32 API (или «платформенной» DLL).Вы уже знаете, что вам нужно использовать эту функцию, поэтому давайте посмотрим на нее более внимательно.

Документация для этой функции указывает, что она принимает два параметра:

  • Первое (uJoyID) является простым int (или целочисленным) значением, которое идентифицирует запрашиваемый джойстик.

  • Второе (pji)) немного сложнее, чем первый, и я думаю, что это та часть, с которой вы боролись.Вместо стандартного типа значения это структура с именем JOYINFOEX, и вы должны определить эту структуру в своем коде.Функция joyGetPosEx заполняет эту специальную структуру информацией о положении джойстика, позволяя ему возвращать сразу несколько разных значений.Вот почему вы должны передать его как ссылку (ref), потому что функция на самом деле собирается заполнить экземпляр структуры, которую вы передаете ей набором значений.Ваш код может затем прочитать эти значения обратно из переменной, содержащей экземпляр структуры.

    Документация для этой структуры доступна здесь , и она сообщает вамимена и типы данных
    каждого из его членов.Вы можете трактовать DWORD как int, поэтому его объявление выглядит следующим образом:

    [StructLayout(LayoutKind.Sequential)]
    public struct JOYINFOEX 
    {
        public int dwSize; 
        public int dwFlags; 
        public int dwXpos; 
        public int dwYpos; 
        public int dwZpos; 
        public int dwRpos; 
        public int dwUpos; 
        public int dwVpos; 
        public int dwButtons; 
        public int dwButtonNumber; 
        public int dwPOV; 
        public int dwReserved1; 
        public int dwReserved2; 
    }
    

Наконец, функция joyGetPosEx возвращает значение типа int,Это значение указывает, успешно ли выполнена функция, а если нет, то что именно пошло не так.Это код ошибки.Приведенная выше документация дает вам таблицу всех возможных значений, которые могут быть возвращены.Если вы хотите проверить эти значения, вам нужно определить их как константы в вашем коде:

public const int JOYERR_BASE = 160
public const int JOYERR_PARMS = (JOYERR_BASE + 5); 
public const int JOYERR_UNPLUGGED = (JOYERR_BASE + 7);
public const int MMSYSERR_BASE = 0;
public const int MMSYSERR_BADDEVICEID = (MMSYSERR_BASE + 2); 
public const int MMSYSERR_INVALPARAM = (MMSYSERR_BASE + 11); 

Итак, учитывая вышеизложенное, окончательное определение функции выглядит следующим образом:

[DllImport("winmm.dll")]
public static extern int joyGetPosEx(int uJoyID, ref JOYINFOEX pji);

В будущем имейте в виду pinvoke.net как справочник по определению и объявлению этих функций Win32 API в вашем коде.В ней нет функции joyGetPosEx (или, по крайней мере, не так, как я нашел), но обычно в ней есть почти все, что вам нужно.И затем, если это не сработает, вы можете сделать, как я пытался объяснить выше: посмотрите на оригинальную документацию для функции и попытайтесь определить, как ее определить для работы в .NET.

3 голосов
/ 11 декабря 2010

Функция возвращает данные через второй аргумент.Возвращаемое значение является целым числом, указывающим на любую возможную ошибку.Правильное объявление:

    [DllImport("winmm.dll")]
    private static extern int joyGetPosEx(int joystickNumber, ref JOYINFOEX info);

Вы должны будете объявить структуру следующим образом:

    [StructLayout(LayoutKind.Sequential)]
    private struct JOYINFOEX {
        public int dwSize;
        public int dwFlags;
        public int dwXpos;
        public int dwYpos;
        public int dwZpos;
        public int dwRpos;
        public int dwUpos;
        public int dwVpos;
        public int dwButtons;
        public int dwButtonNumber;
        public int dwPOV;
        public int dwReserved1;
        public int dwReserved2;
    }

Пример вызова:

        JOYINFOEX info = new JOYINFOEX();
        info.dwSize = Marshal.SizeOf(info);
        int err = joyGetPosEx(1, ref info);
        if (err != 0) reportError(err);
        else {
            int xpos = info.dwXpos;
            // Do something with xpos
            //...
        }
...