title: Why doesn't WINWORD.EXE quit after Closing the document from Delphi?
body: <p>I managed to distill one of the underlying issues rooted in my question <a href="https://stackoverflow.com/questions/16749191/how-to-trace-addref-release-calls-for-ole-automation-objects?noredirect=1#comment24129910_16749191">How to trace _AddRef / _Release calls for OLE Automation objects</a> in the unit below.</p>
  
  <p>I'll answer this answer too, just in case anyone else bumps into this.</p>
  
  <p>The question: with the below code, why doesn't WINWORD.EXE always quit (sometimes it does quit).</p>
  
  <p>The unit can probably be trimmed down even more.</p>
  
  <pre><code>unit Unit2;
  
  interface
  
  uses
    Winapi.Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
    Forms, Dialogs, StdCtrls,
    WordXP;
  
  type
    TForm2 = class(TForm)
      WordXPFailsToQuitButton: TButton;
      procedure WordXPFailsToQuitButtonClick(Sender: TObject);
    private
      FWordApplication: TWordApplication;
    strict protected
      function GetWordApplication: TWordApplication; virtual;
      function GetWordApplication_Documents: Documents; virtual;
      procedure WordApplication_DocumentBeforeClose(ASender: TObject; const Doc: _Document; var Cancel: WordBool); virtual;
      procedure WordApplication_Quit(Sender: TObject); virtual;
      property WordApplication: TWordApplication read GetWordApplication;
      property WordApplication_Documents: Documents read GetWordApplication_Documents;
    end;
  
  var
    Form2: TForm2;
  
  implementation
  
  uses
    Vcl.OleServer;
  
  {$R *.dfm}
  
  function TForm2.GetWordApplication: TWordApplication;
  begin
    if not Assigned(FWordApplication) then
    begin
      FWordApplication := TWordApplication.Create(nil);
  
      FWordApplication.AutoConnect := False;
      FWordApplication.AutoQuit := False;
      FWordApplication.ConnectKind := ckNewInstance;
      FWordApplication.OnDocumentBeforeClose := WordApplication_DocumentBeforeClose;
      FWordApplication.OnQuit := WordApplication_Quit;
      FWordApplication.Connect;
    end;
    Result := FWordApplication;
  end;
  
  function TForm2.GetWordApplication_Documents: Documents;
  begin
    Result := WordApplication.Documents;
    if not Assigned(Result) then
      raise EAccessViolation.Create('WordApplication.Documents');
  end;
  
  procedure TForm2.WordXPFailsToQuitButtonClick(Sender: TObject);
  begin
    try
      WordApplication_Documents.Add(EmptyParam, EmptyParam, EmptyParam, EmptyParam);
      WordApplication.Visible := True;
      WordApplication.ActiveDocument.Close(False, EmptyParam, EmptyParam);
    finally
      WordApplication.OnQuit := nil;
      WordApplication.OnDocumentBeforeClose := nil;
      WordApplication.AutoQuit := True;
      WordApplication.Disconnect;
      WordApplication.Free;
      FWordApplication := nil;
    end;
  end;
  
  procedure TForm2.WordApplication_DocumentBeforeClose(ASender: TObject; const Doc: _Document; var Cancel: WordBool);
  begin
    FWordApplication.Disconnect;
  end;
  
  procedure TForm2.WordApplication_Quit(Sender: TObject);
  begin
    FWordApplication.Disconnect;
  end;
  
  end.
  </code></pre>