And*_*rey 5 delphi dll delphi-xe2
我需要向应用程序添加一些插件功能,以及动态加载和打开插件的能力。
在我的应用程序(主窗体)中,我有以下代码:
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;
Run Code Online (Sandbox Code Playgroud)
我的插件库是(现在仅用于测试):
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.
Run Code Online (Sandbox Code Playgroud)
表单打开正常,但没有任何作用:我既无法按下按钮,也无法关闭表单。我只能按Alt+F4关闭它。
怎么了?
CreateParented使窗体成为子窗口。并且您无法以模态方式显示子窗口。那么,谁知道当您的表单显示时会发生什么?我确信我无法预测当您将 VCL 表单窗口句柄传递给另一个 VCL 表单的构造函数时会发生什么CreateParented。
将表单创建更改为如下所示:
F := TForm.Create(nil);
Run Code Online (Sandbox Code Playgroud)
为了使表单拥有正确的所有者(这里我指的是Win32 意义上的所有者),您可能需要CreateParams按如下方式重写:
procedure TMyForm.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WndParent := FormHandle;
end;
Run Code Online (Sandbox Code Playgroud)
显然,您需要声明一个派生TMyForm类,添加一些管道,以允许其重写的CreateParams方法访问所有者表单句柄。
如果您希望按钮执行某些操作,则需要编写代码。可以是事件处理程序OnClick,也可以设置按钮的ModalResult属性。