excel 退出问题(100分)

  • 主题发起人 主题发起人 greengao
  • 开始时间 开始时间
G

greengao

Unregistered / Unconfirmed
GUEST, unregistred user!
用以下方式excel退出时,excel进程还存在?怎么解决?
unit Unt_callexcel;

interface
uses
Windows, Classes, ActiveX, Excel97, ComObj, Variants,SysUtils;
type
TExcelEventSink = class(TInterfacedObject, IUnknown, IDispatch)
private
FOwner : TObject;
FAppDispatch: IDispatch;
FBookDispatch: IDispatch;
FAppDispIntfIID: TGUID;
FBookDispIntfIID: TGUID;
FAppConnection: Integer;
FBookConnection: Integer;
FOnQuit : TNotifyEvent;
FOnWorkBookChange : TNotifyEvent;
FOnNewWorkBook : TNotifyEvent;
FOnOpenWorkBook : TNotifyEvent;
FOnCloseWorkBook : TNotifyEvent;
protected
{ IUnknown }
function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
{ IDispatch }
function GetTypeInfoCount(out Count: Integer): HRESULT; stdcall;
function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HRESULT; stdcall;
function GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HRESULT; stdcall;
function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HRESULT; stdcall;
public
constructor Create(AnOwner: TObject; AnAppDispatch: IDispatch; const AnAppDispIntfIID, ABookDispIntfIID: TGUID);
destructor Destroy; override;
property OnQuit : TNotifyEvent read FOnQuit write FOnQuit;
property OnWorkBookChange : TNotifyEvent read FOnWorkBookChange write FOnWorkBookChange;
property OnNewWorkBook : TNotifyEvent read FOnNewWorkBook write FOnNewWorkBook;
property OnOpenWorkBook : TNotifyEvent read FOnOpenWorkBook write FOnOpenWorkBook;
property OnCloseWorkBook : TNotifyEvent read FOnCloseWorkBook write FOnCloseWorkBook;
end;


(*-----------Excel--------------*)
TExcelObject = class
private
FLCID:integer;
FExcelApp : olevariant;
FEventSink : TExcelEventSink;
function GetActiveName : String;
function GetCaption : String;
procedure SetCaption(Value : String);
function GetVisible : Boolean;
procedure SetVisible(Value : Boolean);
function GetOnQuit : TNotifyEvent;
procedure SetOnQuit(Value : TNotifyEvent);
function GetOnCloseWorkBook : TNotifyEvent;
procedure SetOnCloseWorkBook(Value : TNotifyEvent);
public
constructor Create;
destructor Destroy; override;
procedure OpenExcel(Template : String);
procedure NewExcel(Template : String);
procedure save;
procedure Saveas(Template : String);
procedure close;
procedure Preview;
published
property ActiveName: string read GetActiveName;
property Caption : String read GetCaption write SetCaption;
property Visible : Boolean read GetVisible write SetVisible;
property OnQuit : TNotifyEvent read GetOnQuit write SetOnQuit;
property OnCloseWorkBook : TNotifyEvent read GetOnCloseWorkBook write SetOnCloseWorkBook;
end;


implementation

{ TExcelEventSink }

function TExcelEventSink._AddRef: Integer;
begin
// Skeleton implementation
Result := 2;
end;

function TExcelEventSink._Release: Integer;
begin
// Skeleton implementation
Result := 1;
end;

constructor TExcelEventSink.Create(AnOwner: TObject;
AnAppDispatch: IDispatch; const AnAppDispIntfIID,
ABookDispIntfIID: TGUID);
begin
inherited Create;

FOwner := AnOwner;
FAppDispIntfIID := AnAppDispIntfIID;
FBookDispIntfIID := ABookDispIntfIID;
FAppDispatch := AnAppDispatch;

// Hook the sink up to the automation server (Excel97)
InterfaceConnect(FAppDispatch,FAppDispIntfIID,Self,FAppConnection);
end;

destructor TExcelEventSink.Destroy;
begin
// Unhook the sink from the automation server (Excel97)
InterfaceDisconnect(FAppDispatch,FAppDispIntfIID,FAppConnection);

inherited Destroy;
end;

function TExcelEventSink.GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HRESULT;
begin
// Skeleton implementation
Result := E_NOTIMPL;
end;

function TExcelEventSink.GetTypeInfo(Index, LocaleID: Integer;
out TypeInfo): HRESULT;
begin
// Skeleton implementation
Result := E_NOTIMPL;
end;

function TExcelEventSink.GetTypeInfoCount(out Count: Integer): HRESULT;
begin
// Skeleton implementation
Count := 0;
Result := S_OK;
end;

