简体   繁体   English

在 TThread 上创建 MainForm

[英]Creating MainForm on a TThread

I have a Delphi 2010 application that exports a DLL and has the library header.我有一个 Delphi 2010 应用程序,它导出一个 DLL 并拥有library header。 It creates its MainForm in a TThread, like so:它在 TThread 中创建 MainForm,如下所示:

var
  ActiveThread: TActive;
  
type
  TActive= class(TThread)
  protected
    procedure Execute; override;
  end;

procedure TActive.Execute;
begin
      Application.Initialize;
      Application.CreateForm(MyForm, form);
      Application.Run;
end;

begin
  ActiveThread := TActive.Create(true);
  ActiveThread.FreeOnTerminate := true;
  ActiveThread.Resume;
end.

Whenever I load this DLL through the LoadLibrary function, the application runs fine.每当我通过LoadLibrary function 加载此 DLL 时,应用程序运行良好。 (Apparently it uses the thread that I passed to LoadLibrary as the main thread and has no issues) (显然它使用我传递给LoadLibrary的线程作为主线程并且没有问题)

But if I attempt to export this DLL to an actual EXE, by changing the generated output in Options -> Application.但是,如果我尝试将此 DLL 导出到实际的 EXE,请通过在选项 -> 应用程序中更改生成的 output。 and changing the header from library to program and then build it and execute the output EXE instead of loading the DLL through the windows api, the application hangs when attempting to create the form, specifically at Application.CreateForm(MyForm, form); and changing the header from library to program and then build it and execute the output EXE instead of loading the DLL through the windows api, the application hangs when attempting to create the form, specifically at Application.CreateForm(MyForm, form); . . If I remove the Application initialization from the thread and place it on the main routine, it runs just fine.如果我从线程中删除应用程序初始化并将其放在主例程中,它运行得很好。

The form I'm trying to render is just an empty form.我试图呈现的表单只是一个空表单。 Any ideas?有任何想法吗?

When compiling this code as a program , at runtime it will try to terminate itself when end.当将此代码编译为program时,在运行时它将尝试在结束时自行end. is reached, before the worker thread even has a chance to run, which could possibly (and likely) happen after the Application object has been destroyed.在工作线程甚至有机会运行之前达到,这可能(并且很可能)在Application object 被销毁之后发生。 You would have to wait for the worker thread to finish its work before letting the program exit, eg:在让程序退出之前,您必须等待工作线程完成其工作,例如:

program MyProgram;

uses
  Classes, Forms, MyForm;

type
  TActive = class(TThread)
  protected
    procedure Execute; override;
  end;

procedure TActive.Execute;
begin
  Application.Initialize;
  Application.CreateForm(TMyForm, MyForm);
  Application.Run;
end;

var
  ActiveThread: TActive;
begin
  ActiveThread := TActive.Create(False);
  ActiveThread.WaitFor;
  ActiveThread.Free;
end.

But, there is really no good reason to ever use a worker thread like this, this defeats the whole purpose of using a thread, so you may as well just get rid of it altogether:但是,真的没有充分的理由使用这样的工作线程,这违背了使用线程的全部目的,所以你不妨干脆完全摆脱它:

program MyProgram;

uses
  Forms, MyForm;

begin
  Application.Initialize;
  Application.CreateForm(TMyForm, MyForm);
  Application.Run;
end.

On the other hand, if you are trying to share common code between program and library projects, then you can wrap the Application code inside of a function and let the project decide which thread calls the function, eg:另一方面,如果您尝试在programlibrary项目之间共享公共代码,那么您可以将Application代码包装在 function 中,让项目决定哪个线程调用 function,例如:

unit MyApp;

interface

procedure RunMyApp;

implementation

uses
  Forms, MyForm;

procedure RunMyApp;
begin
  Application.Initialize;
  Application.CreateForm(TMyForm, MyForm);
  Application.Run;
end;

end.
program MyProgram;

uses
  MyApp;

begin
  RunMyApp;
end.
library MyLibrary

uses
  Classes, MyApp;
  
type
  TActive = class(TThread)
  protected
    procedure Execute; override;
  end;

procedure TActive.Execute;
begin
  RunMyApp;
end;

var
  ActiveThread: TActive;
begin
  ActiveThread := TActive.Create(True);
  ActiveThread.FreeOnTerminate := True;
  ActiveThread.Resume;
end.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM