title: Delphi and threads: "System Error. Code: 1400. Invalid window handle"
body: <p>Being kinda new to threading I'm running into an issue:</p>
  
  <p>I've built a small wrapper for Synapse THTTPSend object to handle Async calls through means of a thread. All seems to go well until I exit the application and get this error (using madExcept exceptions handler) "System Error. Code: 1400. Invalid window handle."</p>
  
  <pre><code>main thread ($2d00):
  0047f931 +091 x.exe  System.SysUtils          RaiseLastOSError
  0047f88e +00e x.exe  System.SysUtils          RaiseLastOSError
  006198c4 +064 x.exe  Vcl.Controls             TWinControl.DestroyWindowHandle
  0061674c +0dc x.exe  Vcl.Controls             TWinControl.Destroy
  0067487b +05b x.exe  Vcl.ComCtrls             TTabSheet.Destroy
  00616781 +111 x.exe  Vcl.Controls             TWinControl.Destroy
  00673218 +0b8 x.exe  Vcl.ComCtrls             TCustomTabControl.Destroy
  0067529c +06c x.exe  Vcl.ComCtrls             TPageControl.Destroy
  00616781 +111 x.exe  Vcl.Controls             TWinControl.Destroy
  0073d95e +06e x.exe  Vcl.Forms                TScrollingWinControl.Destroy
  0073f5d2 +1e2 x.exe  Vcl.Forms                TCustomForm.Destroy
  0040b2d5 +015 x.exe  System                   TObject.Free
  005a034e +08e x.exe  System.Classes           TComponent.DestroyComponents
  0073be06 +046 x.exe  Vcl.Forms                DoneApplication
  00472520 +030 x.exe  System.SysUtils          DoExitProc
  0040e0d9 +079 x.exe  System                   @Halt0
  </code></pre>
  
  <p>I've tracked this down to accessing a listview, it goes like this:</p>
  
  <ul>
  <li>GUI calls a proc in my wrapper and assigns a callback method  </li>
  <li>Wrapper creates a thread and sets a callback    </li>
  <li>Thread does its job (http post) then calls the wrapper's callback    </li>
  <li>Wrapper's callback triggers another callback in the GUI which then updates some items in a listview</li>
  </ul>
  
  <p>If I skip that listview part the error never happens, so I think something may be wrong in my thread code that messes up with the vcl/gui, probably cause it's still running while the VCL is being accessed? If I check the listview there is something very odd with it after the thread ends, sometimes the listview isn't even visible, or the added items aren't clickable.</p>
  
  <p>Listview part</p>
  
  <pre><code>procedure Tx.AddLog(url,DelURL: string);
  begin
    if Settings.OptEnableLogging.Checked then begin
      With UploadsForm.ListView1.Items.Add do begin
        Caption := DateTimeToStr(Now);
        SubItems.Add(OriginalFilename);
        SubItems.Add(url);
        SubItems.Add('');
        SubItems.Add(DelURL);
      end;
      SaveLoggingLog;
    end;
  
      With UploadsForm.ListView2.Items.Add do begin
        Caption := DateTimeToStr(Now);
        SubItems.Add(OriginalFilename);
        SubItems.Add(url);
        SubItems.Add('');
        SubItems.Add(DelURL);
      end;
  end;
  </code></pre>
  
  <p>The thread object</p>
  
  <pre><code>type
    TMySynHTTPAsync = class(TThread)
    protected
      procedure Execute; override;
    private
      sObj: TSynHTTP;
    public
      Constructor Create(SynObj: TSynHTTP);
      Destructor Destroy; override;
  end;
  
  implementation
  
  Constructor TMySynHTTPAsync.Create(SynObj: TSynHTTP);
  begin
    inherited Create(False);
    Self.FreeOnTerminate := True;
    sObj := SynObj;
  end;
  
  Destructor TMySynHTTPAsync.Destroy;
  begin
    //
    inherited Destroy;
  end;
  
  Procedure TMySynHTTPAsync.Execute;
  begin
    With sObj do begin
      try
        case tCallType of
          thPostString: ThreadResult := sObj.Post(tURL, tPostVars);
        end;
      except
        //
      end;
      if Assigned(sObj.xOnAsyncRequestDone) then sObj.xOnAsyncRequestDone;
      FThread := nil;
    end;
  end;
  </code></pre>
  
  <p>creating the thread</p>
  
  <pre><code>FThread: TThread;
  
  procedure TSynHTTP.DoAsync;
  begin
    ThreadResult := False;
    FThread := TMySynHTTPAsync.Create(Self);
    FThread.Resume;
  end;
  </code></pre>
  
  <p>I'm guessing this is the culprit, as it goes through all the GUI processing before the thread finishes.</p>
  
  <blockquote>
    <p>if Assigned(sObj.xOnAsyncRequestDone) then sObj.xOnAsyncRequestDone;</p>
  </blockquote>
  
  <p>How could I solve this?</p>