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

×

[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

こんな感じで。

PR
Comments
お名前
メールアドレス
パスワード
タイトル
コメント
TRACKBACK
TrackBack URL :
"LRESULT" WROTE ALL ARTICLES.
PRODUCED BY SHINOBI.JP @ SAMURAI FACTORY INC.