[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
キーボードのグローバルフックの続き。
DLL側はVC6で作成したので、今度は呼び出し(アプリ)側をBCBで。
今回は、コンストラクタで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
こんな感じで。