如何从控制台应用程序中显示一个dll文件的表单?

时间:2016-01-30 17:49:51

标签: delphi

我有一个包含多个表单的dll。

我在控制台应用程序中引用了加载此dll的主要功能。

然后,我的麻烦是,当执行dll的功能时,表单不会出现,并且执行dll文件和load.exe(调用此dll的控制台应用程序)都是相应的最终确定。

那么,如何解决这个问题?

这是我的代码:

Dll(主要部分)

library DLL;

uses
  System.SysUtils,
  Connect,
  Classes;

{$R *.res}

procedure ShowDllForm;stdcall;
begin
  Form1 :=TForm1.Create(nil);
  Form1.Show;
end;

exports
 ShowDllForm;

begin
end.

控制台应用程序(load.exe)(调用此dll文件)

var
  Msg: TMsg;

  procedure ShowDllForm;stdcall;
    external 'DLL.dll' name 'ShowDllForm';

begin
 CoInitialize(nil);

  ShowDllForm;

while integer(GetMessage(Msg, 0, 0, 0)) = 0 do begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;

 CoUninitialize;
end.

而且,如果可能的话,我想知道如何在隐藏模式下在dll文件中执行主窗体。

1 个答案:

答案 0 :(得分:2)

您的消息循环立即终止。处理WM_QUIT时返回值0。所以永远不会输入循环。返回值的含义在文档中清楚地说明。

消息循环应该是:

while GetMessage(Msg, 0, 0, 0) do begin
  TranslateMessage(Msg);
  DispatchMessage(Msg);
end;

GetMessage返回的非零值表示存在要处理的消息且尚未处理WM_QUIT

如果您希望进程终止,那么当表单关闭时,您还需要安排DLL发布退出消息。

即便如此,这可能会有问题。 VCL期望消息由VCL代码提供。可能会有奇怪的故障。如果是我,我将消息循环放在DLL代码中。实际上,我建议在那里调用ShowModal并从主机中删除消息循环。

procedure ShowDllForm; stdcall;
begin
  Form1 := TForm1.Create(nil);
  try
    Form1.ShowModal;
  finally
    FreeAndNil(Form1);
  end;
end;

主机可以调用该函数,不需要消息循环。因为ShowModal运行模态消息循环。