神仙们过来给我把把脉, HOOK其它进程中的DBGrid老汉一个星期没解决, 郁闷(300分)

  • 主题发起人 主题发起人 gzbxmcx
  • 开始时间 开始时间
G

gzbxmcx

Unregistered / Unconfirmed
GUEST, unregistred user!
已得到对象实例但不能Next数据, 只能读出第一条数据, 只要进行Next或Edit或Insert都是报地址冲突...
核心代码如下:

function FindControl(hwnd: HWND): TWinControl;
type
PObjectInstance = ^TObjectInstance;
TObjectInstance = packed record
Code: Byte; // 0xE8 { CALL NEAR PTR Offset } 相对短跳转
Offset: Integer; // CalcJmpOffset(Instance, @Block^.Code)
Method: Pointer; // WndMethod地址
Self: Pointer; // 对象实例
end;
var
Instance: PObjectInstance;
begin
Instance := Pointer(GetWindowLong(hwnd, GWL_WNDPROC));
if Instance <> nil then
Result := Instance.Self
else
Result := nil;
end;

//自定义消息在隐藏窗口中, 用来接收调用程序发来的消息.

function MsgWndProc(hwnd: HWND; Msg: UINT; WParam: WPARAM; LParam: LPARAM):
LRESULT; stdcall;
var
Str: string;
TempQry: TAdoQuery;
begin
case Msg of
CM_QUERYGRID:
begin
Result := -1;
if P^.DestWnd <> 0 then
begin
ResDataSet := TDBGrid(FindControl(P^.DestWnd)).DataSource.DataSet;
if ResDataSet.RecordCount > 0 then
begin
Result := 1;
end;
end;
Exit;
end;
end;
Result := DefWindowProc(hwnd, Msg, WParam, LParam);
end;
 
你HOOK到其他进程,你的DLL中有TDBGrid类,而另外的进程同样也有TDBGrid.
地址不同,根本就是同名的两个类.
所以你这样的用法不行.
1.对方的进程带VCL包,你的DLL也带VCL包运行.你的方法就可行了.TDBGrid在VCL.BPL中,你的DLL和他的EXE都共享这一个包.
2.我看你的代码对方是ADOQuery.那么你可以获取对方的Recordset.这个是一个接口.你去操作这个接口.这种方式无需共享包的形式.
 
嘿嘿....问题解决了, 范了个错误把TDataSet放到共享内存区了..
 
你的获取控件实例的方法真不错呢。我记得我Delphi7中声明的TObjectInstance结构没有self成员的,你的这个结构是哪个Delphi版本的?
 
我用的是Delphi 6, 所有的对象方法中都有一个隐含的self变量, self是指向调用该方法实例的指针, 编译器当作一个隐含参数传入到所有方法中.
 
接受答案了.
 
后退
顶部