第一步,建一DLL,DELPHI中NEW-》DLL SAVE AS GETKEY library getKey; uses uses SysUtils, Windows, HookMain in 'hookmain.pas'; exports OpenGetKeyHook, CloseGetKeyHook, GetPublicP; begin NextHook := 0; procSaveExit := ExitProc; DLLproc := @DLLMain; ExitProc := @HookExit; DLLMain(DLL_PROCESS_ATTACH); end. 第二步,建一UNIT ,HOOK MAIN。关键在于CreateFileMapping 和 消息 WM_NCM ouseMove, WM_MOUSEMOVE: unit HookMain; interface uses Windows, Messages, Dialogs, SysUtils; //type DataBuf = Array [1..2] of DWORD; type mydata=record data1:array [1..2] of DWORD; data2:TMOUSEHOOKSTRUCT; end; var hObject : THandle; pMem : Pointer; NextHook: HHook; procSaveExit: Pointer; function HookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export; function OpenGetKeyHook(sender : HWND;MessageID : WORD) : BOOL; export ; function CloseGetKeyHook: BOOL; export; function GetPublicP : Pointer;stdcall; export; Procedure DLLMain(dwReason:DWord); far; procedure HookExit; far; implementation Procedure UnMapMem; begin if Assigned(pMem) then begin UnMapViewOfFile(pMem); pMem := Nil end; end; Procedure MapMem; begin hObject := CreateFileMapping($FFFFFFFF,Nil,Page_ReadWrite,0,$FFFF,pCha r('_IOBuffer')); if hObject = 0 then Raise Exception.Create('创建公用数据的Buffer不成功 !'); pMem := MapViewOfFile(hObject,FILE_MAP_WRITE,0,0,SizeOf(mydata)); // 1 or SizeOf(DataBuf) ???? // 创建SizeOf(DataBuf)的数据区 if not Assigned(pMem) then begin begin UnMapMem; Raise Exception.Create('创建公用数据的映射关系不成功!'); end; end; Procedure DLLMain(dwReason:DWord); far; begin Case dwReason of DLL_PROCESS_ATTACH : begin pMem := nil; hObject := 0; MapMem; //以下的公有数据,如tHWND,tMessageID将直接使用本Buf. end; DLL_PROCESS_DETACH : UnMapMem; DLL_THREAD_ATTACH, DLL_THREAD_DETACH :; //缺省 end; end; procedure HookExit; far; begin CloseGetKeyHook; ExitProc := procSaveExit; end; function GetPublicP : Pointer;export; begin //这里引出了公用数据区的指针,你可以在你的应用程序中自由操作它。 但建议去掉此接口。 Result := pMem; end; function HookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export; begin Result := 0; If iCode < 0 Then Result := CallNextHookEx(NextHook, iCode, wParam, lParam); // This is probably closer to what you would want to do... case wparam of WM_LBUTTONDOWN: begin end; end; WM_LBUTTONUP: begin end; WM_LBUTTONDBLCLK: begin end; WM_RBUTTONDOWN: begin messagebeep(1); end; WM_RBUTTONUP: begin end; WM_RBUTTONDBLCLK: begin end; WM_MBUTTONDOWN: begin end; WM_MBUTTONUP: begin end; end; WM_MBUTTONDBLCLK: begin end; WM_NCMouseMove, WM_MOUSEMOVE: begin mydata(pmem^).data2:=pMOUSEHOOKSTRUCT(lparam)^; // messagebeep(1); //SendMessage(DataBuf(pMem^)[1],DataBuf(pMem^)[2],wParam,lParam ); SendMessage(mydata(pMem^).data1[1],mydata(pMem^).data1[2],wParam,integ er(@(mydata(pmem^).data2)) ); end; end; //发送消息 end; function OpenGetKeyHook(sender : HWND;MessageID : WORD) : BOOL; export ; begin Result := False; if NextHook <> 0 then Exit; //已经安装了本钩子 // DataBuf(pMem^)[1] := Sender; //填数据区 // DataBuf(pMem^)[2] := MessageID; //填数据区 mydata(pmem^).data1[1]:=sender; mydata(pmem^).data1[2]:=messageid; NextHook := SetWindowsHookEx(WH_mouse, HookHandler, HInstance, 0); Result := NextHook <> 0; end; function CloseGetKeyHook: BOOL; export; begin if NextHook <> 0 then begin UnhookWindowshookEx(NextHook); //把钩子链链接到下一个钩子处理上. NextHook := 0; end; Result := NextHook = 0; end; end. 第三步,测试DLL,建一PROJECT。关键在于override WndProc unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialo gs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) uncapture: TButton; capture: TButton; Exit: TButton; Panel1: TPanel; show: TLabel; Label1: TLabel; counter: TLabel; procedure ExitClick(Sender: TObject); procedure uncaptureClick(Sender: TObject); procedure captureClick(Sender: TObject); private { Private declarations } public { Public declarations } procedure WndProc(var Message: TMessage); override; end; var Form1: TForm1; var num : integer; const MessageID = WM_User + 100; implementation {$R *.DFM} function OpenGetKeyHook(sender : HWND;MessageID : WORD) : BOOL; extern al 'GetKey.DLL'; function CloseGetKeyHook: BOOL; external 'GetKey.DLL'; procedure TForm1.ExitClick(Sender: TObject); begin close; end; end; procedure TForm1.uncaptureClick(Sender: TObject); begin if CloseGetKeyHook then //ShowMessage('结束记录...'); show.caption:='结束记录...'; end; procedure TForm1.captureClick(Sender: TObject); begin // if OpenGetKeyHook(self.Handle,MessageID) then ShowMessage('开始记录 ...'); if OpenGetKeyHook(Form1.Handle,MessageID) then //ShowMessage('开始记录...'); show.caption:='开始记录...'; num := 0; end; procedure TForm1.WndProc(var Message: TMessage); var x,y:integer; begin if Message.Msg = MessageID then begin // Panel1.Caption := IntToStr(Num); x:=PMouseHookStruct( message.lparam)^.pt.x ; y:=PMouseHookStruct( message.lparam)^.pt.y ; panel1.caption:='x='+inttostr(x)+' y='+inttostr(y); inc(Num); counter.Caption := IntToStr(Num); end else Inherited; end; end.
the following code shuts down the application when anexception is not caught and handled. 当异常没有被捕抓到或是被关闭下面的代码会关闭该应用程序procedure TForm1.FormCreate(Sender: TObject); begin Application.OnException := AppException;end;procedure TForm1.AppException(Sender: TObject; E: Exception);begin Application.ShowException(E); Application.Terminate; end;
先找到窗口的HWND,然后用: int GetClassName( HWND hWnd, // handle of window LPTSTR lpClassName, // address of buffer for class name int nMaxCount // size of buffer, in characters );
:
http://expert.csdn.net/Expert/topic/1201/1201326.xml?temp=.7150385
uses
SysUtils,
Windows,
HookMain in 'hookmain.pas'; exports
OpenGetKeyHook,
CloseGetKeyHook,
GetPublicP; begin
NextHook := 0;
procSaveExit := ExitProc;
DLLproc := @DLLMain;
ExitProc := @HookExit;
DLLMain(DLL_PROCESS_ATTACH);
end. 第二步,建一UNIT ,HOOK MAIN。关键在于CreateFileMapping 和 消息 WM_NCM
ouseMove, WM_MOUSEMOVE: unit HookMain;
interface
uses Windows, Messages, Dialogs, SysUtils; //type DataBuf = Array [1..2] of DWORD;
type mydata=record
data1:array [1..2] of DWORD;
data2:TMOUSEHOOKSTRUCT;
end;
var hObject : THandle;
pMem : Pointer;
NextHook: HHook;
procSaveExit: Pointer; function HookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM):
LRESULT; stdcall; export;
function OpenGetKeyHook(sender : HWND;MessageID : WORD) : BOOL; export
;
function CloseGetKeyHook: BOOL; export;
function GetPublicP : Pointer;stdcall; export;
Procedure DLLMain(dwReason:DWord); far;
procedure HookExit; far;
implementation Procedure UnMapMem;
begin
if Assigned(pMem) then
begin
UnMapViewOfFile(pMem);
pMem := Nil
end;
end; Procedure MapMem;
begin
hObject := CreateFileMapping($FFFFFFFF,Nil,Page_ReadWrite,0,$FFFF,pCha
r('_IOBuffer'));
if hObject = 0 then Raise Exception.Create('创建公用数据的Buffer不成功
!');
pMem := MapViewOfFile(hObject,FILE_MAP_WRITE,0,0,SizeOf(mydata));
// 1 or SizeOf(DataBuf) ????
// 创建SizeOf(DataBuf)的数据区
if not Assigned(pMem) then
begin
begin
UnMapMem;
Raise Exception.Create('创建公用数据的映射关系不成功!');
end;
end;
Procedure DLLMain(dwReason:DWord); far;
begin
Case dwReason of
DLL_PROCESS_ATTACH :
begin
pMem := nil;
hObject := 0;
MapMem; //以下的公有数据,如tHWND,tMessageID将直接使用本Buf.
end;
DLL_PROCESS_DETACH : UnMapMem;
DLL_THREAD_ATTACH,
DLL_THREAD_DETACH :; //缺省
end;
end; procedure HookExit; far;
begin
CloseGetKeyHook;
ExitProc := procSaveExit;
end; function GetPublicP : Pointer;export;
begin //这里引出了公用数据区的指针,你可以在你的应用程序中自由操作它。
但建议去掉此接口。
Result := pMem;
end; function HookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM):
LRESULT; stdcall; export;
begin
Result := 0;
If iCode < 0
Then Result := CallNextHookEx(NextHook, iCode, wParam, lParam);
// This is probably closer to what you would want to do...
case wparam of
WM_LBUTTONDOWN:
begin
end;
end;
WM_LBUTTONUP:
begin
end;
WM_LBUTTONDBLCLK:
begin
end;
WM_RBUTTONDOWN:
begin
messagebeep(1);
end;
WM_RBUTTONUP:
begin
end;
WM_RBUTTONDBLCLK:
begin
end;
WM_MBUTTONDOWN:
begin
end;
WM_MBUTTONUP:
begin
end;
end;
WM_MBUTTONDBLCLK:
begin
end;
WM_NCMouseMove, WM_MOUSEMOVE:
begin
mydata(pmem^).data2:=pMOUSEHOOKSTRUCT(lparam)^;
// messagebeep(1);
//SendMessage(DataBuf(pMem^)[1],DataBuf(pMem^)[2],wParam,lParam );
SendMessage(mydata(pMem^).data1[1],mydata(pMem^).data1[2],wParam,integ
er(@(mydata(pmem^).data2)) );
end;
end; //发送消息
end; function OpenGetKeyHook(sender : HWND;MessageID : WORD) : BOOL; export
;
begin
Result := False;
if NextHook <> 0 then Exit; //已经安装了本钩子
// DataBuf(pMem^)[1] := Sender; //填数据区
// DataBuf(pMem^)[2] := MessageID; //填数据区
mydata(pmem^).data1[1]:=sender;
mydata(pmem^).data1[2]:=messageid; NextHook := SetWindowsHookEx(WH_mouse, HookHandler, HInstance, 0);
Result := NextHook <> 0;
end; function CloseGetKeyHook: BOOL; export;
begin
if NextHook <> 0 then
begin
UnhookWindowshookEx(NextHook); //把钩子链链接到下一个钩子处理上.
NextHook := 0;
end;
Result := NextHook = 0;
end; end. 第三步,测试DLL,建一PROJECT。关键在于override WndProc
unit Unit1; interface uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialo
gs,
StdCtrls, ExtCtrls; type
TForm1 = class(TForm)
uncapture: TButton;
capture: TButton;
Exit: TButton;
Panel1: TPanel;
show: TLabel; Label1: TLabel;
counter: TLabel;
procedure ExitClick(Sender: TObject);
procedure uncaptureClick(Sender: TObject);
procedure captureClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure WndProc(var Message: TMessage); override;
end; var
Form1: TForm1;
var num : integer;
const MessageID = WM_User + 100;
implementation {$R *.DFM}
function OpenGetKeyHook(sender : HWND;MessageID : WORD) : BOOL; extern
al 'GetKey.DLL';
function CloseGetKeyHook: BOOL; external 'GetKey.DLL'; procedure TForm1.ExitClick(Sender: TObject);
begin
close;
end;
end; procedure TForm1.uncaptureClick(Sender: TObject);
begin
if CloseGetKeyHook then //ShowMessage('结束记录...');
show.caption:='结束记录...';
end; procedure TForm1.captureClick(Sender: TObject);
begin
// if OpenGetKeyHook(self.Handle,MessageID) then ShowMessage('开始记录
...'); if OpenGetKeyHook(Form1.Handle,MessageID) then
//ShowMessage('开始记录...');
show.caption:='开始记录...';
num := 0;
end; procedure TForm1.WndProc(var Message: TMessage);
var x,y:integer;
begin
if Message.Msg = MessageID then
begin
// Panel1.Caption := IntToStr(Num);
x:=PMouseHookStruct( message.lparam)^.pt.x ;
y:=PMouseHookStruct( message.lparam)^.pt.y ; panel1.caption:='x='+inttostr(x)+' y='+inttostr(y);
inc(Num);
counter.Caption := IntToStr(Num);
end
else Inherited;
end; end.
当异常没有被捕抓到或是被关闭下面的代码会关闭该应用程序procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnException := AppException;end;procedure TForm1.AppException(Sender: TObject; E: Exception);begin
Application.ShowException(E);
Application.Terminate;
end;
你有简单一点的不用dll做的方法捕获窗体类名吗?我只想知道这个‘#32770’是怎么来的?谢谢你了,也谢谢斑竹
我在做书上的例子截取窗口消息中,用自定义消息处理过程appwindowhook可以扑捉到message id,wparam,lparam.但是我不知道该怎么用这些消息,能讲讲吗
int GetClassName(
HWND hWnd, // handle of window
LPTSTR lpClassName, // address of buffer for class name
int nMaxCount // size of buffer, in characters
);
获得指定窗口所属的类的类名
GetClassName(Handle,ClassName,255)
var
str1:array [0..1024] of char;
hwnd1,parentHwnd,pphwnd,ppphwnd:HWND;
p1:Tpoint;
begin
Getcursorpos(p1);//得到当前鼠标位置
hwnd1:=windowFromPoint(p1); //得到当前鼠标位置所在的控件(或窗体)的句柄 hwndEdit1.text:=IntToStr(hwnd1);
sendMessage(hwnd1,WM_GETTEXT,1024,longint(@str1));//获取句柄hwnd1的文本
edit1.Text:=string(str1); //显示鼠标位置的句柄 getClassName(hwnd1,@str1,1024);
Edit2.Text :=str1; //显示鼠标位置的类名
end;