BCB Client

- C++ Builderを用いたWindowsプログラミングメモ -

キーボードのグローバルフック DLL側

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

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

※追記1:共有メモリ(メモリマップドファイル)のTipsを追加しました。
※追記2:C++ Builder版のDLL側を改めて作成しました。詳しくはこちらで。

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

※追記:CallNextHookExの第1引数はNULLでも問題ないです


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


<DLL側 KeybdHook_dll.cpp>
//---------------------------------------------------------------------------
#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という事と、最初の共有セグメントでグローバル変数を宣言すれば
フックの処理の部分はローカルフックとそれほど違いはなさげ。

次はアプリ(DLLを呼び出す)側を作成していきます。

[ トップ | 一覧 | 前へ | 次へ ]

  • トップ
  • 一覧
  • リンク
  • 掲示板

Copyright © BCB Client. All Rights Reserved. Template by ネットマニア