忍者ブログ
Comments
[03/30 のん]
TrackBack
Counter
blogRank
忍者ブログ [PR]
http://lresult.blog.shinobi.jp/
Borland C++ Builderを用いたWindowsプログラミングメモブログ

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

マウスのグローバルフックを試してみる
今回もDLLはVC6.0で作成
呼び出し側のアプリは全く同じものなので省略で。
キーボードのフックとほとんど同じですな。

・[新規作成] → [プロジェクト]タブ → Win32 Dynamic-Link Library を選んで
 プロジェクト名 "MouseHook"で作成してから...

<DLL側 MouseHook.cpp>
// MouseHook.cpp : DLL アプリケーション用のエントリ ポイントを定義します。
//

#include "stdafx.h"

#define DLLEXPORT extern "C" __declspec(dllexport)

// 宣言
// フック開始用

DLLEXPORT void HookStart(void);
// フック停止用
DLLEXPORT void HookStop(void);
// フック処理用 DLLにする事によってグローバルフックが出来るようになります
DLLEXPORT LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam);

//---------------------------------------------------------------------------
// 必ず初期化しないと動いてくれない
#pragma data_seg(".shared")
HHOOK g_hHook = NULL;  
// フックハンドル
#pragma data_seg()
#pragma comment(linker, "/section:.shared,rws")

HINSTANCE g_hInst;

//---------------------------------------------------------------------------
// DLLエントリポイント
BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    if ( ul_reason_for_call == DLL_PROCESS_ATTACH ){
        g_hInst = (HINSTANCE)hModule;   // DLLモジュールのハンドル取得
    }
    return TRUE;
}
//---------------------------------------------------------------------------
// フック開始

DLLEXPORT void HookStart()
{
    g_hHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseProc, g_hInst, 0);

    if ( g_hHook == NULL ){
        MessageBox(NULL, "フック開始は失敗しました", "HookStart", MB_OK);
        return;
    }
    MessageBox(NULL, "フック開始は成功しました", "HookStart", MB_OK);
}
//---------------------------------------------------------------------------
// フック処理

DLLEXPORT LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam)
{
    char sMsg[100];     // メッセージ表示用

    // この構造体から位置,ハンドル,ヒットテストコード,追加情報を取得出来ます
    MOUSEHOOKSTRUCT *mmsg; 

    // lParamをMOUSEHOOKSTRUCT型でキャストし
    // 構造体のメンバを指定出来るようにします

    mmsg = (MOUSEHOOKSTRUCT *)lParam;

    if ( code < 0 ){
        return CallNextHookEx(g_hHook, code, wParam, lParam);
    }

    // 今回は右クリックと位置を確認します
    if ( wParam == WM_RBUTTONDOWN ){
        wsprintf(sMsg,
                 "位置 X : %d, Y : %d で\r\n右クリックされました!"
                 , mmsg->pt.x, mmsg->pt.y);

        MessageBox(mmsg->hwnd, sMsg, "MouseProc", MB_OK);
    }

    // 最大化ボタン上かどうかも確認してみます
    // マウスカーソルを最大化ボタン上に持っていくとメッセージが表示されます
    if ( mmsg->wHitTestCode == HTMAXBUTTON ){
        MessageBox(mmsg->hwnd, "最大化ボタン!", "MouseProc", MB_OK);
    }

    // 最後は次のフックへ渡します
    return CallNextHookEx(g_hHook, code, wParam, lParam);
}
//---------------------------------------------------------------------------
// フック停止
DLLEXPORT void HookStop(void)
{
    BOOL bResult;

    if ( g_hHook == NULL ) return;

    bResult = UnhookWindowsHookEx(g_hHook);
    if ( bResult == 0 ){
        MessageBox(NULL, "フック解除は失敗しました", "HookStop", MB_OK);
        return;
    }

    MessageBox(NULL, "フック解除は成功しました", "HookStop", MB_OK);
}
//---------------------------------------------------------------------------

と、まぁどうすかね。
SetWindowsHookExの第1引数をWH_MOUSEに変更してある点、
MOUSEHOOKSTRUCT型による、マウス座標やヒットテストコードの取得
この辺りが、キーボードフックと異なる点です。

ここでひとつ。
MessageBoxで確認をしていますが、コードの書き方がマズイと
大量のMessageBoxが出現し、どうにもならなくなってしまう場合がありますので
その辺、上手くやるなりなんなりで注意してください。

・参考
typedef struct tagMOUSEHOOKSTRUCT { 
    POINT pt;              // pt.x  pt.y  マウスのスクリーン座標
    HWND  hwnd;            // メッセージを受け取ったウィンドウのハンドル
    UINT  wHitTestCode;    // ヒットテストコード
    DWORD dwExtraInfo;     // 追加情報
} MOUSEHOOKSTRUCT;

ヒットテストコードにはマウスカーソルがどの位置にあるのか等の
情報が入ります。(タイトルバー、クライアント領域、閉じるボタン上など)
MSDN「WM_NCHITTES」にて説明があります。

PR
Comments
お名前
メールアドレス
パスワード
タイトル
コメント
TRACKBACK
TrackBack URL :
"LRESULT" WROTE ALL ARTICLES.
PRODUCED BY SHINOBI.JP @ SAMURAI FACTORY INC.