C# でジョイスティックを使う方法

C#  でジョイスティックを使う方法について記載します。

 

 

目次

1. まずは動かしてみる

参考

 

 

1. まずは動かしてみる

[概要]

まずは動かしてみます。

 

[環境]

 

こんな感じのテストプログラムを作成してみます。

作成するプログラムの画面

 

["Joystick.cs"]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace JoyStickController
{
    public enum JOYSTICK_ID
    {
        JOYSTICKID1 = 0,
        JOYSTICKID2 = 1,
        JOYSTICKID3 = 2,
        JOYSTICKID4 = 3,
        JOYSTICKID5 = 4,
        JOYSTICKID6 = 5,
        JOYSTICKID7 = 6,
        JOYSTICKID8 = 7,
        JOYSTICKID9 = 8,
        JOYSTICKID10 = 9,
        JOYSTICKID11 = 10,
        JOYSTICKID12 = 11,
        JOYSTICKID13 = 12,
        JOYSTICKID14 = 13,
        JOYSTICKID15 = 14,
        JOYSTICKID16 = 15
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct JOYINFO
    {
        public uint dwXpos;
        public uint dwYpos;
        public uint dwZpos;
        public uint dwButtons;
    }

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

    public enum MMRESULT : uint
    {
        JOYERR_NOERROR = 0,
        MMSYSERR_NOERROR = 0,
        MMSYSERR_ERROR = 1,
        MMSYSERR_BADDEVICEID = 2,
        MMSYSERR_NOTENABLED = 3,
        MMSYSERR_ALLOCATED = 4,
        MMSYSERR_INVALHANDLE = 5,
        MMSYSERR_NODRIVER = 6,
        MMSYSERR_NOMEM = 7,
        MMSYSERR_NOTSUPPORTED = 8,
        MMSYSERR_BADERRNUM = 9,
        MMSYSERR_INVALFLAG = 10,
        MMSYSERR_INVALPARAM = 11,
        MMSYSERR_HANDLEBUSY = 12,
        MMSYSERR_INVALIDALIAS = 13,
        MMSYSERR_BADDB = 14,
        MMSYSERR_KEYNOTFOUND = 15,
        MMSYSERR_READERROR = 16,
        MMSYSERR_WRITEERROR = 17,
        MMSYSERR_DELETEERROR = 18,
        MMSYSERR_VALNOTFOUND = 19,
        MMSYSERR_NODRIVERCB = 20,
        WAVERR_BADFORMAT = 32,
        WAVERR_STILLPLAYING = 33,
        WAVERR_UNPREPARED = 34,

        JOYERR_PARMS = NativeMethods.JOYERR_PARMS,          //!< 165: 指定されたジョイスティックIDは無効
        JOYERR_UNPLUGGED = NativeMethods.JOYERR_UNPLUGGED   //!< 167: 指定されたジョイスティックが接続されていない
    }

    public class JoyStick
    {
        private JOYINFO _pji;
        private JOYINFOEX _pjiex;
        private MMRESULT _mmresult;

        public JoyStick(JOYSTICK_ID joystick_id)
        {
            _pji = new JOYINFO();
            _pjiex = new JOYINFOEX();
            JoystickId = joystick_id;
        }

        public JOYSTICK_ID JoystickId { get; }

        private MMRESULT GetPos(uint uJoyID, ref JOYINFO pji)
        {
            return NativeMethods.joyGetPos(uJoyID, ref pji);
        }

        private MMRESULT GetPosEx(uint uJoyID, ref JOYINFOEX pjiex)
        {
            return NativeMethods.joyGetPosEx(uJoyID, ref pjiex);
        }

        public JOYINFO GetPos()
        {
            _mmresult = GetPos((uint)JoystickId, ref _pji);
            return _pji;
        }

        public JOYINFOEX GetPosEx()
        {
            _pjiex.dwSize = (uint)Marshal.SizeOf(_pjiex);
            _pjiex.dwFlags = NativeMethods.JOY_RETURNALL;
            _mmresult = GetPosEx((uint)JoystickId, ref _pjiex);
            return _pjiex;
        }

        public static MMRESULT JoyConfigChanged()
        {
            return NativeMethods.joyConfigChanged(0);
        }

        public MMRESULT GetMMRESULT()
        {
            return _mmresult;
        }
    }

    internal static class NativeMethods
    {
#pragma warning disable IDE1006 // 命名スタイル
        [DllImport("winmm.dll")]
        public static extern uint joyGetNumDevs();
        [DllImport("winmm.dll")]
        public static extern MMRESULT joyGetPos(uint uJoyID, ref JOYINFO pji);
        [DllImport("winmm.dll"), System.Security.SuppressUnmanagedCodeSecurity]
        public static extern MMRESULT joyGetPosEx(uint uJoyID, ref JOYINFOEX pjiex);
        [DllImport("winmm.dll")]
        public static extern MMRESULT joyConfigChanged(uint dwFlags);
#pragma warning restore IDE1006 // 命名スタイル

        public static UInt32 JOY_RETURNX = 0x00000001;
        public static UInt32 JOY_RETURNY = 0x00000002;
        public static UInt32 JOY_RETURNZ = 0x00000004;
        public static UInt32 JOY_RETURNR = 0x00000008;
        public static UInt32 JOY_RETURNU = 0x00000010;
        public static UInt32 JOY_RETURNV = 0x00000020;
        public static UInt32 JOY_RETURNPOV = 0x00000040;
        public static UInt32 JOY_RETURNBUTTONS = 0x00000080;
        public static UInt32 JOY_RETURNALL = (JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNR | JOY_RETURNU | JOY_RETURNV | JOY_RETURNPOV | JOY_RETURNBUTTONS);

        public const int JOYERR_BASE = 160;
        public const int JOYERR_PARMS = (JOYERR_BASE + 5);              //!< 指定されたジョイスティックIDは無効
        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);
    }
}

 

