2013-05-25 11 views
8

Aşağıdaki ünitedeki How to trace _AddRef/_Release calls for OLE Automation objects sorusundaki temel sorunlardan birini ayırmayı başardım.WINWORD.EXE belgeyi Delphi'den kapattıktan sonra neden çıkmıyor?

Bu cevabı da yanıtlayacağım, sadece başka birinin buna çarpması durumunda.

Soru: Aşağıdaki kodla, neden WINWORD.EXE her zaman çalışmıyor (bazen işi bırakıyor).

Ünite muhtemelen daha da fazla kırpılabilir.

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. 

cevap

6

Cevap bölüm 1:

olay DocumentClose (...) yöntemiyle sırasında çağrılacak

procedure TForm2.WordApplication_DocumentBeforeClose(ASender: TObject; const Doc: _Document; var Cancel: WordBool); 
begin 
// FWordApplication.Disconnect; 
end; 
, sonra da çıkartıp silin: Aşağıdaki olay kesmek dışarı

Yorum FWordApplication örneğinden OLE arabirimi.

Henüz hangi referansın sarktığını çözmedim, ancak bu WINWORD.EXE dosyasını çoğu zaman canlı tutuyor.

Cevap bölüm 2:

ayak WordApplication_DocumentBeforeClose olay olarak adlandırılır, çünkü bazen WINWORD.EXE çıkın gelmez. Bunun nedeni, kodun o kadar hızlı çalıştığıdır ki, Word, olayı gerçekleştirmek için henüz tam olarak başlatılmadı.

İlgili konular