Проблемы с созданием формы в jvPlugin dll и отображением ее как дочернего элемента управления в почтовой форме - PullRequest
0 голосов
/ 21 октября 2011

Я пытаюсь написать систему плагинов для моего приложения на основе jvPlugin.Я создаю формы в плагине dll, затем переопределяю их в элементы управления стыковкой DevExpress.На первый взгляд, это похоже на работу.Проблема в том, что ни один из элементов управления на формах dll никогда не получает фокус.Кроме того, при нажатии на элементы управления, такие как TSplitter, возникает исключение «Элемент управления« xxx »не имеет родительского окна».

Вот как я это делаю (сокращенная версия).

Плагинхост реализует интерфейс IPluginHost

  IPluginHost = interface
  ['{C0416F76-6824-45E7-8819-414AB8F39E19}']
    function AddDockingForm(AForm: TForm): TObject;
    function GetParentApplicationHandle: THandle;
  end;

Плагин реализует интерфейс IMyPlugin

  IMyPlugin = interface
  ['{E5574F27-3130-4EB8-A8F4-F709422BB549}']
    procedure AddUIComponents;
  end;

При инициализации плагина вызывается следующее событие:

procedure TMyPlugin.JvPlugInInitialize(Sender: TObject; var AllowLoad: Boolean);
var
  RealApplicationHandle: THandle;
begin
  if Supports(HostApplication.MainForm, IPluginHost, FPluginHost) then
  begin
    RealApplicationHandle := Application.Handle;
    Application.Handle := FPluginHost.GetParentApplicationHandle; // Returns Application.Handle from the host application
    try
      FMyPluginForm:= TMyPluginForm.Create(Application); // Plugin host app owns the form
    finally
      Application.Handle := RealApplicationHandle;
    end;
  end;
end;

Когдахост плагина загрузился, я вызываю IMyPlugin.AddUIComponents в моем плагине.Это реализовано так:

procedure TMyPlugin.AddUIComponents;
begin
  // Add the docking form
  FPluginHost.AddDockingForm(FMyPluginForm);
end;

AddDockingForm реализован на хосте следующим образом:

function TfrmMyPluginHost.AddDockingForm(AForm: TForm): TObject;
var
  DockPanel: TdxDockPanel;
begin
  // Create a new dockpanel
  DockPanel := TdxDockPanel.Create(Self);
  DockPanel.Name := DPName;

  DockPanel.Height := AForm.Height;
  DockPanel.DockTo(dxDockSite1, dtBottom, 0);
  DockPanel.AutoHide := TRUE;

  // Rename the dock panel and parent the plugin
  DockPanel.Caption := AForm.Caption;
  DockPanel.Tag := Integer(AForm);

  AForm.Parent := DockPanel;
  AForm.BorderStyle := bsNone;
  AForm.Align := alClient;
  AForm.Show;

  FDockedPluginFormList.Add(AForm);

  Result := DockPanel;
end;

Если я запускаю следующую функцию на любом из элементов управления в форме плагина, я вижусписок, идущий полностью назад к главной форме моего хозяина.Все же TSplitters говорят мне, что у них нет родительского окна.Как это может быть?

function TfrmMyPlugin.GetParents(WC: TWinControl): String;
begin
  if (WC <> nil) and (WC is TWinControl) then
    Result := WC.Name + ' [' + WC.ClassName + '] - ' + GetParents(WC.Parent);
end;

Я должен что-то упустить где-то.У кого-нибудь есть хорошие идеи?

Ответы [ 2 ]

1 голос
/ 21 октября 2011

Сборка плагина и хост-приложения с пакетами времени исполнения.

Без использования пакетов времени выполнения, DLL использует отдельную копию RTL, VCL и любых используемых модулей. Например, класс TForm библиотеки DLL не совпадает с классом TForm хоста (оператор is не проходит через границу хоста / DLL, и поэтому элемент управления DLL не распознает родительскую форму хоста как допустимый экземпляр TForm) глобальные переменные, такие как Application, Mouse, Screen, являются отдельными экземплярами, у вас есть две копии RTTI и т. д. и т. д.

VCL просто не был предназначен для такого использования.

При включенных пакетах времени выполнения все проблемы решены, и плагин (либо сам пакет времени исполнения, либо DLL, собранная из пакетов времени выполнения) может беспрепятственно интегрироваться с хост-приложением с помощью пакетов времени выполнения.

0 голосов
/ 21 октября 2011

Мы заставили его работать, используя «пакеты времени выполнения», добавив «vcl, rtl, ourownpckg», где ourownpckg - это наш собственный пакет, созданный со всеми зависимостями DX и некоторыми другими, которые мы используем в exe-плагинах, включая JVCL.

Три пакета должны быть отправлены по exe

Надеюсь, это поможет

...