放出测试代码DLL中的代码
unit MyMsgHook;interface
uses
Windows,SysUtils,Messages,Dialogs;
function MsgHookProc(icode:Integer;awParam:WPARAM;alParam:LPARAM):LongInt;stdcall;
function SetupHook:Boolean;stdcall
function EndHook:Boolean;stdcallvar
IsHooked:Boolean=False;
gHook:HHOOK;implementation
//------------------------------------------------------------------------------function MsgHookProc(icode:Integer;awParam:WPARAM;alParam:LPARAM):LongInt;stdcall;
begin
Result:=0;
if icode<0 then
Result:=CallNextHookEx(gHook,icode,awParam,alParam); if icode=HCBT_ACTIVATE then
ShowMessage('11111111');end;//------------------------------------------------------------------------------
function SetupHook:Boolean;stdcall
begin
if IsHooked=False then
begin
gHook:=SetWindowsHookEx(WH_CBT,@MsgHookProc,HInstance,0);
IsHooked:=True;
Result:=True;
end
else
Result:=False;
end;
//------------------------------------------------------------------------------
function EndHook:Boolean;stdcall
begin
if IsHooked=True then
begin
Result:=UnhookWindowsHookEx(gHook);
IsHooked:=False;
end;
end;
end.导出函数如下
library MsgHook;{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }uses
SysUtils,
Classes,
MyMsgHook in 'MyMsgHook.pas';exports
SetupHook,
EndHook;
begin
end.MAIN程序中的测试代码
unit mwssage;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
btn1: TButton;
btn2: TButton;
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;function SetupHook:Boolean;stdcall;external 'MsgHook.dll';
function EndHook:Boolean;stdcall;external 'MsgHook.dll';implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
begin
if SetupHook then
ShowMessage('成功加入');
end;procedure TForm1.btn2Click(Sender: TObject);
begin
if EndHook then
ShowMessage('成功解除');
end;end.
编译没错,运行后为什么会出错?请高手根据此代码解之,感谢
unit MyMsgHook;interface
uses
Windows,SysUtils,Messages,Dialogs;
function MsgHookProc(icode:Integer;awParam:WPARAM;alParam:LPARAM):LongInt;stdcall;
function SetupHook:Boolean;stdcall
function EndHook:Boolean;stdcallvar
IsHooked:Boolean=False;
gHook:HHOOK;implementation
//------------------------------------------------------------------------------function MsgHookProc(icode:Integer;awParam:WPARAM;alParam:LPARAM):LongInt;stdcall;
begin
Result:=0;
if icode<0 then
Result:=CallNextHookEx(gHook,icode,awParam,alParam); if icode=HCBT_ACTIVATE then
ShowMessage('11111111');end;//------------------------------------------------------------------------------
function SetupHook:Boolean;stdcall
begin
if IsHooked=False then
begin
gHook:=SetWindowsHookEx(WH_CBT,@MsgHookProc,HInstance,0);
IsHooked:=True;
Result:=True;
end
else
Result:=False;
end;
//------------------------------------------------------------------------------
function EndHook:Boolean;stdcall
begin
if IsHooked=True then
begin
Result:=UnhookWindowsHookEx(gHook);
IsHooked:=False;
end;
end;
end.导出函数如下
library MsgHook;{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }uses
SysUtils,
Classes,
MyMsgHook in 'MyMsgHook.pas';exports
SetupHook,
EndHook;
begin
end.MAIN程序中的测试代码
unit mwssage;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
btn1: TButton;
btn2: TButton;
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;function SetupHook:Boolean;stdcall;external 'MsgHook.dll';
function EndHook:Boolean;stdcall;external 'MsgHook.dll';implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
begin
if SetupHook then
ShowMessage('成功加入');
end;procedure TForm1.btn2Click(Sender: TObject);
begin
if EndHook then
ShowMessage('成功解除');
end;end.
编译没错,运行后为什么会出错?请高手根据此代码解之,感谢
HCBT_ACTIVATE
HCBT_CREATEWND
HCBT_DESTROYWND
HCBT_MINMAX
HCBT_MOVESIZE
HCBT_SETFOCUS
HCBT_SYSCOMMAND library HookPrj; uses
SysUtils,
Classes,
QQTitleHook in ’QQTitleHook.pas’; exports
EnableWheelHook, DisableWheelHook; begin
hkQQChat:= 0;
end.
==========================================================
unit QQTitleHook; interface uses
Windows, Messages, SysUtils, Dialogs, CommCtrl, StrUtils; var
hkQQChat: HHOOK;
//聊天窗口的句柄
hwQQChat: HWnd ;
//聊天窗口的标题
tlQQChat: string;
//窗口类名
clsName: string;
buf: array [0..1024] of char; const
//QQ聊天窗口的类名
csQQ = ’#32770’; function TitleHookProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
function EnumWindowsTitleFunc(Handle: THandle; lParam: LPARAM): boolean ; stdcall;
function EnableWheelHook : Boolean; stdcall; export;
function DisableWheelHook: Boolean; stdcall; export; implementation //钩子的处理函数
function TitleHookProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
Result:= 0;
if Code<0 then
begin
Result:= CallNextHookEx(hkQQChat, Code, wParam, lParam);
Exit;
end
else
if Code = HCBT_ACTIVATE then
begin
//获取激活窗口的句柄,以及窗口类名,然后判断此窗口类名是否为#32770。
hwQQChat:= HWND(wParam);
GetClassName(hwQQChat, buf, 1024);
clsName:= string(buf);
if clsName = csQQ then
begin
//如果窗口类名是#32770,则遍枚举所有窗口,并将窗口句柄传入
//【这里仅仅做演示用,因为Windows中很多窗口的类名均为#32770,所以这样判断效率会很底,】
//【有兴趣的朋友可以根据QQ聊天窗口的特性来增加判断条件,从而提高效率。】
EnumWindows(@EnumWindowsTitleFunc, hwQQChat);
end;
end;
end; function EnumWindowsTitleFunc(Handle: THandle; lParam: LPARAM): boolean ; stdcall;
begin
if (Handle = lParam) and boolean(GetWindowText(Handle, buf, 256)) then
begin
//根据窗口句柄获得窗口标题
tlQQChat:= string(buf);
//然后判断标题中是否包含“与...聊天”等相关字符,如果包括则此窗口为QQ聊天窗口
if ((pos(’与’, tlQQChat)>0) and (pos(’聊天中’, tlQQChat)>0)) then
begin
//确定为聊天窗口后遍修改窗口标题。
tlQQChat := AnsiReplaceStr(tlQQChat, ’与’ , ’我的文档’);
tlQQChat := AnsiReplaceStr(tlQQChat, ’聊天中’, ’’ );
SetWindowText(Handle, pchar(tlQQChat));
end;
//【同上,这个地方大家可以自由控制,不仅仅局限在QQ、MSN等聊天窗口。】
//【而且想要将标题改成什么也可以自由控制,如果能根据修改后的窗口图标来确定标题】
//【比如通过修改将窗口图标替换成Delphi的图标,然后标题修改为Delphi7,谁还能看出破绽呢?哈哈】
if ((pos(’群 -’, tlQQChat)>0) or (pos(’高级群 -’, tlQQChat)>0)) then
begin
tlQQChat := AnsiReplaceStr(tlQQChat, ’群 -’, ’我的文档’);
tlQQChat := AnsiReplaceStr(tlQQChat, ’高级’ , ’’ );
SetWindowText(Handle, pchar(tlQQChat));
end;
//MSN
if pos(’ - 对话’, tlQQChat)>0 then
begin
tlQQChat := AnsiReplaceStr(tlQQChat, ’ - 对话’ , ’我的文档’);
SetWindowText(Handle, pchar(tlQQChat));
end;
end;
Result :=True;
end; //启动钩子
function EnableWheelHook: Boolean; stdcall; export;
begin
if hkQQChat=0 then
begin
hkQQChat := SetWindowsHookEx(WH_CBT, @TitleHookProc, Hinstance, 0);
Result := True;
end
else
Result := False;
end; //卸载钩子
function DisableWheelHook: Boolean; stdcall; export;
begin
if hkQQChat<>0 then
begin
UnHookWindowsHookEx(hkQQChat);
hkQQChat := 0;
Result := True;
end
else
Result := False;
end; end.先看看这个例子看看自己能不能搞定
unit HKProc;
interface
uses
Windows, Messages,Dialogs,iniFiles,SysUtils;
var
hNextHookProc: HHook;
procSaveExit: Pointer;
function CBTProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
function EnableHotKeyHook: BOOL; export;
function DisableHotKeyHook: BOOL; export;
implementation
function CBTProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
p: PCBTActivateStruct;
begin
result:= 0;
If iCode<0 Then
begin
Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);
Exit;
end
else
begin
If iCode = HCBT_ACTIVATE then
begin
p:= PCBTActivateStruct(lParam);
if (p.hWndActive = findwindow('#32770',nil)) then showmessage('lkjl');
end;
end;
end;
function EnableHotKeyHook: BOOL; export;
begin
Result := False;
if hNextHookProc <> 0 then Exit;
hNextHookProc := SetWindowsHookEx(WH_CBT,CBTProc,HInstance,0);
Result := hNextHookProc <> 0;
end;
function DisableHotKeyHook: BOOL; export;
begin
if hNextHookProc <> 0 then
begin
UnhookWindowshookEx(hNextHookProc);
hNextHookProc := 0;
end;
Result := hNextHookProc = 0;
end;
end. __________________________________________
If iCode = HCBT_ACTIVATE then
begin
p:= PCBTActivateStruct(lParam);
p.hWndActive//就是激活窗口的句柄。findwindow('#32770',nil)返回的是QQ聊天窗口的句柄
end;
function MsgHookProc(icode:Integer;awParam:WPARAM;alParam:LPARAM):LongInt;stdcall;
begin
Result:=0;
if icode<0 then
begin
Result:=CallNextHookEx(gHook,icode,awParam,alParam);
exit;
end
else if icode=HCBT_ACTIVATE then
begin
// ShowMessage('11111111');
end;end;
改成这样试试,我测试没问题
function MsgHookProc(icode:Integer;awParam:WPARAM;alParam:LPARAM):LongInt;stdcall;
var
a:textfile;
begin
Result:=0;
if icode<0 then
begin
Result:=CallNextHookEx(gHook,icode,awParam,alParam);
exit;
end
else if icode=HCBT_ACTIVATE then
begin
assignfile(a,'c:\1.txt');//开始写入//rewrite(a);
if FileExists('c:\1.txt') then
begin
append(a);
end
else
rewrite(a);//rewrite(a);//写入操作
writeln(a,'有窗口激活了');//写入
closefile(a);//关闭文件
end;end;
begin
p:= PCBTActivateStruct(lParam);
p.hWndActive//就是激活窗口的句柄。findwindow('#32770',nil)返回的是QQ聊天窗口的句柄
end;
参考
要有条件的,不能随便弹出!