古川制御日記

佐賀県武雄市の組み込み開発屋ブログ

Unityライクなマウス左右にスライドさせて数値いじれるSpinBox

public partial class SlidableSpinBox : NumericUpDown {

    bool press = false;
    int mouseX = 0;

    public SlidableSpinBox() {
        InitializeComponent();
        ContextMenu = new ContextMenu();
        mouseX = System.Windows.Forms.Cursor.Position.X;
        Timer t = new Timer();
        t.Tick += (object sender, EventArgs e) => {
            if (0 == (Control.MouseButtons & MouseButtons.Right))
                press = false;
            if (press) {
                var tmp = Value + (System.Windows.Forms.Cursor.Position.X - mouseX) * Increment;
                Value = (tmp > Maximum) ? Maximum : (tmp < Minimum) ? Minimum : tmp;
            }
            mouseX = System.Windows.Forms.Cursor.Position.X;
        };
        t.Interval = 10;
        t.Start();
    }
    protected override void OnMouseDown(MouseEventArgs e) {            
        base.OnMouseDown(e);
        if (e.Button == MouseButtons.Right) {
            ReleaseCapture();
            press = true;
            System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.SizeWE;
        }
    }
    protected override void OnMouseUp(MouseEventArgs e) {
        base.OnMouseUp(e);
        if (e.Button == MouseButtons.Right) {
            press = false;
            System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Arrow;
        }
    }
    [DllImport("user32.dll")]
    public static extern bool ReleaseCapture();
}
  • 自分矩形領域で右クリックを押してそのまま左右にマウスをスライドさせたら数値が上下に振れる
  • NumericUpDownを継承してるので分解能(Increment)や上限(Maximum)下限(Minimum)はNumericUpDownのプロパティが使える
  • 1点てこずったのが自分矩形領域で右クリック後、自分矩形領域外で右ボタンを離したときに謎のコンテキストメニューが表示されてしまった
  • 出来ればTimerで常時監視せず自分矩形領域外でのマウスの動きを必要な時にだけ(press状態時のみ)取得したいが、どうやればいいのやら。