function TExcelEventSink.Invoke(DispID: Integer; const IID: TGUID;
LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo,
ArgErr: Pointer): HRESULT;
begin
// Fire the different event handlers when
// the different event methods are invoked
case DispID of
1569 : if Assigned(FOnQuit) then
FOnQuit(FOwner);
1564 : begin
if Assigned(FOnWorkBookChange) then
FOnWorkBookChange(FOwner);
// When we see a document change, we also need to disconnect the
// sink from the old document, and hook it up to the new document
InterfaceDisconnect(FBookDispatch,FBookDispIntfIID,FBookConnection);
try
FBookDispatch := _Application(FAppDispatch).ActiveWorkBook;
InterfaceConnect(FBookDispatch,FBookDispIntfIID,Self,FBookConnection);
except;
end;
end;
1565 : if Assigned(FOnNewWorkBook) then
FOnNewWorkBook(FOwner);
1567 : if Assigned(FOnOpenWorkBook) then
FOnOpenWorkBook(FOwner);
1570 : if Assigned(FOnCloseWorkBook) then
FOnCloseWorkBook(FOwner);
end;

Result := S_OK;
end;

function TExcelEventSink.QueryInterface(const IID: TGUID;
out Obj): HRESULT;
begin
// We need to return the two event interfaces when they're asked for
Result := E_NOINTERFACE;
if GetInterface(IID,Obj) then
Result := S_OK;
if IsEqualGUID(IID,FAppDispIntfIID) and GetInterface(IDispatch,Obj) then
Result := S_OK;
if IsEqualGUID(IID,FBookDispIntfIID) and GetInterface(IDispatch,Obj) then
Result := S_OK;
end;

{ TExcelObject }

procedure TExcelObject.close;
begin
FExcelApp.quit;
end;

constructor TExcelObject.Create;
begin
FLCID := GetUserDefaultLCID;
//FExcelApp := CoExcelApplication.Create;
FExcelApp := createoleobject('excel.application');
FEventSink := TExcelEventSink.Create(Self,FExcelApp,AppEvents,WorkbookEvents);
end;

destructor TExcelObject.Destroy;
var
SaveChanges,
OriginalFormat,
RouteWorkBook : OleVariant;
begin
SaveChanges := xlDoNotSaveChanges;
OriginalFormat := UnAssigned;
RouteWorkBook := UnAssigned;
try
FExcelApp.Quit;
except
end;
FEventSink := nil;
inherited Destroy;
end;

function TExcelObject.GetActiveName: String;
begin
Result := FExcelApp.ActiveWorkbook.Name;
end;

function TExcelObject.GetCaption: String;
begin
Result := FExcelApp.Caption;
end;

function TExcelObject.GetOnCloseWorkBook: TNotifyEvent;
begin
Result := FEventSink.OnCloseWorkBook;
end;

function TExcelObject.GetOnQuit: TNotifyEvent;
begin
Result := FEventSink.OnQuit;
end;

function TExcelObject.GetVisible: Boolean;
begin
Result := FExcelApp.Visible;
end;

procedure TExcelObject.NewExcel(Template: String);
begin
try
if fileexists(Template) then deletefile(Template);
except
end;
FExcelApp.Workbooks.Add;
FExcelApp.ActiveWorkbook.SaveAs(Template);
end;

procedure TExcelObject.OpenExcel(Template: String);
begin
FExcelApp.workbooks.open(Template);
end;

procedure TExcelObject.Preview;
begin
FExcelApp.Visible := true;
FExcelApp.Worksheets.PrintPreview;
end;

procedure TExcelObject.save;
begin
FExcelApp.ActiveWorkbook.Save;
end;

procedure TExcelObject.Saveas(Template: String);
begin

end;

procedure TExcelObject.SetCaption(Value: String);
begin
FExcelApp.Caption := Value;
end;

procedure TExcelObject.SetOnCloseWorkBook(Value: TNotifyEvent);
begin
FEventSink.OnCloseWorkBook := Value;
end;

procedure TExcelObject.SetOnQuit(Value: TNotifyEvent);
begin
FEventSink.OnQuit := Value;
end;

procedure TExcelObject.SetVisible(Value: Boolean);
begin
FExcelApp.Visible := Value;
end;

end.
 
看这个帖子:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1296713
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1838147
 
可以先判断Excel的进程存不存在
 
直接结束进程好了。
 
这么长一段程序我没看,等你操作完后用ExcelApplication.discconnet就行了
 
同意直接杀进程,我就是这样解决的。
 
后退
顶部