C# でジョイスティックを使う方法について記載します。
[概要]
まずは動かしてみます。
[環境]
こんな感じのテストプログラムを作成してみます。

["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日 新規作成、木下英俊