При разработке приложений на Delphi часто возникает необходимость создания компонентов, которые могут быть автоматизированы другими приложениями. Одним из способов достижения этой цели является создание COM-сервера. В данной статье мы рассмотрим, как настроить COM-сервер в Delphi XE для работы с ActiveX объектами, чтобы обеспечить возможность изменения данных в запущенном приложении.
Проблема
Разработчик столкнулся с проблемой, при которой при запуске VBScript, предназначенного для изменения текста в Memo-контроле запущенного приложения, создавалась новая форма, текст добавлялся, но после этого приложение закрывалось, не изменяя текст в запущенном экземпляре. Проблема заключалась в том, что при использовании GetObject не удавалось переиспользовать уже запущенное приложение.
Решение
Для решения проблемы необходимо было изменить подход к регистрации COM-сервера. В частности, было обнаружено, что добавление глобального объекта и его регистрация в Running Object Table (ROT) позволяет достичь желаемого результата. Таким образом, ком-вызов будет направлен на уже запущенное приложение.
Пример кода
program TestOLEProject3;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
TestOLEProject3_TLB in 'TestOLEProject3_TLB.pas',
Unit2 in 'Unit2.pas' {TestOLE: CoClass},
Unit3 in 'Unit3.pas';
{$R *.TLB}
{$R *.res}
begin
Application.Initialize;
RegisterGlobalTestOLE; // Регистрация глобального объекта
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
unit Unit2;
interface
uses
ComObj, ActiveX, TestOLEProject3_TLB, StdVcl;
type
TTestOLE = class(TAutoObject, ITestOLE)
protected
procedure Method1; safecall;
procedure Quit; safecall;
end;
implementation
uses ComServ, Unit1, Unit3;
procedure TTestOLE.Method1;
begin
Form1.Memo1.Lines.Add('Wheeee'); // Добавление текста в Memo
end;
procedure TTestOLE.Quit;
begin
RevokeGlobalTestOLE; // Отзыв регистрации глобального объекта
end;
initialization
TAutoObjectFactory.Create(ComServer, TTestOLE, CLASS_TestOLE, ciMultiInstance, tmApartment);
end.
unit Unit3;
interface
procedure RegisterGlobalTestOLE;
procedure RevokeGlobalTestOLE;
implementation
uses TestOLEProject3_TLB, ComObj, ActiveX;
var
GlobalTestOLEHandle: longint = 0;
procedure RegisterGlobalTestOLE;
var
GlobalTestOLE: ITestOLE;
begin
GlobalTestOLE := CoTestOLE.Create;
OleCheck(RegisterActiveObject(GlobalTestOLE, CLASS_TestOLE, ACTIVEOBJECT_STRONG, GlobalTestOLEHandle));
end;
procedure RevokeGlobalTestOLE;
begin
if (GlobalTestOLEHandle <> 0) then
begin
OleCheck(RevokeActiveObject(GlobalTestOLEHandle, nil));
GlobalTestOLEHandle := 0;
end;
end;
end.
Важные моменты
При использовании множественного инстанцирования (ciMultiInstance) и апартаментной модели потоков (tmApartment) COM-сервер будет доступен для запущенных экземпляров приложения.
Регистрация в Running Object Table (ROT) позволяет автоматизировать уже запущенное приложение, не создавая новый экземпляр.
Заключение
Создание COM-сервера в Delphi XE для работы с ActiveX объектами требует тщательной настройки параметров инстанцирования и регистрации объекта в ROT. Это позволяет достичь переиспользования запущенного приложения для изменения его данных без необходимости запуска нового экземпляра.
Контекст связан с настройкой сервера COM в Delphi XE для работы с ActiveX объектами, чтобы обеспечить возможность взаимодействия и изменения данных в запущенных приложениях Windows 8.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS