BCB Client

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

キーボードのグローバルフック アプリ側

キーボードのグローバルフックの続き。
今度はアプリ(呼び出し)側をBuilderで。
今回は、コンストラクタでDLLを読み込み、フォームを閉じる前に解放するコード

ややこしいのは、関数ポインタの宣言とか、
GetProcAddressにて関数のアドレスをゲットするとことか。


・ローカルフックと同様に、Buttonコンポーネントの"HookStartBtn", "HookStopBtn"を
 設置し、作成したDLLを同じフォルダに置いてから...

<Unit1.h>
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE 管理のコンポーネント
	TButton *HookStartBtn;
	TButton *HookStopBtn;
	void __fastcall HookStartBtnClick(TObject *Sender);
	void __fastcall HookStopBtnClick(TObject *Sender);
	void __fastcall FormClose(TObject *Sender, TCloseAction &Action);

private: // ユーザー宣言

	// DLLのインスタンスハンドル
	HINSTANCE m_hInst;

	// DLL関数呼び出し用の関数ポインタ宣言
	__declspec(dllexport)void (*HookStart)(void);   // フック開始呼び出し用
	__declspec(dllexport)void (*HookStop)(void);    // フック停止呼び出し用

public:  // ユーザー宣言
	__fastcall TForm1(TComponent* Owner);

};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

<Unit1.cpp>
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
// コンストラクタ
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
	// DLLの読み込み
	m_hInst = LoadLibrary("KeybdHook.dll");
	// エラー処理
	if ( m_hInst == NULL ){
		ShowMessage("KeybdHook.dll:読込失敗しました");
		return;
	}

	// DLL関数のアドレスを取得
	HookStart = (void (*)(void))GetProcAddress(m_hInst, "HookStart");
	HookStop  = (void (*)(void))GetProcAddress(m_hInst, "HookStop" );
	// エラー処理
	if ( HookStart == NULL || HookStop == NULL ){
		ShowMessage("関数のアドレス取得に失敗しました");
		FreeLibrary(m_hInst);   // 読み込んだDLLを解放
		m_hInst = NULL;
		return;
	}
}
//---------------------------------------------------------------------------
// APP側フック開始
void __fastcall TForm1::HookStartBtnClick(TObject *Sender)
{
	HookStart();
}
//---------------------------------------------------------------------------
// APP側フック停止
void __fastcall TForm1::HookStopBtnClick(TObject *Sender)
{
	HookStop();
}
//---------------------------------------------------------------------------
// フォームを閉じた
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
	// DLLの解放
	if ( m_hInst != NULL ){
		FreeLibrary(m_hInst);   // 読み込んだDLLを解放
		m_hInst = NULL;
	}
}
//---------------------------------------------------------------------------

と、まぁどんなもんでしょうか。
フック処理は全てDLLで実施している為、アプリ側では呼び出しているだけ。

ここまで敢えて"HookStopBtn"でフック解除を行ってきたが
普通はデストラクタやClose()イベントで解除するもんだと思う。

また、実行してみると分かるが、メッセージボックスが2回表示されますな。
これは、KeyDownとKeyUpで2回呼ばれている為、lParamからどちらなのか判断します。

if ( (lParam & 0x80000000) == 0 )       // KeyUp
else if ( (lParam & 0x80000000) == 1 )  // KeyDown


こんな感じで。

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

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

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