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

×

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

今度は、キーボードのグローバルフックを試してみる
グローバルフックするにはDLLにてフックプロシージャを実行する必要がある
ただ・・問題が1つ。。

プロセス間で使えるグローバル変数は共有セグメントってのに確保せねばならんらしい。
ただ、BCBで実現しようとするとアセンブラやメモリマップト・ファイル(メモリマップド・ファイル?)等が
出てきて、いろいろ面倒らしい上に調べてもサッパリHITせず..。

というわけで、仕方なくVisual C++ 6.0を使用してDLLを作成。
#pragma data_seg("hoge") ~ #pragma data_seg()の間で
利用するグローバル変数を宣言し、初期化しなければならない。

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

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

#include "stdafx.h"

#define DLLEXPORT extern "C" __declspec(dllexport)

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

DLLEXPORT void HookStart(void);
// フック停止用
DLLEXPORT void HookStop(void);
// フック処理用 DLLにする事によってグローバルフックが出来るようになります
DLLEXPORT LRESULT CALLBACK KeyboardProc(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_KEYBOARD, (HOOKPROC)KeyboardProc, g_hInst, 0);

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

DLLEXPORT LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
    if ( code < 0 ){
        return CallNextHookEx(g_hHook, code, wParam, lParam);
    }

    // 今回も試しにキーボードの[0]と[F2]の押下を確認してみます
    if ( wParam == 0x30 ){
        MessageBox(NULL, "0押した!", "KeyboardProc", MB_OK);
    }
    else if ( wParam == VK_F2 ){
        MessageBox(NULL, "F2押した!", "KeyboardProc", 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);
}
//---------------------------------------------------------------------------


と、まぁこんな感じで。
DLLという事と、最初の共有セグメントでグローバル変数を宣言すれば
フックの処理の部分はローカルフックとそれほど違いはなさげ。

また、BCBでの実装方法をご存知の方がいらっしゃれば教えてください。お願いします、なにとぞ。

PR
Comments
BCBでの実装
2007/03/30(Fri)14:35:06
BCBで実装してみました。
ポイントはg_hHookを共有セグメントに置かなくてもよいということと、HookStart、HookStop関数に__stdcallを付けることです。

以下BCBでのソース

//---------------------------------------------------------------------------

#include <windows.h>


#define DLLEXPORT extern "C" __declspec(dllexport)

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

//---------------------------------------------------------------------------
// 必ず初期化しないと動いてくれない
HHOOK g_hHook = NULL; // フックハンドル

HINSTANCE g_hInst;
//---------------------------------------------------------------------------
// KeybdHook.cpp : DLL アプリケーション用のエントリ ポイントを定義します。
#pragma argsused
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
if ( fwdreason == DLL_PROCESS_ATTACH ){
g_hInst = hinstDLL; // DLLモジュールのハンドル取得
}
return TRUE;
}
//---------------------------------------------------------------------------
// フック開始
DLLEXPORT void __stdcall HookStart()
{
g_hHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, g_hInst, 0);

if ( g_hHook == NULL ){
MessageBox(NULL, "フック開始は失敗しました", "HookStart", MB_OK);
return;
}
MessageBox(NULL, "フック開始は成功しました", "HookStart", MB_OK);
}
//---------------------------------------------------------------------------
// フック処理
DLLEXPORT LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
if ( code < 0 ){
return CallNextHookEx(g_hHook, code, wParam, lParam);
}

// 今回も試しにキーボードの[0]と[F2]の押下を確認してみます
if ( wParam == 0x30 ){
MessageBox(NULL, "0押した!", "KeyboardProc", MB_OK);
}
else if ( wParam == VK_F2 ){
MessageBox(NULL, "F2押した!", "KeyboardProc", MB_OK);
}

return CallNextHookEx(g_hHook, code, wParam, lParam);
}
//---------------------------------------------------------------------------
// フック停止
DLLEXPORT void __stdcall 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);
}
//---------------------------------------------------------------------------
Posted by のん Edit RES
お名前
メールアドレス
パスワード
タイトル
コメント
TRACKBACK
TrackBack URL :
"LRESULT" WROTE ALL ARTICLES.
PRODUCED BY SHINOBI.JP @ SAMURAI FACTORY INC.