又是钩子的问题!100分哦 (100分)

L

lfpsoft

Unregistered / Unconfirmed
GUEST, unregistred user!
//想做个钩子,每当系统打开应用程序或者资源管理器等时,都在它的窗体的系统菜单上
//加入我的菜单,如下代码实现了,但是我不知道如何实现响应事件,请高手指教!

library HookCreate;

{*************************************************************}
{* *}
{* HookCreate Library,Copyright lfpsoft 2002 *}
{* All rights reserverd. *}
{* Bug Report : lfpsoft@163.net *}
{* WEB : http://www.lkgarden.com/lfpsoft *}
{* *}
{* 效果不是很好,因为到现在我还没有想出如何响应菜单事件 *}
{*************************************************************}

uses
SysUtils,
Classes,
HookCreateProc in 'HooKCreateProc.pas';

{$R *.RES}

exports
EnableMenuHook,
DisableMenuHook,
MenuHookExit,
SetMenuHandle;

begin
IntoShare;
end.

//-----------------------------------------------------------------------------
unit HooKCreateProc;

{*************************************************************}
{* *}
{* HookCreate Library,Copyright lfpsoft 2002 *}
{* All rights reserverd. *}
{* Bug Report : lfpsoft@163.net *}
{* WEB : http://www.lkgarden.com/lfpsoft *}
{* *}
{* 效果不是很好,因为到现在我还没有想出如何响应菜单事件 *}
{*************************************************************}

interface

uses
Windows, Messages, SysUtils,Dialogs;
var
hNextHookProc: HHook;
procSaveExit: Pointer;

function MenuHookHandler(iCode: Integer;
wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall; export;
function EnableMenuHook: BOOL; export;
function DisableMenuHook: BOOL; export;
procedure MenuHookExit; far;
procedure IntoShare; stdcall;export;
procedure SetMenuHandle( MenuHwnd: HWND );stdcall; export;
implementation

type
TGoData = record //将设置菜单的HWND值共享到内存中的数据结构
bMenuHwnd: HWND;
end;
PGoData = ^TGoData;


var
GoData : PGoData;
MemFile : THandle;


//钩子程序

procedure SetMenuHandle( MenuHwnd: HWND );stdcall; export; //
begin
GoData^.bMenuHwnd := MenuHwnd;
end;

function MenuHookHandler(iCode: Integer;
wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall; export;
var
hwndmenu : HWND;
begin
Result := 0;
If iCode < 0 Then
begin
Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);
Exit;
end;

if (PCWPStruct(lParam).message = WM_CREATE) then
begin
if IsWindowEnabled(PCWPStruct(lParam)^.hwnd) then
begin
hwndmenu :=PCWPStruct(lParam)^.hwnd;
if isWindow(hwndmenu) then begin
hwndmenu := GetSystemMenu(hwndmenu,FALSE);
if isMenu(hwndmenu) then
begin
AppendMenu(hwndmenu, MF_SEPARATOR, 0, '');
AppendMenu(hwndmenu, MF_STRING or MF_POPUP,GoData^.bMenuHwnd , '聪聪的菜单(&A)...');
MessageBeep(0);
end;
end;
exit;
end;
end;

Result := CallNextHookEx( hNextHookProc, iCode, wParam, lParam);
end;

//挂钩子
function EnableMenuHook: BOOL; export;
begin
Result := False;
if hNextHookProc <> 0 then Exit;
hNextHookProc := SetWindowsHookEx(WH_CALLWNDPROC,
MenuHookHandler,
HInstance,
0);
if hNextHookProc<>0 then
MessageBeep(0);
Result := hNextHookProc <> 0;
end;

//取消钩子
function DisableMenuHook: BOOL; export;
begin
if hNextHookProc <> 0 then
begin
UnhookWindowsHookEx(hNextHookProc);
hNextHookProc := 0;
end;
Result := hNextHookProc = 0;
end;

//退出钩子
procedure MenuHookExit;
begin
if hNextHookProc <> 0 then DisableMenuHook;
ExitProc := procSaveExit;
end;

//将要设置菜单的HWND值共享到内存中去
procedure IntoShare; stdcall;export;
begin

MemFile := OpenFileMapping( FILE_MAP_WRITE, False, 'CCSOFT' );
if MemFile = 0 then
MemFile:=CreateFileMapping( $FFFFFFFF, nil,
PAGE_READWRITE, 0, SizeOf( TGoData ), 'CCSOFT');
GoData := MapViewOfFile( MemFile, FILE_MAP_WRITE, 0, 0, 0 );
if MemFile = 0 then
FillChar( GoData^, SizeOf( TGoData ),0);
end;


end.
 
勾上之后用SetWindowLong替换目标窗口的消息循环
然后在消息循环中响应你的菜单命令。
 
可以写个代码出来吗?我试过了都不行。
 
严重关注
 
好早已前写的。
为的是让delphi的帮助文件在win9x下也能支持鼠标滚轮。
写的有些乱,凑货着看吧。

btw,这各程序每次只subclass一个窗口。同时subclass多哥窗口的程序我找不到了,
你自己写吧。

//Created BY tt.t.
// E-Mail:dbin@sohu.com

library sample;

uses
SysUtils,
Classes,
Windows,
Messages,
StrUtils;

type
//定义内存文件映射对象
PHookRec = ^THookRec;
THookRec = record
WndType:integer;//保存调用DLL的程序的Handle
HookedProc:pointer;//保存指向原窗口过程的指针
HookedWnd:HWND;//保存已被替换窗口过程的窗口的句柄
HookID: HHOOK;//保存SetWindowsHookEx的返回值
HookedCount:integer;//已被替换窗口过程的窗口数
Ending:boolean;//正在解除hook的标志,防止在解除hook时,hook处理函数继续运行
end;
//以下都对rHookRec进行操作
const
rHookRec: PHookRec = nil;

var
Exit_Message:Cardinal;

{$R *.RES}
//新的窗口消息处理过程
function WndProc(handle:hwnd;msg,wparam,lparam:longint):longint;stdcall;
var
i:integer;
begin
// result:=0;
//------------这里对感兴趣的消息进行处理----------------
{ if msg=WM_LBUTTONUP then
begin
// messagebox(0,pchar(inttostr(GetForegroundWindow)+'::'+inttostr(rHookRec^.MainWnd)),pchar('Title'),mb_ok);
// Exit;
end; }
if msg=WM_MOUSEWHEEL then
begin
if HiWord(wParam)>120 then
begin
case rHookRec^.WndType of
0:
begin
for i:=0 to 3 do
sendMessage(rHookRec^.HookedWnd,WM_VSCROLL,SB_LINEDOWN,0);
end;
1:
begin
for i:=0 to 2 do
sendMessage(GetForegroundWindow,WM_KEYDOWN,VK_DOWN,$01500001);
end;
end;
// sendMessage(GetForegroundWindow,WM_KEYDOWN,40,4);
// sendMessage(GetFocus,WM_KEYDOWN,40,4);
// sendMessage(rHookRec^.MainWnd,WM_VSCROLL,SB_LINEDOWN,0);
end
else
begin
case rHookRec^.WndType of
0:
begin
for i:=0 to 3 do
sendMessage(rHookRec^.HookedWnd,WM_VSCROLL,SB_LINEUP,0);
end;
1:
begin
for i:=0 to 2 do
sendMessage(GetForegroundWindow,WM_KEYDOWN,VK_UP,$01500001);
end;
end;
{ msg:=WM_VSCROLL;
wParam:=SB_LINEUP;
lParam:=0;}
// sendMessage(GetForegroundWindow,WM_KEYDOWN,38,4);
// sendMessage(GetFocus,WM_KEYDOWN,38,4);
// sendMessage(rHookRec^.MainWnd,WM_VSCROLL,SB_LINEUP,0);
end;
// messagebox(0,pchar(inttostr(HiWord(wParam) div 120)),pchar('Title'),mb_ok);
end;
//-------------------处理结束------------------------
if Msg=WM_DESTROY then//窗口关闭
begin
SetWindowLong(rHookRec^.HookedWnd,GWL_WNDPROC,longint(rHookRec^.HookedProc));
rHookRec^.HookedWnd:=0;//置为0,以再利用
end;
if DWORD(Msg)=Exit_Message then//程序退出,还原窗口过程
SetWindowLong(rHookRec^.HookedWnd,GWL_WNDPROC,longint(rHookRec^.HookedProc));
result:=callwindowproc(rHookRec^.HookedProc,handle,msg,wparam,lparam);//必须的
end;
//处理钩子的回调函数
function HookProc(nCode:integer;wParam:WPARAM;lParam:LPARAM):LResult;stdcall;
var
cName,tName:Array [0..255] of char;
begin
Result:=0;
if nCode<0 then//不进行处理
begin
Result:=CallNextHookEx(rHookRec^.HookID, nCode, wParam, lParam);
Exit;
end;
if rHookRec^.Ending then Exit;
// if nCode<>HSHELL_WINDOWACTIVATED then Exit;//仅在有顶层窗口被激活时才处理
// if nCode<>HCBT_ACTIVATE then Exit;
// while getparent(wparam)<>0 do
// wparam:=getparent(wparam);
// if PMOUSEHOOKSTRUCT(lParam)^.hwnd<>rHookRec^.MainWnd then exit;//不subclass安装钩子的程序
GetClassName(PMOUSEHOOKSTRUCT(lParam)^.hwnd,cName,255);
GetWindowText(GetParent(PMOUSEHOOKSTRUCT(lParam)^.hwnd),tName,255);
if (cName<>'MS_WINDOC') and (cName<>'MS_WINHELP') and (cName<>'MS_WINTOPIC_SECONDARY') then
//是不是老版winhelp ?
if LeftStr(tName,14)<>'URSoft W32Dasm' then //是不是W32Dasm(一个反汇编软件)?
exit
else
rHookRec^.WndType:=0
else
rHookRec^.WndType:=1;
// textout(getwindowdc(0),10,10,tName,14);
if rHookRec^.HookedWnd=PMOUSEHOOKSTRUCT(lParam)^.hwnd then Exit;
//若窗口已subclass,不重复处理
SendMessage(rHookRec^.HookedWnd,Exit_Message,0,0);

rHookRec^.HookedWnd:=PMOUSEHOOKSTRUCT(lParam)^.hwnd;//保存被替换过程的窗口的句柄
rHookRec^.HookedProc:=
Pointer(GetWindowLong(rHookRec^.HookedWnd,GWL_WNDPROC));
//保存指向原窗口过程的指针
if SetWindowLong(rHookRec^.HookedWnd,GWL_WNDPROC,Longint(@WndProc))=0 then
begin
rHookRec^.HookedWnd:=0;
messagebeep(0);
end;
// else
// textout(getwindowdc(0),10,10,ClassName,10);
// rHookRec^.Ending:=true;
end;
//挂钩
procedure SetHook;
begin
rHookRec^.HookID := SetWindowsHookEx(WH_MOUSE, @HookProc, hInstance, 0);//挂钩
end;
//解除hook
procedure UnHook;
begin
rHookRec^.Ending:=True;
if rHookRec^.HookID=0 then exit;//若以解除hook,则不进行处理
SendMessage(rHookRec^.HookedWnd,Exit_Message,0,0);
//向所有已被替换过程的窗口发送解除subcalss的消息
UnHookWindowsHookEx(rHookRec^.HookID);//解除hook
rHookRec^.HookID:=0;//置标志为0
// rHookRec^.MainWnd:=0;
rHookRec^.HookedWnd:=0;
end;
//保存调用DLL的程序的Handle
procedure SetMainWnd(const Wnd:HWND);
begin
// rHookRec^.MainWnd:=Wnd;
end;
//建立内存文件映射对象
procedure EntryPointProc(Reason: Integer);
const
hMapObject: THandle = 0;
begin
case reason of
DLL_PROCESS_ATTACH://DLL挂上程序时:
begin
hMapObject := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(THookRec), '_SET');
rHookRec := MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(THookRec));
rHookRec^.Ending:=False;//hook终止标志初始化
end;
DLL_PROCESS_DETACH://DLL解除时:
begin
try//释放内存文件映射对象
UnMapViewOfFile(rHookRec);
CloseHandle(hMapObject);
except
end;
end;
end;
end;
Exports
SetHook,//挂钩
SetMainWnd,//保存调用DLL的程序的Handle
UnHook;//解除hook

begin
DllProc := @EntryPointProc;
EntryPointProc(DLL_PROCESS_ATTACH);
Exit_Message:=RegisterWindowMessage(pchar('SetWin_Ext'));//定义退出程序的消息
end.
 
楼上的:
可能我的水平不够,思路是明白的,可是做起来却总是出错啊
 
那没办法,多看,多试,早晚会会的。
btw,我得程序没问题吧
 
你的程序没有问题,但是我按你的方法改我的就有问题了。
 
多人接受答案了。
 

Similar threads

I
回复
0
查看
637
import
I
I
回复
0
查看
635
import
I
I
回复
0
查看
722
import
I
顶部