操纵杆键捕获

Posted

技术标签:

【中文标题】操纵杆键捕获【英文标题】:Joystick Key Capture 【发布时间】:2010-12-11 13:41:48 【问题描述】:

我想使用 winmm dll 捕获来自操纵杆的输入。我对导入和使用 DLL 了解不多。

我尝试过,但我不知道该怎么做..

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

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

【问题讨论】:

【参考方案1】:

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

该函数的documentation 表示它接受两个参数:

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

第二个 (pji) 比第一个要复杂一些,我认为这是您正在努力解决的部分。它不是标准值类型,而是称为JOYINFOEX 的结构,您必须在代码中定义该结构。 joyGetPosEx 函数所做的就是用有关操纵杆位置的信息填充该特殊结构,允许它同时返回一堆不同的值。这就是为什么您必须将其作为引用传递 (ref),因为该函数实际上将 fill 使用一组值传递给它的结构实例。然后,您的代码可以从包含结构实例的变量中读取这些值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 中工作。

【讨论】:

请注意,winmm 中的操纵杆 API 是 DirectInput API 的薄包装器。如果您使用 DirectInput,您可能会获得更好的可靠性和更强大的功能。使用 DirectInput 的一个主要优点是您可以使用 DirectX SDK for Managed code 从托管代码中直接使用它:msdn.microsoft.com/en-us/library/ms920643.aspx【参考方案2】:

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

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

【讨论】:

非常感谢 这对我帮助很大。因此,例如,如果我只想获得 dwxPos,我会这样称呼它:joygetpos(1, ref info.dwXpos); ? 不,你必须通过结构。调用后,只需使用 info.dwXpos 我遇到了问题。它返回正确的 dwx 和 dwy 位置,但为什么不按下按钮?它总是返回 0。那是什么? :S

以上是关于操纵杆键捕获的主要内容,如果未能解决你的问题,请参考以下文章

JAVA捕获MYSQL主键冲突异常 示例如Exception ex 对应的异常 如何捕获,只要捕获,求满意答案

java 主键异常怎么捕获

捕获组合键 键盘组合键

为 iOS 上的功能键捕获 UIKeyCommand

在 SwiftUI 中捕获文本字段值而不按返回键 [重复]

如何通过 JavaScript 捕获 Mac 的命令键?