Delphi从DLL打开模式窗体

Delphi从DLL打开模式窗体,delphi,dll,delphi-xe2,Delphi,Dll,Delphi Xe2,我需要添加一些插件功能的应用程序,并能够动态加载和打开插件 在我的申请表(主表)中,我有以下代码: procedure TfrmMain.PluginClick(Sender: TObject); Var DllFileName : String; DllHandle : THandle; VitoRunPlugin : procedure (AppHandle, FormHandle : HWND); begin DllFileName := (Sender AS TCom

我需要添加一些插件功能的应用程序,并能够动态加载和打开插件

在我的申请表(主表)中,我有以下代码:

procedure TfrmMain.PluginClick(Sender: TObject);
Var
  DllFileName : String;
  DllHandle   : THandle;
  VitoRunPlugin : procedure (AppHandle, FormHandle : HWND);
begin
  DllFileName := (Sender AS TComponent).Name + '.dll';
  DllHandle := LoadLibrary(PWideChar (DllFileName));

  if DllHandle <> 0 then
  Begin
    @VitoRunPlugin := GetProcAddress (DllHandle, 'VitoRunPlugin');
    VitoRunPlugin (Application.Handle, Self.Handle);
  End Else Begin
    ShowMessage ('Plugin load error');
  End;

  FreeLibrary (DllHandle);
end;
表单打开正常,但没有工作:我既不能按下按钮,也不能关闭表单。我只能通过Alt+F4将其关闭


怎么了?

CreateParented
使窗体成为子窗口。并且不能以模式显示子窗口。那么,谁知道当你的表单被显示时会发生什么呢?我确信,当您将VCL窗体窗口句柄传递给另一个VCL窗体的
CreateParented
构造函数时,我无法预测会发生什么

将表单创建更改为这样:

F := TForm.Create(nil);
为了使表单拥有正确的所有者(这里我的意思是),您可能需要覆盖
CreateParams
,如下所示:

procedure TMyForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.WndParent := FormHandle;
end;
显然,您需要声明派生的
TMyForm
类并添加一些管道,以允许其重写的
CreateParams
方法访问所有者表单句柄


如果你想让按钮做点什么,你需要编码。一个
OnClick
事件处理程序,或者设置按钮的
ModalResult
属性。

该按钮没有OnClick事件处理程序,这可能是它看起来没有响应的原因。是否尝试过
Application.Handle:=AppHandle在DLL中?我尝试了,但没有工作。您确实应该将按钮的
ModalResult
设置为不同于
mrNone
(默认值)。我会将
AppHandle
传递到
CreateParented
,而不是
FormHandle
(或者在设置
Application.Handle
后调用
Create(Application)
)。设置正确的FormStyle或重新启用windows链还有两个解决方法,同时继续使用.ParentWindow-
procedure TMyForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.WndParent := FormHandle;
end;