gpt4 book ai didi

delphi - 为什么从 Delphi 关闭文档后 WINWORD.EXE 不退出?

转载 作者:行者123 更新时间:2023-12-03 14:42:07 26 4
gpt4 key购买 nike

我设法提炼出我的问题 How to trace _AddRef / _Release calls for OLE Automation objects 中根源的根本问题之一。在下面的单元中。

我也会回答这个答案,以防其他人遇到这个问题。

问题:使用下面的代码,为什么WINWORD.EXE总是不退出(有时确实退出)。

该装置可能还可以进一步缩小。

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.

最佳答案

回答第 1 部分:

注释掉以下事件中的断开连接:

procedure TForm2.WordApplication_DocumentBeforeClose(ASender: TObject; const Doc: _Document; var Cancel: WordBool);
begin
// FWordApplication.Disconnect;
end;

该事件将在 DocumentClose(...) 方法期间调用,然后从 FWordApplication 实例断开连接并删除 OLE 接口(interface)。

我还没有弄清楚哪个引用是悬空的,但这在大多数情况下有效地使 WINWORD.EXE 保持事件状态。

回答第 2 部分:

有时 WINWORD.EXE 确实会退出,因为未调用 WordApplication_DocumentBeforeClose 事件。原因是代码运行速度太快,以至于 Word 尚未完全初始化以执行该事件。

关于delphi - 为什么从 Delphi 关闭文档后 WINWORD.EXE 不退出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16753330/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com