2012-09-14 75 views
0

我在Delphi中使用網格應用程序。從Delphi網格中讀取數據

我需要創建另一個應用程序,這應該

一個)讀取從電網和 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; 

在與「錯誤」註釋的行,下面的問題出現:

項目PROJECT1.EXE募集在模塊'Project1.exe'中地址爲0046C8C3的消息'Access 違例的異常類EAccessViolation。閱讀地址01262984'。

當我把一個斷點在該行並檢查表達「formPtr ^」中的「手錶」選項卡上,我得到「無法訪問的價值」消息的價值。

如何修改代碼以便能夠從網格中讀取數據?

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; 
+3

這不起作用。你的兩個進程有獨立的地址空間。地址僅在擁有該內存的進程的上下文中才有意義。您將需要公開自動化界面,以便一個進程可以在另一個進程中自動執行操作。 –

+0

有沒有任何如何做的例子?基本上,我需要開發應用程序A(使用Delphi或C#或C++),它將控制(按下按鈕,讀/寫文本字段)Delphi應用程序B(我不能修改)。 –

+0

另請參閱我對原始問題的更新。 –

回答

1

這種做法是行不通的。你的兩個進程有獨立的地址空間。地址以及對象只在擁有該地址或對象的進程的上下文中才有意義。您只能調用駐留在進程中的對象的方法。

+0

是的,但是如果您將代碼(類似於上面給出的代碼)放入DLL中,然後將其注入到目標應用程序的地址空間中(如http://www.codeproject。com/Articles/4610/Three-Ways-Inject-Your-Code-into-Another-Proces),可以讀出TStringGrid的值。 –

+0

確實如此。這正是我的觀點。注入會導致所有代碼在同一進程中運行。 –