读书人

钩子的有关问题

发布时间: 2012-06-14 16:00:31 作者: rapoo

钩子的问题
以下代码是一个网友写的钩子,可以钩系统菜单的句柄,但不知如何便用。各位大大,如何操作呢,是不是要作一个DLL,
但里面没有什么函数可以调用呢,帮帮看看

unit MenuSubClass;

interface

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

const
WM_SPECIAL=$01E2; //SPECIAL menu
MENU_CLASS = '#32768';
EDIT_CLASS='TEdit';

type
TCallbackThunk = packed record
POPEDX: Byte;
MOVEAX: Byte;
SelfPtr: Pointer;
PUSHEAX: Byte;
PUSHEDX: Byte;
JMP: Byte;
JmpOffset: Integer;
end;


TMenuHookCallback =
procedure(code: Integer; wparam: WPARAM; lparam: LPARAM) of object;

TOSType=( Win32s,WinNT3,Win95,Win98,WinME,WinNT4,Win2000,WinXP,Win2003);
TMenuSubClass = class(TComponent)
private
{ Private declarations }
log:tstringlist;
FHook : HHOOK;
FThunk,FThunk1 : TCallbackThunk;
bSysMenu : Boolean;
NewProc : Pointer;
OldProc : Longint;
HookProc : Pointer;


function MenuCallBack(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT;stdcall;

protected
{ Protected declarations }

public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;


published
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('foxVCL', [TMenuSubClass]);
end;



{ TMenuSubClass }


//hook CallBack Procedure
function TMenuSubClass.MenuCallBack(code: Integer; wparam: WPARAM;
lparam: LPARAM): LRESULT;
var
cwps: TCWPStruct;
lRet: Longint;
szClass: array[0..8] of char;
MenuHwnd:Hwnd;
begin
if (Code = HC_ACTION) then
begin
CopyMemory(@cwps, Pointer(lParam), SizeOf(CWPSTRUCT));
case cwps.message of
WM_CONTEXTMENU:
begin
//判断是否Tedit
GetClassName(cwps.wParam, szClass, Length(szClass)-1);
if (lstrcmpi(szClass,EDIT_CLASS) = 0) then
begin
//Tedit 的句柄
log.add('TEdit Handle: '+inttostr(cwps.wParam));
end;
end;
WM_INITMENUPOPUP:
begin
log.add('WM_INITMENUPOPUP ');
//判断是否系统菜单
if (getSystemmenu(cwps.hwnd,false)=cwps.wParam) or (hiword(cwps.lParam)<>0) then
bSysMenu:=true
else
bSysMenu:=false;
end;
//特殊的菜单??如果没有这个消息好像在9x有些菜单钩不住
WM_SPECIAL: //$01E2 SPECIAL Menu???
begin
log.add('WM_SPECIAL '+inttostr(CWPs.hwnd));
GetClassName(cwps.hwnd, szClass, Length(szClass)-1);
// Window name for menu is #32768
if (lstrcmpi(szClass, MENU_CLASS) = 0) and (not bSysMenu) then
begin
log.add('WM_SPECIAL '+inttostr(CWPs.hwnd));
//cwps.hwnd就是菜单的句柄
////
//可以对菜单进行子类化
// end;
end;
end;
WM_CREATE:
begin

GetClassName(cwps.hwnd, szClass, Length(szClass)-1);
// Window name for menu is #32768
if (lstrcmpi(szClass, MENU_CLASS) = 0) and (not bSysMenu) then
begin
log.add('WM_CREATE '+inttostr(CWPs.hwnd));


//cwps.hwnd就是菜单的句柄
////
//可以对菜单进行子类化
end;
//end;
end;
WM_UNINITMENUPOPUP:bSysMenu:=false;
end;
Result:=0;
end;
// Call the next hook in the chain
Result := CallNextHookEx(WH_CALLWNDPROC, Code, wParam, lParam);

end;



constructor TMenuSubClass.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
log:=tstringlist.Create;
if not (csDesigning in ComponentState) then
begin
FThunk.POPEDX:= $5A;
FThunk.MOVEAX:= $B8;
FThunk.SelfPtr:= Self;
FThunk.PUSHEAX:= $50;
FThunk.PUSHEDX:= $52;
FThunk.JMP:= $E9;
FThunk.JmpOffset:= Integer(@TMenuSubClass.MenuCallBack)-Integer(@FThunk.JMP)-5;
FHook:= SetWindowsHookEx(WH_CALLWNDPROC, TFNHookProc(@FThunk), 0, MainThreadID);
end;
end;

destructor TMenuSubClass.Destroy;
begin
log.SaveToFile('F:\log.txt');
log.Free;
if not (csDesigning in ComponentState) then
UnhookWindowsHookEx(FHook);
inherited Destroy;
end;
end.

[解决办法]
直接创建 TMenuSubClass 实例

读书人网 >.NET

热点推荐