【问题标题】:Delphi open modal form from DLLDelphi从DLL打开模态表单
【发布时间】:2013-11-10 21:20:40
【问题描述】:

我需要向应用程序添加一些插件功能,以及动态加载和打开插件的能力。

在我的应用程序(主要形式)中,我有以下代码:

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;

我的插件库是(现在只用于测试):

library plugintest;

uses
  System.SysUtils, WinApi.Windows,
  Vcl.Forms,
  System.Classes,
  Vcl.StdCtrls;

{$R *.res}

Procedure VitoRunPlugin (AppHandle, FormHandle : HWND);
  Var F : TForm;  B: TButton;
Begin
  F := TForm.CreateParented(FormHandle);
  F.FormStyle := fsNormal;

  B := TButton.Create(F);
  B.Left := 5; B.Top := 5; B.Height := 50; B.Width := 50;
  B.Caption := 'Touch me!';
  B.Parent := F;

  F.ShowModal;
  F.Free;
End;

exports VitoRunPlugin;

begin
end.

表单打开正常,但没有任何效果:我既不能按下按钮,也不能关闭表单。我只能通过 Alt+F4 关闭它。

怎么了?

【问题讨论】:

  • 该按钮没有 OnClick 事件处理程序,这可能是它看起来没有响应的原因。
  • 你在DLL中试过Application.Handle := AppHandle;吗?
  • 我试过了,但没用。
  • 您确实应该将按钮的ModalResult 设置为不同于mrNone(默认值)的值。我会将AppHandle 传递给CreateParented,而不是FormHandle(或者在设置Application.Handle 后直接调用Create(Application))。
  • 设置合适的FormStyle或重新启用windows链qc.embarcadero.com/wc/qcmain.aspx?d=108580

标签: delphi dll delphi-xe2


【解决方案1】:

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

将表单创建更改为:

F := TForm.Create(nil);

为了使表单拥有正确的所有者(这里我的意思是owner in the Win32 sense),您可能需要覆盖CreateParams,如下所示:

procedure TMyForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.WndParent := FormHandle;
end;

显然,您需要声明一个派生的 TMyForm 类,添加一些管道以允许其覆盖的 CreateParams 方法获得对所有者表单句柄的访问权限。

如果您希望按钮执行某项操作,则需要对其进行编码。要么是 OnClick 事件处理程序,要么设置按钮的 ModalResult 属性。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-02
  • 1970-01-01
  • 2018-04-19
  • 2012-12-10
相关资源
最近更新 更多