Delphi从DLL中打开模态窗体 [英] Delphi open modal form from DLL

查看:160
本文介绍了Delphi从DLL中打开模态窗体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to add some plugin functionality to application, and ability to dynamically load and open plugins.

在我的应用程序(主窗体)中,我有以下代码:

In my application (in main form), I have following code:

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;

我的插件库(仅用于测试):

And my plugin library is (just for testing now):

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关闭它。

The form opening OK, but nothing working: I can't neither press the button, nor close the form. I can only close it by Alt+F4.

有什么问题?

推荐答案

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

CreateParented makes the form be a child window. And you cannot show a child window modally. So, who knows what happens when your form is shown? I'm sure I cannot predict what happens when you pass a VCL form window handle to the CreateParented constructor of another VCL form.

将表单创建更改为如下所示:

Change the form creation to be like so:

F := TForm.Create(nil);

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

In order to make the form have the right owner (and here I mean owner in the Win32 sense), you may need to override CreateParams as follows:

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

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

Obviously you'll need to declare a derived TMyForm class add some plumbing to allow its overridden CreateParams method to gain access to the owner form handle.

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

If you want the button to do something, you need to code that. Either an an OnClick event handler, or set the button's ModalResult property.

这篇关于Delphi从DLL中打开模态窗体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