Home > Software design >  What is the API to close another application by the app's handle?
What is the API to close another application by the app's handle?

Time:09-06

I use ShellExecuteEx to open a MS Word document and get its handle. How can I use the handle to close the document? Thanks?

CodePudding user response:

You can connect to running MSWORD COM object and use the API to find the document you want to close and close it using the same API. Here an simple example showing how to close the active document:

unit VclWordComObjectDemoMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
  System.Win.ComObj, Word_TLB;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    MsWord: _Application;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
    SaveChanges    : OleVariant;
    OriginalFormat : OleVariant;
    RouteDocument  : OleVariant;
begin
    try
        MsWord := GetActiveOleObject('Word.Application') as _Application;
    except
        Memo1.Lines.Add('Word is not already open or no document is open.');
        Exit;
    end;
    Memo1.Lines.Add('Connected to Word.');
    SaveChanges    := wdDoNotSaveChanges;
    OriginalFormat := EmptyParam;
    RouteDocument  := EmptyParam;
    MsWord.ActiveDocument.Close(SaveChanges,
                                OriginalFormat,
                                RouteDocument);
end;

end.

Word_TLB is obtained by importing Microsoft Word type library (Delphi / Menu / Component / Import component / Import a type library. Then select Microsoft Word in the list of type libraries. Then select Create a unit and add it to your project.

CodePudding user response:

You can save the windows handle to a global variable, and then use the 'TerminateProcess' to terminate whatever you have executed.

Try this code for example:

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, ShellApi;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
      SEInfo: TShellExecuteInfo;
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);

var
  ExecuteFile: string;
  //ParamString, StartInString: string;
begin
  ExecuteFile:='C:\Windows\System32\notepad.exe';
  FillChar(SEInfo, SizeOf(SEInfo), 0);
  SEInfo.cbSize := SizeOf(TShellExecuteInfo);
  with SEInfo do
  begin
    fMask := SEE_MASK_NOCLOSEPROCESS;
    Wnd := Application.Handle;
    lpFile := PChar(ExecuteFile);
    //lpParameters := PChar(ParamString);
      {ParamString can contain the application parameters.}
    //lpDirectory := PChar(StartInString);
      {StartInString specifies the name of the working directory.
      If ommited, the current directory is used.}
    nShow := SW_SHOWNORMAL;
  end;
  if ShellExecuteEx(@SEInfo) then
  begin
    ShowMessage('Notepad started.');
  end
  else
    ShowMessage('Error starting Notepad!');

end;

procedure TForm2.Button2Click(Sender: TObject);
begin
  TerminateProcess(SEInfo.hProcess,0);
end;

end.
  1. You have to put 'ShellApi' to uses units.
  2. You have to declare as a global variable the 'SEInfo: TShellExecuteInfo;' where you will save the Window Handle, of the executed process.
  3. Button1 will start the notepad.exe process.
  4. Button2 will terminate the notepad.exe process you have opened with button1 (not the other notepad.exe processes you may have open to this computer)
  • Related