从Delphi网格读取数据

时间:2012-09-14 10:01:09

标签: delphi delphi-2009 access-violation

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

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

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

我。即模仿人类用户的行为。

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

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,并显示消息“Access”   在模块'Project1.exe'中的地址0046C8C3处违反。阅读地址01262984'。

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

如何修改代码以便能够从网格中读取数据?

UPD:

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

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;

1 个答案:

答案 0 :(得分:1)

这种做法无法奏效。您的两个进程具有隔离的地址空间。地址以及对象仅在拥有该地址或对象的进程的上下文中有意义。您只能在驻留在进程中的对象上调用方法。