操纵杆钥匙捕获

时间:2010-12-11 13:41:48

标签: c# .net winapi joystick winmm

我想使用winmm dll从操纵杆捕获输入..我对导入和使用DLL没有太多了解。

我试图这样做,但我不知道该怎么做..

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

如何从DLL获取joyinfoEx结构并将其放入JoygetPosEx ..? :S

2 个答案:

答案 0 :(得分:4)

正如您的问题所示,您必须从joyGetPosEx导入wimmm.dll功能。这通常称为P/Invoking,因为您正在从本机Win32 API(或“平台”DLL)调用函数。您已经知道需要使用该功能,所以让我们更仔细地看一下它。

该函数的documentation表示它需要两个参数:

  • 第一个(uJoyID)是一个简单的int(或整数)值,用于标识要查询的操纵杆。

  • 第二个(pji)比第一个稍微复杂一点,我认为这是你正在努力的部分。它不是标准值类型,而是一个名为JOYINFOEX的结构,您必须在代码中定义该结构。 joyGetPosEx函数的作用是填充该特殊结构,其中包含有关操纵杆位置的信息,允许它一次性返回一堆不同的值。这就是为什么你必须将它作为引用传递(ref),因为该函数实际上将填充使用一组值传递给它的结构的实例。然后,您的代码可以读回包含结构实例的变量 out 的那些值。

    该结构的文档可用here,它告诉它你是每个成员的名字和数据类型。您可以将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中工作。

答案 1 :(得分:3)

该函数通过第二个参数返回数据。返回值是一个整数,表示任何可能的错误。适当的声明是:

    [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
            //...
        }