Last Updated 2005/06/15
Programming Tips Visual C++ API  索 引 
フック
2005/06/15

WM_PAINT などのメッセージを送らないようにするには,メッセージフックを使用する.
WH_CALLWNDPROC でフックして,スレッド ID に 0 を指定して全てのメッセージを監視とする.ダミーのウィンドウプロシージャを DLL で用意しておき,メッセージを送信したくないときに SetWindowLong() でウィンドウプロシージャを挿げ替える.
(そしてすぐにもとのプロシージャに戻す)
(この方法は,フックに渡されるウィンドウハンドルと実際にメッセージを受け取るウィンドウが同じ場合に有効である.WH_GETMESSAGE は必ずしもウィンドウハンドルと同じウィンドウにメッセージが送られるわけではない)


SetWindowsHookEx() で第4パラメータの dwThreadId に 0 を設定して,DLL のデータセグメントを共有すれば全てのメッセージをフック可能である.

#pragma data_seg(".GLOBALS")
HHOOK hHook=0
#pragma data_seg()


DLL の DEF ファイル
SECTIONS
    .GLOBALS READ WRITE SHARED

あとはリンクの設定に
 /SECTION:.GLOBALS,RWS
を追加する.





メッセージフックサンプル

/* ユーザー定義メッセージ */
#define WM_USERMESSAGE_CALLWND  (WM_USER + 50)

extern HINSTANCE _hInstance;

/* フックプロシージャで使用する変数は共有メモリにおく */
/* これは Visual C++ の場合                           */
/* リンカのオプションに /SECTION:.share,RWS を追加    */
#pragma data_seg(".share")
HHOOK   _hHookCallWnd   = NULL;
HWND    _hWndCallWnd    = NULL;
#pragma data_seg()

/* フック プロシージャ */
static LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CWPSTRUCT* pCWP;
    if( nCode >= 0 && nCode == HC_ACTION ) {
        pCWP = (CWPSTRUCT*)lParam;
        if( pCWP->message == WM_PAINT ) {
            PostMessage(_hWndCallWnd, WM_USERMESSAGE_CALLWND, wParam, lParam);
        }
        return CallNextHookEx(_hHookCallWnd, nCode, wParam, lParam);
    }
    return CallNextHookEx(_hHookCallWnd, nCode, wParam, lParam);
}

/* フックのセット                               */
/* ここで渡したウィンドウに                     */
/* メッセージ WM_USERMESSAGE_CALLWND が送られる */
BOOL SetCallWnd(HWND hWnd)
{
    /* キーのフック */
    _hHookCallWnd = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)CallWndProc, _hInstance, 0);
    /* ここで hInstance は DLL のインスタンス ハンドル */
    _hWndCallWnd  = hWnd;
    return (_hHookCallWnd != NULL);
}

/* アンフック                   */
/* フックが不必要になったら呼ぶ */
void ResetCallWnd()
{
    if(_hHookCallWnd != NULL ) {
        UnhookWindowsHookEx(_hHookCallWnd);
        _hHookCallWnd = NULL;
    }
}


参照
マウスのフック
前後のTips
フック

DSS ProgrammingTipsCGI Ver2.01