Q&A

  • 키 훅킹이 잘안되는데.... ????
아래는 제가만든 훅킹 샘플 프로그램 입니다.



키보드 입력이 발생하면 화면의 caption에 문자를 표시하는 프로그램 입니다.



그런데 어플리케이션의 메인 화면이 active 일 경우에만 키입력을 체크하는것



같습니다. 화면이 active 상태가 아닐경우에도 키입력을 체크할수 있는 방법은



없을까요? 혹시 방법을 알고계신 고수분이 계시면 도움을 부탁드립니다.







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

// 메인프로그램 : Project1.exe

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

unit Unit1;



interface



uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;



const

HookDataFile = 'c:tempHook.dat';



type

TForm1 = class(TForm)

procedure FormActivate(Sender: TObject);

procedure FormClose(Sender: TObject; var Action: TCloseAction);

procedure FormCreate(Sender: TObject);

private

{ Private declarations }

procedure AppMessage(var Msg: TMsg; var Handled: Boolean);

public

{ Public declarations }

end;



var

Form1: TForm1;



WM_SSMenu : integer;

HKeyboardHook : HHOOK;

HForm_Handle : HWND;



function sjHookKeyboard : Boolean; external 'Hook_sam.dll';

function sjUnHookKeyboard : Boolean; external 'Hook_sam.dll';



implementation



{$R *.DFM}



procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);

begin

if Msg.message = WM_SSMenu then begin

caption := caption + '1';

Handled := True;

end;

end;



procedure TForm1.FormCreate(Sender: TObject);

var

F : TFileStream;

begin

Application.OnMessage := AppMessage;

WM_SSMenu := RegisterWindowMessage('Samsung Menu');





HKeyboardHook := 0;

HForm_Handle := Application.handle;



F := TFileStream.Create(HookDataFile,fmCreate);



try

F.Write(HKeyboardHook, sizeof(HKeyboardHook));

F.Write(HForm_Handle, sizeof(HForm_Handle));

finally

F.Free;

end;



// 키훅킹을 시작

sjHookKeyboard;

end;



procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

begin

// 키훅킹 종료

sjUnHookKeyboard;

action := cafree;

end;



end.







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

// 훅킹 dll : hook_sam.dll

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

library hook_sam;



uses

SysUtils,

Classes,

Windows,

Messages,

Dialogs;



const

HookDataFile = 'c:tempHook.dat';



var

HKeyboardHook : HHOOK;

HForm_Handle : HWND;

WM_SSMenu : Integer;



procedure ReadData;

var

F : TFileStream;

begin

F := TFileStream.Create(HookDataFile,fmOpenRead);



try

F.Read(HKeyboardHook, sizeof(HKeyboardHook));

F.Read(HForm_Handle, sizeof(HForm_Handle));

finally

F.Free;

end;

end;



procedure WriteData;

var

F : TFileStream;

begin

F := TFileStream.Create(HookDataFile,fmCreate);



try

F.Write(HKeyboardHook, sizeof(HKeyboardHook));

F.Write(HForm_Handle, sizeof(HForm_Handle));

finally

F.Free;

end;

end;



function sjMyKeyboardHook(Code:integer; wParam:WPARAM; lParam: LPARAM) : LongInt ; stdcall;

begin

if Code >= 0 then begin

PostMessage(HWND_BROADCAST, WM_SSMenu, 0, 0);

end;



Result := CallNextHookEx(HKeyboardHook, Code, wParam, lParam);

end;



function sjHookKeyboard: Boolean;

begin

ReadData;



WM_SSMenu := RegisterWindowMessage('Samsung Menu');



HKeyboardHook := SetWindowsHookEx(WH_KEYBOARD,sjMyKeyboardHook, HInstance, 0);



result := Boolean(HKeyboardHook);



WriteData;

end;



function sjUnHookKeyboard: Boolean;

begin

if HKeyboardHook = 0 then

ReadData;



Result := UnhookWindowsHookEx(HKeyboardHook);

end;



Exports

sjHookKeyboard,

sjUnHookKeyboard;



begin

end.



