SHOEISHA iD

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

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

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

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

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

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

関数

 今回作る関数は下の4つだけです。

関数
//マウスジェスチャのスタート
void StartMouseGesture(MOUSEGESTURE *lpmg, HWND hwnd, int x, int y);

//マウスジェスチャの終わり
void EndMouseGesture(MOUSEGESTURE *lpmg);

//マウスジェスチャの判定を行う。
MGARROW TestMouseGesture(MOUSEGESTURE *lpmg, int x, int y);

//移動情報のリセット
void ResetDirection(MOUSEGESTURE *lpmg);

 最後のリセット関数は内部的に必要となるだけの関数なので、使用者は使うことがありません。行っているのは「direc」の移動距離リセットと有効化です。

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

 この関数は「WM_*BUTTONDOWN」に仕掛けます。

スタート
//マウスジェスチャのスタート
void StartMouseGesture(MOUSEGESTURE *lpmg, HWND hwnd, int x, int y){
    
    //有効化
    lpmg->enable = TRUE;
    
    //リセット
    ResetDirection(lpmg);
    
    lpmg->old.x = x;
    lpmg->old.y = y;
    
    //押されている間だのキャプチャを開始
    SetCapture(hwnd);
}

 マウスジェスチャ構造体、ウィンドウハンドル、位置を使ってマウスジェスチャの準備をします。また「SetCapture」を呼び出しています。

マウスジェスチャの判定

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

判定
//マウスジェスチャの判定を行う。
MGARROW TestMouseGesture(MOUSEGESTURE *lpmg, int x, int y){
    
    //有効なときだけ判定する。
    if(lpmg->enable){
        int ox = lpmg->old.x,oy = lpmg->old.y;
        int direc = (int)MG_NONE;

        //情報を入れ替えておく
        lpmg->old.x = x;
        lpmg->old.y = y;
        
        //移動量を判定して縦横どっちに動くかを判定
        if(abs(ox - x) > abs(oy - y)){
            if(ox > x){
                lpmg->direc[MG_LEFT].length += ox - x;
                lpmg->direc[MG_RIGHT].length = 0;
                direc = (int)MG_LEFT;
            } else if(x >ox){
                lpmg->direc[MG_RIGHT].length += x - ox;
                lpmg->direc[MG_LEFT].length = 0;
                direc = (int)MG_RIGHT;
            }
        } else {
            if(oy > y){
                lpmg->direc[MG_UP].length += oy - y;
                lpmg->direc[MG_DOWN].length = 0;
                direc = (int)MG_UP;
            } else if(y >oy){
                lpmg->direc[MG_DOWN].length += y - oy;
                lpmg->direc[MG_UP].length = 0;
                direc = (int)MG_DOWN;
            }
        }
        
        //移動を検知したとき
        if(direc !=MG_NONE){
            if(lpmg->direc[direc].enable &&
                lpmg->direc[direc].length > lpmg->range){

                ResetDirection(lpmg);
                
                //同じ向きが2度入力されないようにする。
                lpmg->direc[direc].enable=FALSE;

                return (MGARROW)direc;
            }
        }
    }
    return MG_NONE;
}

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

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

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

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

 ボタンが離されると、「SetCapture」の魔法が解けてしまいます。よって、「WM_*BUTTONUP」あたりに、この関数を仕掛けるのが妥当だと思います。

終わり
//マウスジェスチャの終わり
void EndMouseGesture(MOUSEGESTURE *lpmg){
    
    //マウスキャプチャの終わり
    ReleaseCapture();
    
    lpmg->enable = FALSE;
}

 一応「ReleaseCapture」を呼び出しておいてください。

サンプルの使い方

 まずはどこかに「MOUSEGESTURE構造体」を作ってください。次に「ZeroMemory」で全体を初期化した後、「range」に適当な値をセットしてください。

 そしたら、ウィンドウプロシージャの設定をします。「WM_*BUTTONDOWN」の中で「StartMouseGesture」を、「WM_MOUSEMOVE」の中で「TestMouseGesture」を、「WM_*BUTTONUP」の中で「EndMouseGesture」を呼び出すようにセットしてください。

 これで「TestMouseGesture」を呼び出すたびに「MGARROW列挙型」で値が返ってくるようになります。

まとめ

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

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

参考資料

  1. 猫でも分かるプログラミング Windows SDK編 第2部 『第101章 マウス・キャプチャー
  2. WisdomSoft 『標準 WindowsAPI

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

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
マウスジェスチャを実装する連載記事一覧
この記事の著者

利都(りと)

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

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/381 2008/08/19 20:52

イベント

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

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

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

メールバックナンバー