拦截EDIT控件中的消息问题(上次提问过,我自己找了些资料,虽然拦截到消息,可得到的是空白字符) Delphi / Windows SDK/APIhttp://www.delphi2007.net/DelphiAPI/html/delphi_20061117131358209.html
接上次的问题,这里我在简单说说
单位有一程序,其中有一个Edit控件
该控件是用来显示我们执行操作命令返回的消息
我的目的是拦截该控件中的消息,主要是为了获取该控件中显示的字符
消息为EM_RSPLACESEL
下面我给出我根据别人的人个代码写的Hook程序,和我写的主程序
Hook.dll文件一
library hook;
{ 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,
wdSpyCommon in 'wdSpyCommon.pas',
wdMsgSpy in 'wdMsgSpy.pas';
{$R *.res}
exports
StartSpyMessage,
StopSpyMessage;
begin
end.
Hook.dll文件二
unit wdSpyCommon;
{*******************************************
* brief: 消息Spy用到的数据结构等的声明文件
* autor: linzhenqun
* date: 2005-9-25
* email: linzhengqun@163.com
* blog: http://blog.csdn.net/linzhengqun
********************************************}
interface
uses
Windows, Messages;
resourcestring
err_ProcInvalid = 'the Message spy procedure are invalid.';
err_ShareMem = 'could not create share memory.';
const
Msg_Null_Value = 0;
Msg_Type_Sent = 1;
Msg_Type_Post = 2;
Msg_Type_Return = 3;
type
{ 受监察的消息结构 }
PMsgInfo = ^TMsgInfo;
TMsgInfo = packed record
hwnd: HWND;
message: UINT;
wParam: WPARAM;
lParam: LPARAM;
time: DWORD;
pt: TPoint;
lResult: LRESULT;
MsgType: UINT;
end;
implementation
end.
Hook.dll文件三 钩子就在这里设置的
unit wdMsgSpy;
{*******************************************
* brief: 消息Spy的SDK
* autor: linzhenqun
* date: 2005-9-24
* email: linzhengqun@163.com
* blog: http://blog.csdn.net/linzhengqun
********************************************}
interface
uses
Messages, Windows, Classes, SysUtils, wdSpyCommon;
const
MApingFile_Name = 'MsgSpy_FC819A73-2718-47E2-BF78-6810562CDA65';
type
//共享内存
PShareMem = ^TShareMem;
TShareMem = record
HRevWnd: THandle; //存放接收消息的窗口句柄
HWndSpy: THandle; //被监察的窗口句柄
end;
{ 开始监察消息,AHSpyWnd为受监察的窗口,AHRevWnd为接收监察到的消息的窗口 }
function StartSpyMessage(AHSpyWnd, AHRevWnd: THandle): Boolean; stdcall;
{ 停止监察消息 }
procedure StopSpyMessage; stdcall;
var
HMsgProc, HWndProc, HWndRetProc: THandle; //相应钩子的句柄
PSMem: PShareMem; //共享内存块
hMApFile: THandle; //内存映射文件的句柄。
implementation
//将截获的消息结构发送到目标窗口
procedure SendData(AMsgInfo: PMsgInfo); stdcall;
var
pcds: PCopyDataStruct;
begin
New(pcds);
pcds^.cbData := SizeOf(TMsgInfo);
pcds^.lpData := AMsgInfo;
SendMessage(PSMem^.HRevWnd, WM_COPYDATA, 0, LongInt(pcds));
Dispose(pcds);
end;
{ WH_GETMESSAGE的钩子过程 }
function GetMsgProc(code: Integer; wP: WPARAM; lP: LPARAM): LRESULT; stdcall;
var
LMsgInfo: PMsgInfo;
begin
{只有截获的消息的窗口句柄等于被监察的窗口句柄,才进行下一步,
接着,当被监察的窗口不是接收消息的窗口时执行下一步操作;或者当被监察窗口
就是接收消息的窗口时,截获的消息不是WM_CopyData,执行下一步。
这么做是为了避免进入发送消息与截获消息的死循环}
if code = HC_ACTION then
if (PMsg(lp)^.hwnd = PSMem^.HWndSpy) then
if ((PSMem^.HWndSpy = PSMem^.HRevWnd) and (PMsg(lp)^.message <> WM_COPYDATA))
or (PSMem^.HWndSpy <> PSMem^.HRevWnd) then
begin
New(LMsgInfo);
LMsgInfo.hwnd := PMsg(lp)^.hwnd;
LMsgInfo.message := PMsg(lp)^.message;
LMsgInfo.wParam := PMsg(lp)^.wParam;
LMsgInfo.lParam := PMsg(lp)^.lParam;
LMsgInfo.pt := PMsg(lp)^.pt;
LMsgInfo.time := PMsg(lp)^.time;
LMsgInfo.lResult := Msg_Null_Value;
LMsgInfo.MsgType := Msg_Type_Post;
SendData(LMsgInfo);
Dispose(LMsgInfo);
end;
Result := CallNextHookEx(HMsgProc, code, wP, lP);
end;
{ WH_CALLWNDPROC的钩子过程 }
function CallWndProc(code: Integer; wP: WPARAM; lP: LPARAM): LRESULT; stdcall;
var
LMsgInfo: PMsgInfo;
begin
if code = HC_ACTION then
if (PCWPStruct(lp)^.hwnd = PSMem^.HWndSpy) then
if ((PSMem^.HWndSpy = PSMem^.HRevWnd) and (PCWPStruct(lp)^.message <> WM_COPYDATA))
or (PSMem^.HWndSpy <> PSMem^.HRevWnd) then
begin
New(LMsgInfo);
LMsgInfo^.hwnd := PCWPStruct(lp)^.hwnd;
LMsgInfo^.message := PCWPStruct(lp)^.message;
LMsgInfo^.wParam := PCWPStruct(lp)^.wParam;
LMsgInfo^.lParam := PCWPStruct(lp)^.lParam;
LMsgInfo^.pt := Point(0, 0);
LMsgInfo^.time := Msg_Null_Value;
LMsgInfo^.lResult := Msg_Null_Value;
LMsgInfo^.MsgType := Msg_Type_Sent;
SendData(LMsgInfo);
Dispose(LMsgInfo);
end;
Result := CallNextHookEx(HWndProc, code, wP, lP);
end;
{ WH_CALLWNDPROCRET的钩子过程 }
function CallWndRetProc(code: Integer; wP: WPARAM; lP: LPARAM): LRESULT; stdcall;
var
LMsgInfo: PMsgInfo;
begin
if code = HC_ACTION then
if (PCWPRetStruct(lp)^.hwnd = PSMem^.HWndSpy) then
if ((PSMem^.HWndSpy = PSMem^.HRevWnd) and (PCWPRetStruct(lp)^.message <> WM_COPYDATA))
or (PSMem^.HWndSpy <> PSMem^.HRevWnd) then
begin
New(LMsgInfo);
LMsgInfo^.hwnd := PCWPRetStruct(lp)^.hwnd;
LMsgInfo^.message := PCWPRetStruct(lp)^.message;
LMsgInfo^.wParam := PCWPRetStruct(lp)^.wParam;
LMsgInfo^.lParam := PCWPRetStruct(lp)^.lParam;
LMsgInfo^.pt := Point(0, 0);
LMsgInfo^.time := Msg_Null_Value;
LMsgInfo^.lResult := PCWPRetStruct(lp)^.lResult;
LMsgInfo^.MsgType := Msg_Type_Return;
SendData(LMsgInfo);
Dispose(LMsgInfo);
end;
Result := CallNextHookEx(HWndRetProc, code, wP, lP);
end;
function StartSpyMessage(AHSpyWnd, AHRevWnd: THandle): Boolean;
begin
Result := False;
try
if (HMsgProc <> 0) or (HWndProc <> 0) or (HWndRetProc <> 0) then
Exit;
PSMem^.HWndSpy := AHSpyWnd;
PSMem^.HRevWnd := AHRevWnd;
HMsgProc := SetWindowsHookEx(WH_GETMESSAGE, @GetMsgProc, HInstance, 0);
HWndProc := SetWindowsHookEx(WH_CALLWNDPROC, @CallWndProc, HInstance, 0);
HWndRetProc := SetWindowsHookEx(WH_CALLWNDPROCRET, @CallWndRetProc, HInstance, 0);
if (HMsgProc = 0) or (HWndProc = 0) or (HWndRetProc = 0) then
begin
StopSpyMessage;
Exit;
end;
except
Exception.Create(err_ProcInvalid);
end;
Result := True;
end;
procedure StopSpyMessage;
begin
UnhookWindowsHookEx(HMsgProc);
UnhookWindowsHookEx(HWndProc);
UnhookWindowsHookEx(HWndRetProc);
HMsgProc := 0;
HWndProc := 0;
HWndRetProc := 0;
end;
initialization
//创建共享内存块
hMApFile := OpenFileMApping(FILE_MAP_ALL_ACCESS, False, MApingFile_Name);
if hMApFile = 0 then
hMApFile := CreateFileMApping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(TShareMem), MApingFile_Name);
PSMem := MApViewOfFile(hMApFile, FILE_MAP_WRITE or FILE_MAP_READ, 0, 0, 0);
if PSMem = nil then
begin
CloseHandle(hMApFile);
Exception.Create(err_ShareMem);
end;
finalization
//释放共享内存块
UnMApViewOfFile(PSMem);
CloseHandle(hMApFile);
end.
友情接分;;;;;;;;
问题解决了,其实在这个Hook.dll代码里修改一下即可了
因为拦截上的问题,所以,我在dll代码里修改了一下,拦截到消息以后,我直接用
SendMessage把消息发送到我的程序中即可
具体修改为
{ WH_CALLWNDPROCRET的钩子过程 }
function CallWndRetProc(code: Integer; wP: WPARAM; lP: LPARAM): LRESULT; stdcall;
var
LMsgInfo: PMsgInfo;
begin
//if code = HC_ACTION then 这条也可以不要
if (PCWPRetStruct(lp)^.hwnd = PSMem^.HWndSpy) then
if ((PSMem^.HWndSpy = PSMem^.HRevWnd) and (PCWPRetStruct(lp)^.message <> WM_COPYDATA))
or (PSMem^.HWndSpy <> PSMem^.HRevWnd) then
begin
New(LMsgInfo);
LMsgInfo^.hwnd := PCWPRetStruct(lp)^.hwnd;
LMsgInfo^.message := PCWPRetStruct(lp)^.message;
LMsgInfo^.wParam := PCWPRetStruct(lp)^.wParam;
LMsgInfo^.lParam := PCWPRetStruct(lp)^.lParam;
LMsgInfo^.pt := Point(0, 0);
LMsgInfo^.time := Msg_Null_Value;
LMsgInfo^.lResult := PCWPRetStruct(lp)^.lResult;
LMsgInfo^.MsgType := Msg_Type_Return;
//SendData(LMsgInfo); 这条不要
SendMessage(PSMem^.HRevWnd,PCWPRetStruct(lp)^.message,PCWPRetStruct(lp)^.wParam,PCWPRetStruct(lp)^.lParam) //修改中添加了这条
Dispose(LMsgInfo);
end;
Result := CallNextHookEx(HWndRetProc, code, wP, lP);
end;
然后,把其他的两个钩子函数都可以去掉,包括安装钩子,只留第三个钩子,
呵呵,现在,我在那个单位的程序里输入命令以后,返回的消息,包括字符
全部在我的程序中显示了,虽然我没弄明白这些参数的用途,不过也算解决了一个问题
在我的程序里还得在用消息机制拦截自己进程的消息并处理消息,
虽然复杂点,现在也只能这样了
呵呵,分还是我自己拿吧,等以后在有问题在问大家
不要啊,楼主,给偶一点也好嘛,呵呵~~
路过。
路过~~~
楼主不要这么小气嘛
呵呵,分还是我自己拿吧,等以后在有问题在问大家
----------------------------------------------
把他性欲给降低!!!!!!!!!!!!!!!