title: VCL/LCL – a form in DLL – no Application taskbar window, cannot minimize the main form
body: <p>I have one problem, and I tried to search a solution but can't achieve what I want. Sorry if that is actually simple, please just point me to correct way of how to do it.</p>
  
  <p>So! I have a C program that is a loader. It must call my DLL written in Delphi or Lazarus (Free Pascal). The DLL is actually a standalone GUI application: during debugging I conditionally compile it as EXE and it working.</p>
  
  <p>My build script compiles it as DLL with one entry point that must execute it just as it works standalone. I expect exactly the same behavior, but I can do some things different (especially setting the Application icon) if needed.</p>
  
  <p>Loader is a console-style program but compiled without a console – no windows, no anything. It just loads DLL and calls a function.</p>
  
  <p>Problem is that when I build even empty default project with one form as an EXE – it will actually have "master" Application (.Handle &lt;> 0) window in taskbar. So I can set its title independently from main form caption.</p>
  
  <p>But when the same thing is inside a DLL – there is no Application window (.Handle = 0), the title will be the form caption, but the most important bug: a form <strong>cannot</strong> be minimized!</p>
  
  <p>In Delphi 7 it goes background under other windows (but taskbar thing stays!); in Lazarus it just minimizes to nowhere (hided, no way to restore anymore); both without any minimizing animation.</p>
  
  <p>Other than that, my application seems to behave normally. This is only issue I have.</p>
  
  <p>OK, I know that forms in libraries is a bad thing to do, but:</p>
  
  <ol>
  <li><p>I’m fine to instantiate "another" VCL completely independent from host’s instance, maybe even in different thread.</p></li>
  <li><p>There is no VCL in my particular host application! For me, it must work exactly as it will in EXE alone…</p></li>
  </ol>
  
  <p>I searched something about Application.Handle in DLL, and now understand than I need to pass a handle to host’s Application object, so DLL will be joined with others host forms, but I have none! It’s even not Delphi… (and Application:=TApplication.Create(nil); didn’t help either)</p>
  
  <p>Anything of following will probably help me:</p>
  
  <ul>
  <li><p>A) How to instruct VCL to create a normal Application object for me? How it does it when in EXE, maybe I can copy that code?</p></li>
  <li><p>B) How to create a suitable master window from C (proper styles, etc.) to pass it’s handle to DLL? Also, I believe, in Free Pascal there is no direct access to TApplication handle value, so I couldn’t probably assign it.</p></li>
  <li><p>C) How to live without a taskbar window, but have my form (good news: my program has only one form!) to minimize correctly (or just somehow…)?</p></li>
  </ul>
  
  <p>I now you all love to see some code, so here it is:</p>
  
  <pre class="lang-delphi prettyprint-override"><code>// default empty project code, produces valid working EXE:
  program Project1;
  
  uses Forms, Unit1 in 'Unit1.pas' {Form1};
  {$R *.res}
  
  begin
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  end.
  </code></pre>
  
  <p>+</p>
  
  <pre class="lang-delphi prettyprint-override"><code>// that's how I tried to put it in a DLL:
  library Project1;
  
  uses Forms, Unit1 in 'Unit1.pas' {Form1};
  {$R *.res}
  
  function entry(a, b, c, d: Integer): Integer; stdcall;
  begin
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
    Result := 0;
  end;
  
  exports
    entry;
  
  begin
  end.
  </code></pre>
  
  <p>I specially crafted entry() function to be callable with rundll32, just for testing.</p>
  
  <p>Also, I tried to put the body directly to "<code>begin end.</code>" initialization section – same wrong behavior.</p>
  
  <pre class="lang-delphi prettyprint-override"><code>// To call a DLL, this can be used:
  program Project1;
  
  function entry(a, b, c, d: Integer): Integer; stdcall; external 'Project1.dll';
  
  begin
    entry(0, 0, 0, 0);
  end.
  </code></pre>
  
  <p>Also, CMD-command "<code>rundll32 project1.dll entry</code>" will run it instantly. (Yeah, that way I might get a handle that Rundll gives me, but it isn’t what I want anyway.)</p>
  
  <p>Last notes: (a) the DLL must be compiled in Lazarus; actually first thing I thought that it is a bug in LCL, but now when tested in Delphi7 I see the same; and since Delphi case is more simpler and robust, I decided to put here that; (b) my C loader doesn’t call LoadLibrary, it uses TFakeDLL hack (that OBJ file was tweaked to work without Delphi wrapper) and loads my DLL from memory (so I don’t have a handle to DLL itself), but otherwise their behavior is the same.</p>