У меня есть приложение в Delphi с сеткой.Чтение данных из сетки Delphi
Мне нужно создать другое приложение, которое должно
а) читать данные из сетки и б) записать данные в сеть,
I. е. подражать действиям человека.
Для того, чтобы прочитать данные из таблицы, я использую следующий код:
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;
В соответствии с «Error» комментарий, возникает следующая проблема:
Проект Project1.exe поднял класс исключения EAccessViolation с сообщением «Доступ нарушение по адресу 0046C8C3 в модуле Project1.exe». Читайте адрес 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;
Это не сработает. Два ваших процесса имеют изолированные адресные пространства. Адрес имеет смысл только в контексте процесса, которому принадлежит эта память. Вам нужно будет открыть интерфейс автоматизации, чтобы один процесс мог автоматизировать действия в другом процессе. –
Есть ли примеры того, как это сделать? В принципе, мне нужно разработать приложение A (в Delphi или C# или C++), которое будет управлять (нажимать кнопки, читать/писать в/из текстовых полей) Delphi application B (которое я не могу изменить). –
См. Также мое обновление исходного вопроса. –