【问题标题】:Reading data from a Delphi grid从 Delphi 网格中读取数据
【发布时间】:2012-09-14 10:01:08
【问题描述】:

我在 Delphi 中有一个带有网格的应用程序。

我需要创建另一个应用程序,应该

a) 从网格中读取数据并 b) 将数据写入网格,

我。 e.模拟人类用户的行为。

为了从表中读取数据,我使用以下代码:

Procedure TForm1.Button1Click(Sender: TObject);
type
  PForm = ^TForm;
  PClass = ^TClass;
var
  formPtr : PForm;
  I: Integer;
  msg : string;
  windowHandle : HWND;
begin
  windowHandle := FindWindow('TForm1', 'FORMSSSSS');
  formPtr := PForm(GetVCLObjectAddr(windowHandle) + 4);
  if (not Assigned(formPtr)) then Exit;
  for I := 0 to formPtr^.ControlCount - 1 do // Error
  begin
    msg := msg + formPtr^.Controls[i].Name;
    if formPtr^.Controls[i].Name = 'StringGrid1' then
    begin
      msg := TStringGrid(formPtr^.Controls[i]).Cells[1, 1];
    end;

  end;
  ShowMessage(msg);
end;


function GetVCLObjectAddr(AHandle: HWND): DWORD;
var
  pid: DWORD;
begin
  pid := 0;
  GetWindowThreadProcessId(AHandle, pid);
  if (pid =0) then
  begin
    Result := 0;
    Exit;
  end;
  Result := GetPropW(AHandle, PWideChar(WideString(Format('Delphi%.8X', [PID]))))
end;

在带有“错误”注释的行中,出现以下问题:

Project Project1.exe 引发异常类 EAccessViolation 并带有消息“访问” 模块“Project1.exe”中地址 0046C8C3 的违规行为。读取地址 01262984'。

当我在该行设置断点并检查“Watches”选项卡中表达式“formPtr^”的值时,我收到“Inaccessible value”消息。

应该如何修改代码才能从网格中读取数据?

更新:

如果我将代码更改为下面给出的版本,内存问题就会消失。但是出现了另一个问题——控制计数等于零。

Procedure TForm1.Button1Click(Sender: TObject);
var
  formPtr : TForm;
  I: Integer;
  msg : string;
  windowHandle : HWND;
begin
  windowHandle := FindWindow('TForm1', 'FORMSSSSS');
  formPtr := TForm(GetVCLObjectAddr(windowHandle) + 4);
  if (not Assigned(formPtr)) then Exit;
  for I := 0 to formPtr.ControlCount - 1 do
  begin
    msg := msg + formPtr.Controls[i].Name;
    if formPtr.Controls[i].Name = 'StringGrid1' then
    begin
      msg := TStringGrid(formPtr.Controls[i]).Cells[1, 1];
    end;    
  end;
  ShowMessage(msg);
end;

【问题讨论】:

  • 这行不通。您的两个进程具有独立的地址空间。地址仅在拥有该内存的进程的上下文中才有意义。您将需要公开一个自动化接口,以便一个进程可以自动执行另一个进程中的操作。
  • 有没有例子说明如何做到这一点?基本上,我需要开发应用程序 A(在 Delphi 或 C# 或 C++ 中),它将控制(按下按钮,读/写到/从文本字段)Delphi 应用程序 B(我无法修改)。
  • 另请参阅我对原始问题的更新。
  • 您可以在这里找到一些如何在两个进程之间进行通信的好建议:moving data between processes
  • 关于您的更新,它仍然无法正常工作。你把头埋在沙子里。你有两个独立的地址空间。是时候让你接受这一点了。

标签: delphi delphi-2009 access-violation


【解决方案1】:

这种方法行不通。您的两个进程具有独立的地址空间。一个地址,也就是一个对象,仅在拥有该地址或对象的进程的上下文中才有意义。您只能调用驻留在进程中的对象的方法。

【讨论】:

  • 是的,但是如果您将代码(类似于上面给出的那个)放入 DLL,然后将其注入目标应用程序的地址空间(如 codeproject.com/Articles/4610/… 中所述),它是可以读出 TStringGrid 的值。
  • 确实如此。这正是我的观点。注入导致所有代码在同一个进程中运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
相关资源
最近更新 更多