1  COMMENTS
  • Profile
    임형호 1999.12.18 01:36
    이선주 wrote:

    > 아래는 제가만든 훅킹 샘플 프로그램 입니다.

    >

    > 키보드 입력이 발생하면 화면의 caption에 문자를 표시하는 프로그램 입니다.

    >

    > 그런데 어플리케이션의 메인 화면이 active 일 경우에만 키입력을 체크하는것

    >

    > 같습니다. 화면이 active 상태가 아닐경우에도 키입력을 체크할수 있는 방법은

    >

    > 없을까요? 혹시 방법을 알고계신 고수분이 계시면 도움을 부탁드립니다.

    >

    >

    >

    > //---------------------------------------------------------------

    > // 메인프로그램 : Project1.exe

    > //---------------------------------------------------------------

    > unit Unit1;

    >

    > interface

    >

    > uses

    > Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

    >

    > const

    > HookDataFile = 'c:tempHook.dat';

    >

    > type

    > TForm1 = class(TForm)

    > procedure FormActivate(Sender: TObject);

    > procedure FormClose(Sender: TObject; var Action: TCloseAction);

    > procedure FormCreate(Sender: TObject);

    > private

    > { Private declarations }

    > procedure AppMessage(var Msg: TMsg; var Handled: Boolean);

    > public

    > { Public declarations }

    > end;

    >

    > var

    > Form1: TForm1;

    >

    > WM_SSMenu : integer;

    > HKeyboardHook : HHOOK;

    > HForm_Handle : HWND;

    >

    > function sjHookKeyboard : Boolean; external 'Hook_sam.dll';

    > function sjUnHookKeyboard : Boolean; external 'Hook_sam.dll';

    >

    > implementation

    >

    > {$R *.DFM}

    >

    > procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);

    > begin

    > if Msg.message = WM_SSMenu then begin

    > caption := caption + '1';

    > Handled := True;

    > end;

    > end;

    >

    > procedure TForm1.FormCreate(Sender: TObject);

    > var

    > F : TFileStream;

    > begin

    > Application.OnMessage := AppMessage;

    > WM_SSMenu := RegisterWindowMessage('Samsung Menu');

    >

    >

    > HKeyboardHook := 0;

    > HForm_Handle := Application.handle;

    >

    > F := TFileStream.Create(HookDataFile,fmCreate);

    >

    > try

    > F.Write(HKeyboardHook, sizeof(HKeyboardHook));

    > F.Write(HForm_Handle, sizeof(HForm_Handle));

    > finally

    > F.Free;

    > end;

    >

    > // 키훅킹을 시작

    > sjHookKeyboard;

    > end;

    >

    > procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

    > begin

    > // 키훅킹 종료

    > sjUnHookKeyboard;

    > action := cafree;

    > end;

    >

    > end.

    >

    >

    >

    > //---------------------------------------------------------------

    > // 훅킹 dll : hook_sam.dll

    > //---------------------------------------------------------------

    > library hook_sam;

    >

    > uses

    > SysUtils,

    > Classes,

    > Windows,

    > Messages,

    > Dialogs;

    >

    > const

    > HookDataFile = 'c:tempHook.dat';

    >

    > var

    > HKeyboardHook : HHOOK;

    > HForm_Handle : HWND;

    > WM_SSMenu : Integer;

    >

    > procedure ReadData;

    > var

    > F : TFileStream;

    > begin

    > F := TFileStream.Create(HookDataFile,fmOpenRead);

    >

    > try

    > F.Read(HKeyboardHook, sizeof(HKeyboardHook));

    > F.Read(HForm_Handle, sizeof(HForm_Handle));

    > finally

    > F.Free;

    > end;

    > end;

    >

    > procedure WriteData;

    > var

    > F : TFileStream;

    > begin

    > F := TFileStream.Create(HookDataFile,fmCreate);

    >

    > try

    > F.Write(HKeyboardHook, sizeof(HKeyboardHook));

    > F.Write(HForm_Handle, sizeof(HForm_Handle));

    > finally

    > F.Free;

    > end;

    > end;

    >

    > function sjMyKeyboardHook(Code:integer; wParam:WPARAM; lParam: LPARAM) : LongInt ; stdcall;

    > begin

    > if Code >= 0 then begin

    > PostMessage(HWND_BROADCAST, WM_SSMenu, 0, 0);

    > end;

    >

    > Result := CallNextHookEx(HKeyboardHook, Code, wParam, lParam);

    > end;

    >

    > function sjHookKeyboard: Boolean;

    > begin

    > ReadData;

    >

    > WM_SSMenu := RegisterWindowMessage('Samsung Menu');

    >

    > HKeyboardHook := SetWindowsHookEx(WH_KEYBOARD,sjMyKeyboardHook, HInstance, 0);

    >

    > result := Boolean(HKeyboardHook);

    >

    > WriteData;

    > end;

    >

    > function sjUnHookKeyboard: Boolean;

    > begin

    > if HKeyboardHook = 0 then

    > ReadData;

    >

    > Result := UnhookWindowsHookEx(HKeyboardHook);

    > end;

    >

    > Exports

    > sjHookKeyboard,

    > sjUnHookKeyboard;

    >

    > begin

    > end.

    >

    현재 실행되는 폼이 Active상태가 아닐때 키입력을 받을 수가 없습니다. 전에 저두 이런경우가 있었는데... 그때 전역적 핫키라는것을 사용하시면 되거든요. 그 방법은 저두 확실하게 몰라서 뭐라고 말씀은 못드리겠구요. 전에 전 김영대님 홈페이지에서 그부분에 대한 내용을 참고하여 작성했었거든요. 참고하시면 도움이 될것 같습니다.