title: Delphi2006 - How to create in DLL a message pump for a new window in a thread?
body: <p>I have multithreaded application that loads my custom dll.<br>
  In this dll I need to create a window.<br>
  I'm doing it by creating new thread and inside it I'm trying to create this window, but I have got error that tells me: <code>EInvalidOperation - Canvas does not allow drawing</code>.  </p>
  
  <p>By searching in the net, I have discovered that I need custom message pump for that thread.<br>
  So, my question is, how properly do this?  </p>
  
  <p>What I do now is:<br>
  - external app is loading dll<br>
  - than this app in separte thread is calling <code>Init</code> function from dll<br>
  - <code>Init</code> function creates thread<br>
  - <code>TMyThread</code> is declared as:  </p>
  
  <pre><code>type
    TMyThread = class(TThread)
    private
      Form: TMyForm;
      FParentHWnd: HWND;
      FRunning: Boolean;
    protected
      procedure Execute; override;
    public
      constructor Create(parent_hwnd: HWND); reintroduce;
    end;
  
  constructor TMyThread.Create(parent_hwnd: HWND);
  begin
    inherited Create(False); // run after create
    FreeOnTerminate:=True;
    FParentHWnd:=parent_hwnd;
    FRunning:=False;
  end;
  
  procedure TMyThread.Execute;
  var
    parent_hwnd: HWND;
    Msg: TMsg;
    XRunning: LongInt;
  begin
    if not Terminated then begin
      try
        try
          parent_hwnd:=FParentHWnd;
  
          Form:=TMyForm.Create(nil); // &lt;-- here is error
          Form.Show;
  
          FRunning:=True;
  
          while FRunning do begin
            if PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) then begin
              if Msg.Message &lt;&gt; WM_QUIT then
                Application.ProcessMessages
              else
                break;
            end;
            Sleep(1);
            XRunning:=GetProp(parent_hwnd, 'XFormRunning');
            if XRunning = 0 then
              FRunning:=False;
          end;
        except
          HandleException; // madExcept
        end;
      finally
        Terminate;
      end;
    end;
  end;
  </code></pre>
  
  <p>The exception <code>EInvalidOperation - Canvas does not allow drawing</code> is fired before thread reaches my existing message pump code.  </p>
  
  <p>What do I do wrong or what is the right way to make it work?<br>
  Thanks for any help.</p>
  
  <hr>
  
  <p>To create second GUI thread in a DLL, I must do things exactly as in standard application.<br>
  Can anyone confirm my thinking?  </p>
  
  <p>In the DLL <code>begin...end.</code> section I do:  </p>
  
  <pre><code>begin
    Application.CreateForm(THiddenForm, HiddenForm);
    Application.Run;
  end.
  </code></pre>
  
  <p>In the <code>TMyThread.Execute</code> I must do:</p>
  
  <pre><code>procedure TMyThread.Execute;
  begin
    if not Terminated then begin
      try
        try
          Application.CreateForm(TMyForm, Form);
  
          ???? how to make a thread that has remained in this place until you close this window ???
        except
          HandleException; // madExcept
        end;
      finally
        Terminate;
      end;
    end;
  end;
  </code></pre>
  
  <p>Is this the right way? Could it be that simple?</p>