["Form1.cs"]

using JoyStickController;
using System;
using System.Windows.Forms;

namespace test_JoyStick
{
    public partial class Form1 : Form
    {
        private JoyStick _joyStick1 = new JoyStick(JOYSTICK_ID.JOYSTICKID1);
        private JoyStick _joyStick2 = new JoyStick(JOYSTICK_ID.JOYSTICKID2);

        public Form1()
        {
            InitializeComponent();
        }

        private void Timer1_Tick(object sender, EventArgs e)
        {
            // JoyStick 1
            {
                JOYINFOEX joyInfoEx1 = _joyStick1.GetPosEx();

                if (_joyStick1.GetMMRESULT() == MMRESULT.JOYERR_NOERROR) {
                    tb_x_1.Text = joyInfoEx1.dwXpos.ToString();
                    tb_y_1.Text = joyInfoEx1.dwYpos.ToString();
                    tb_z_1.Text = joyInfoEx1.dwZpos.ToString();
                    tb_buttons_1.Text = joyInfoEx1.dwButtons.ToString("X8");
                    tb_JoyStick1_ID.Text = (_joyStick1.JoystickId).ToString();
                }
                else
                {
                    if (tb_x_1.Text != "")
                    {
                        JoyStick.JoyConfigChanged();
                    }
                    tb_x_1.Text = "";
                    tb_y_1.Text = "";
                    tb_z_1.Text = "";
                    tb_buttons_1.Text = "";
                    tb_JoyStick1_ID.Text = "";
                }
            }

            // JoyStick 2
            {
                JOYINFOEX joyInfoEx2 = _joyStick2.GetPosEx();

                if (_joyStick2.GetMMRESULT() == MMRESULT.JOYERR_NOERROR)
                {
                    tb_x_2.Text = joyInfoEx2.dwXpos.ToString();
                    tb_y_2.Text = joyInfoEx2.dwYpos.ToString();
                    tb_z_2.Text = joyInfoEx2.dwZpos.ToString();
                    tb_buttons_2.Text = joyInfoEx2.dwButtons.ToString("X8");
                    tb_JoyStick2_ID.Text = (_joyStick2.JoystickId).ToString();
                }
                else
                {
                    if (tb_x_2.Text != "")
                    {
                        JoyStick.JoyConfigChanged();
                    }
                    tb_x_2.Text = "";
                    tb_y_2.Text = "";
                    tb_z_2.Text = "";
                    tb_buttons_2.Text = "";
                    tb_JoyStick2_ID.Text = "";
                }
            }
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            Close();
        }
    }
}

 

ダウンロード

サンプルプログラム ダウンロード

 

 

参考


 

記載:
2018年05月19日 新規作成、木下英俊