B
bcfans
Unregistered / Unconfirmed
GUEST, unregistred user!
//------------------------------------------------------------------<br>{ DLL单元 }<br>library Project1;<br><br>uses<br> ShareMem, //因为用到了string类型<br> SysUtils,<br> Classes,<br> Unit1 in 'Unit1.pas';<br><br>{$R *.res}<br>exports<br> StartSpyMessage,<br> StopSpyMessage;<br><br>begin<br>end.<br>//------------------------------------------------------------------<br><br><br>{ DLL单元引用的Unit1单元 }<br>//------------------------------------------------------------------<br>unit Unit1;<br>{ }<br>interface<br><br>uses<br> Messages, Windows, Classes, SysUtils;<br><br>{ 开始监视 hSpyWnd为调用者窗体上Edit控件的句柄 dwThreadId为要监视的线程的ID }<br>function StartSpyMessage(hSpyWnd: THandle; dwThreadId: DWORD): Boolean; stdcall;<br><br>{ 结束监视 }<br>procedure StopSpyMessage; stdcall;<br><br>implementation<br><br>var<br> HWndProc: THandle; //WH_CALLWNDPROC钩子的句柄<br><br> { 保存StartSpyMessage在被调用时传进来的要监视的线程的ID }<br> ghSpyWnd: HWND; <br><br>{ WH_CALLWNDPROC的钩子过程 }<br>function CallWndProc(code: Integer; wP: WPARAM; lP: LPARAM): LRESULT; stdcall;<br>var<br> s: string;<br>begin<br> if code = HC_ACTION then<br> if PCWPSTRUCT(lp)^.message = WM_COMMAND then //只想捕获菜单操作和快捷键操作<br> begin<br> { 设置DLL调用程序上的Edit控件的内容为 受控程序的菜单ID或快捷键ID }<br> s := IntToStr(LOWORD(PCWPSTRUCT(lp)^.wParam));<br> MessageBox(0, '截获到了', '', MB_OK);<br> SendMessage(ghSpyWnd, WM_SETTEXT, Length(s), Longint(s)); { ghSpyWnd为DLL调用程序上的Edit控件的句柄 }<br> end;<br> Result := CallNextHookEx(HWndProc, code, wP, lP);<br>end;<br><br>function StartSpyMessage(hSpyWnd: THandle; dwThreadId: DWORD): Boolean;<br>begin<br> Result := False;<br> ghSpyWnd := hSpyWnd;<br> if HWndProc <> 0 then<br> Exit;<br><br> { 因为只想监视指定程序,不想将DLL注入所有进程空间来挂WH_CALLWNDPROC钩子,所以使用了ThreadId 主要是想节省资源 }<br> HWndProc := SetWindowsHookEx(WH_CALLWNDPROC, @CallWndProc, HInstance, dwThreadId);<br> if HWndProc = 0 then<br> begin<br> StopSpyMessage;<br> Exit;<br> end;<br> Result := True;<br>end;<br><br>procedure StopSpyMessage;<br>begin<br> UnhookWindowsHookEx(HWndProc);<br> HWndProc := 0;<br>end;<br><br>end.<br>//------------------------------------------------------------------<br><br><br>//------------------------------------------------------------------<br>{ DLL的调用程序 窗体上放两个Edit,两个Button }<br>unit Unit1;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> Dialogs, StdCtrls;<br><br>type<br> TForm1 = class(TForm)<br> Edit1: TEdit;<br> Button1: TButton;<br> Button2: TButton;<br> Edit2: TEdit;<br> procedure Button1Click(Sender: TObject);<br> procedure Button2Click(Sender: TObject);<br> procedure FormDestroy(Sender: TObject);<br> private<br> { Private declarations }<br> public<br> { Public declarations }<br> end;<br><br>var<br> Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br>function StartSpyMessage(hSpyWnd: THandle; dwThreadId: DWORD): Boolean; stdcall; external 'Project1.dll';<br>procedure StopSpyMessage; stdcall; external 'Project1.dll';<br><br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> { Edit2上的内容为16进制的线程ID(创建最外层窗体的线程的ID),可以用Spy++查得 }<br> StartSpyMessage(Edit1.Handle, strtoint('$' + Edit2.Text)); //开始监视<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br> StopSpyMessage; //停止监视<br>end;<br><br>procedure TForm1.FormDestroy(Sender: TObject);<br>begin<br> StopSpyMessage;<br>end;<br><br>end.<br>//------------------------------------------------------------------<br><br><br>现在的问题是:<br>在开始监视后用进程管理器可以看到Project1.dll和borlandmm.dll已经进入了受控程序的进程中。比如RealPlayer。<br>可是不论我操作其菜单还是使用快捷键,我的监控程序都监视不到!怎么回事?<br>另外在停止监视时受控程序会弹出出错对话框,报告“0X00000000指令引用的0X00000000内存。该内存不能为read”怎么回事?<br><br>差哪呢?为什么就不能捕获WM_COMMAND消息呢?为什么?????