SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

マウスジェスチャを実装する

マウスジェスチャを実装する(.NET版)

マウスジェスチャによる機能の迅速な呼び出し

  • X ポスト
  • このエントリーをはてなブックマークに追加

インターフェイスとデータ構造

 マウスジェスチャを検出するために次のクラスと列挙型を作ります。

インターフェイス
namespace MouseGesture_Net
{
    /// マウスジェスチャの判定を行う
    public class MouseGesture
    {
        /// 判定距離(プロパティ)
        public int Range
        
        /// マウスジェスチャの有効無効
        private bool enable;
        
        /// 判定距離
        private int range;
        
        /// 四方向それぞれについての情報(要素の大きさは4)
        private Direction []direction;
        
        /// マウスをキャプチャしているコントロール
        private Control control_;
        
        /// 移動距離計算用の古い位置
        private Point old;

        /// コンストラクタ
        public MouseGesture();

        /// マウスジェスチャの開始
        /// <param name="control">マウスジェスチャの
        /// 対象となるコントロール</param>
        /// <param name="pos">現在のマウス位置</param>
        public void Start(Control control,Point pos);

        /// マウスジェスチャの終わり
        public void End();

        /// マウスジェスチャの判定
        /// <param name="pos">マウスの位置</param>
        /// <returns>ジェスチャ</returns>
        public Arrow Test(Point pos);
        
        /// 4方向の情報をリセットする
        private void resetDirection();
        
       
        
        #region インラインクラス
        
        /// 一定の方向に関する情報を持つ。
        public class Direction
        {
            /// 有効無効
            public bool Enable;
            
            /// 累計移動距離
            public int Length;
            
            /// リセットします
            public void Reset();
            
            /// コンストラクタ
            public Direction();
        }    
        #endregion
    }
    
    /// 方向
    public enum Arrow
    {
        none =-1,  // 移動無し
        up   = 0,  // 上への移動
        right= 1,  // 右への移動
        down = 2,  // 下への移動
        left = 3   // 左への移動
    }
}

 とりあえずは、これらを実装すればちゃんとマウスジェスチャになります。

 以下では、重点項目だけを説明しています。

マウスジェスチャのスタート

 このメソッドは「MouseDown」イベントに仕掛けます。

Start
/// <summary>
/// マウスジェスチャの開始
/// </summary>
/// <param name="control">マウスジェスチャの対象となるコントロール
/// </param>
/// <param name="pos">現在のマウス位置</param>
public void Start(Control control, Point pos)
{
    enable =true;
    resetDirection();
    old =pos;
    
    control_ =control;
    control_.Capture =true;
}

 方向情報の初期化、位置のセット、コントロールから取得したウィンドウハンドルを使って、マウスキャプチャを行います。

マウスジェスチャの判定

 ここがマウスジェスチャの心臓部です。これは「MouseMove」イベントに仕掛けるのが妥当でしょう。

判定
/// <summary>
/// マウスジェスチャの判定
/// </summary>
/// <param name="pos">マウスの位置</param>
/// <returns>ジェスチャ</returns>
public Arrow Test(Point pos)
{    
    //有効なときだけ判定する。
    if(enable)
    {
        int ox = old.X ,oy = old.Y;
        Arrow arrow = Arrow.none;
        
        //情報を入れ替えておく
        old = pos;
        
        //移動量を判定して縦横どっちに動くかを判定
        if(Math.Abs(ox - pos.X) > Math.Abs(oy - pos.Y))
        {
            if(ox > pos.X)
            {
                direction[(int)Arrow.left].Length += ox - pos.X;
                direction[(int)Arrow.right].Length = 0;
                arrow = Arrow.left;
            }
            else if(pos.X >ox)
            {
                direction[(int)Arrow.right].Length += pos.X - ox;
                direction[(int)Arrow.left].Length = 0;
                arrow = Arrow.right;
            }
        }
        else
        {
            if(oy > pos.Y)
            {
                direction[(int)Arrow.up].Length += oy - pos.Y;
                direction[(int)Arrow.down].Length = 0;
                arrow = Arrow.up;
            }
            else if(pos.Y >oy)
            {
                direction[(int)Arrow.down].Length += pos.Y - oy;
                direction[(int)Arrow.up].Length = 0;
                arrow = Arrow.down;
            }
        }
        
        //移動を検知したとき
        if(arrow != Arrow.none)
        {
            if(direction[(int)arrow].Enable &&
                direction[(int)arrow].Length > range)
            {
                resetDirection();
                
                //同じ向きが2度入力されないようにする。
                direction[(int)arrow].Enable=false;
                
                return arrow;
            }
        }
    }
    return Arrow.none;
}

 直感に反しないよう、私なりに調整してあります。流れは次のようになります。

  1. マウスジェスチャが有効かの判定。
  2. 縦横の移動量を判定。
  3. 左右(または上下)どちらへ移動しているのかを判定。
  4. 移動量を加算。反対への移動量を0。
  5. その移動が有効であるかを判定。
  6. 移動量が検出量に達しているかを判定。

 もっと良い工夫をお持ちの方もいると思います。いろいろな人に試してもらいながらどんな仕組みにするのかを決定すると良いと思います。

マウスジェスチャの終わり

 ボタンが離されると、マウスキャプチャの魔法が解けてしまいます。よって、「MouseUp」イベントあたりでこのメソッドを呼ぶようにするのが妥当だと思います。

終わり
/// <summary>
/// マウスジェスチャの終わり
/// </summary>
public void End()
{
    if(enable)
    {
        enable =false;
        control_.Capture = false;
    }
}

 一応、control_.Captureにfalseを代入しておいてください。

まとめて使う

 まずは、MouseGestureクラスを作ってください。

 そしたら、イベントの設定をします。「MouseDown」のなかでStart()を、「MouseMove」のなかでTest()を、「MouseUp」のなかでEnd()を呼び出すようにセットしてください。

 これでTest()を呼び出すたびに、Arrow列挙型で値が帰ってくるようになります。

まとめ

 マウスジェスチャはアプリケーションに大きな魅力を付加します。使いこなせば、ボタンにカーソルを移動することなく素早く操作できるようになります。

 ぜひ、実装を検討してみてください。

 それと、今回はサンプルなので、使いやすさよりも説明のしやすさを優先しました。せっかくイベントという仕組みがあるのですから、それをしっかりと利用した方がより良くなると思います。

参考資料

  1. 猫でも分かるプログラミング Windows SDK編 第2部 『第101章 マウス・キャプチャー
  2. WisdomSoft 『標準 Windows API
  3. @IT .NET TIPS 『Win32 APIやDLL関数を呼び出すには?
  4. Microsoft Win32とMicrosoft .NET Framework APIとの対応
修正履歴

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
マウスジェスチャを実装する連載記事一覧
この記事の著者

利都(りと)

陸奥でプログラムをしている学生。LOGOからVB6.0へ。現在は主にC系言語を利用。Atelier BlueにてManaged DirectXについてのTipsを書いている。http://www.atelier-blue.com/IL(CIL,MSIL)もしているのでそちらに興味がある方もどうぞ。Manag...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/382 2006/08/21 15:52

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング