1

最近、XBOX 360 コントローラー ドライバーを作成してみました。ボタンが押されているか押されているかを検出する必要があります。したがって、押したままにすると、ボタンを 1 回押すのと同じように、特定の関数も 1 回呼び出されます。これが私のコードです(別の投稿でこのソリューションを見つけましたが、うまくいきませんでした)

using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using SharpDX.XInput;
using System.Runtime.InteropServices;

namespace Windows_XBOX_Controller_Driver
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);

        private static Controller controller;
        private State stateNew;
        private State stateOld;
        private int x, y;

        public Form1()
        {
            InitializeComponent();
            Setup();
        }

        private void loop_Tick(object sender, EventArgs e)
        {
            if(!enabledcb.Checked)
            {
                return;
            }
            //
            stateNew = controller.GetState();
            ///////////////////////////////////
            x = stateNew.Gamepad.RightThumbX;
            y = stateNew.Gamepad.RightThumbY;

            x /= 1000;
            y /= 1000;
            //////////////////////////////
            int movementX = x;
            int movementY = y;

            movementX *= (int)sensnud.Value;
            movementY *= (int)sensnud.Value;

            movementX /= 2;
            movementY /= 2;

            movementY *= -1;
            ////////////////////////
            if (x > buffernud.Value || x < -buffernud.Value)
            {
                Cursor.Position = new Point(Cursor.Position.X + movementX, Cursor.Position.Y);
            }
            if(y > buffernud.Value || y < -buffernud.Value)
            {
                Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y + movementY);
            }
            //buttons
            CheckButtons();
        }

        private void CheckButtons()
        {

            //a left click
            if (stateOld.Gamepad.Buttons == GamepadButtonFlags.LeftShoulder && stateNew.Gamepad.Buttons == GamepadButtonFlags.LeftShoulder)
            {
                LeftClick();
            }

            //b right click
            if (stateOld.Gamepad.Buttons == GamepadButtonFlags.RightShoulder && stateNew.Gamepad.Buttons == GamepadButtonFlags.RightShoulder)
            {
                RightClick();
            }

            //dpad up button sens up
            if (stateOld.Gamepad.Buttons == GamepadButtonFlags.DPadUp && stateNew.Gamepad.Buttons == GamepadButtonFlags.DPadUp)
            {
                sensnud.UpButton();
            }

            //dpad down button sens down
            if (stateOld.Gamepad.Buttons == GamepadButtonFlags.DPadDown && stateNew.Gamepad.Buttons == GamepadButtonFlags.DPadDown)
            {
                sensnud.DownButton();
            }
            stateOld = stateNew;
        }

        private void LeftClick()
        {
            int X = Cursor.Position.X;
            int Y = Cursor.Position.Y;
            mouse_event(0x02 | 0x04, (uint)X, (uint)Y, 0, 0);
            Thread.Sleep(100);
        }

        private void RightClick()
        {
            int X = Cursor.Position.X;
            int Y = Cursor.Position.Y;
            mouse_event(0x08 | 0x10, (uint)X, (uint)Y, 0, 0);
            Thread.Sleep(100);
        }

        private void LoadController()
        {
            controller = new Controller(UserIndex.One);
            if(!controller.IsConnected)
            {
                MessageBox.Show("Error", "It seems like there is no XBOX 360 Controller connected via USB!");
                Application.Exit();
            }
        }

        private void updateLoop_Tick(object sender, EventArgs e)
        {
            xlbl.Text = "Offset X: " + x;
            ylbl.Text = "Offset Y: " + y;
        }

        private void applybtn_Click(object sender, EventArgs e)
        {
            loop.Interval = (int)updatenud.Value;
        }

        private void Setup()
        {
            LoadController();
        }
    }
}

このコードを使用すると、ボタンを押したままにすることができ、クリック機能または呼び出されているものは何でもスパムします。

また、押されたときにtrueに設定され、押されていないときにfalseに設定されている「押された」ブール値を使用してみました。そして、「押された」が== falseの場合にのみ呼び出しを行います。

どちらも機能しませんでした。

その問題に対する他の解決策はありますか?

これが悪い質問である場合は申し訳ありません。質問のルールとヒントを読み、重複を検索しましたが、最初の解決策を得たもの以外は見つかりませんでした。

4

2 に答える 2

1

その問題に対する他の解決策はありますか?

これは、別のエンジン用に先日書いたクラスです。しかし、私はそれが他のエンジンにも同様に当てはまると考えました. これがお役に立てば幸いです:

基本的に、キーが現在のフレームで保持され、最後のフレームで保持されていないかどうかを確認します。それらの主要な状態はディクショナリに保存されます

重要な部分は次のとおりです。

public bool IsKeyPress(Keys key)
{
    bool isCurrentlyPressed = WaveServices.Input.KeyboardState.IsKeyPressed(key);
    bool previouslyReleased = this.previousKeyStates[key] == ButtonState.Release;

    this.previousKeyStates[key] = isCurrentlyPressed ? ButtonState.Pressed : ButtonState.Release;

    return  isCurrentlyPressed && previouslyReleased;
}
于 2016-04-16T11:37:32.847 に答える
0

私はすでにそれを理解しました 愚かな間違い: ボタンを押すための if 句の最初の条件を反転するのを忘れていました

于 2016-04-16T11:29:33.887 に答える