Я пытаюсь написать систему плагинов для моего приложения на основе 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;
Я должен что-то упустить где-то.У кого-нибудь есть хорошие идеи?