1. create a new unit utils.pas:
unit utils;
interface
uses
Controls, Graphics, StdCtrls, ExtCtrls, ComCtrls, Buttons, Dialogs, Classes,
SysUtils, Windows, ShellApi, Forms;
procedure CloseMessage (process_id : Cardinal);
// get proc id
function RunCommandEx (const Cmd, Params: String) : Cardinal;
// get handle
function ExecApplication(APPName, CmdLine: String; out proc_id : Cardinal): Cardinal;
// for use with ExecApplication
function GetHandles(ThreadID: Cardinal): Cardinal;
var
WindowList: TList;
function GetWindow (Handle: Cardinal; LParam: longint): bool; stdcall;
implementation
function GetWindow (Handle: Cardinal; LParam: longint): bool; stdcall;
begin
Result := true;
WindowList.Add (Pointer (Handle));
end;
function ExecApplication(APPName, CmdLine: String; out proc_id : Cardinal): Cardinal;
var
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
process_id : Cardinal;
begin
FillChar(StartInfo, SizeOf(StartInfo), 0);
StartInfo.cb:=SizeOf(StartInfo);
StartInfo.dwFlags:=STARTF_USESHOWWINDOW;
StartInfo.wShowWindow:=SW_Show;
if AppName <> '' then
CreateProcess(PChar(APPName), PChar(CmdLine), nil, nil, False, 0, nil, nil,
StartInfo, ProcInfo);
Sleep(500);
process_id := ProcInfo.dwProcessId;
proc_id := ProcInfo.hProcess;
Result := GetHandles(process_id);
// CloseHandle (ProcInfo.hProcess);
CloseHandle (ProcInfo.hThread );
end;
function GetHandles(ThreadID: Cardinal): Cardinal;
var
i: integer;
hnd : Cardinal;
cpid : DWord;
begin
Result:=0;
WindowList := TList.Create;
EnumWindows (@GetWindow, 0);
for i := 0 to WindowList.Count - 1 do
begin
hnd := HWND (WindowList [i]);
GetWindowThreadProcessID (hnd, @cpid);
if ThreadID = CPID then
begin
Result := hnd;
Exit;
end;
end;
WindowList.Free;
end;
procedure CloseMessage (process_id : Cardinal);
var
StatusCode : Cardinal;
begin
if process_id > 0 then
begin
if GetExitCodeProcess (process_id, StatusCode) then
begin
if StatusCode = STILL_ACTIVE then
TerminateProcess (process_id, StatusCode);
CloseHandle (process_id);
end;
end;
end;
function RunCommandEx (const Cmd, Params: String) : Cardinal;
var
SEI: TShellExecuteInfo;
begin
result := 0;
//Fill record with zero byte values
FillChar(SEI, SizeOf(SEI), 0);
// Set mandatory record field
SEI.cbSize := SizeOf(SEI);
// Ask for an open process handle
SEI.fMask := see_Mask_NoCloseProcess;
// Tell API which window any error dialogs should be modal to
SEI.Wnd := Application.Handle;
//Set up command line
SEI.lpFile := PChar(Cmd);
if Length (Params) > 0 then
SEI.lpParameters := PChar(Params);
SEI.nShow := sw_ShowNormal;
// Try and launch child process. Raise exception on failure
if not ShellExecuteEx(@SEI) then
Abort;
// Wait until process has started its main message loop
WaitForInputIdle(SEI.hProcess, Infinite);
result := SEI.hProcess;
end;
end.
2. Create Window HandleNow lets get back to the main form and create two global variables,
windows_handle and proc_id, and reference utils.pas:
type
TForm1 = class(TForm)
...
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
window_handle : cardinal;
proc_id : cardinal;
implementation
{$R *.dfm}
uses
utils;
3. Use in ApplicationThe application is ran as following:
procedure TForm1.cmdRunApplicationClick(Sender: TObject);
var
app_name : string;
command_line : string;
StatusCode : Cardinal;
begin
if proc_id > 0 then
if GetExitCodeProcess (proc_id, StatusCode) then
if StatusCode = STILL_ACTIVE then
begin
MessageDlg ('Application is already loaded', mtWarning, [mbOk], 0);
exit;
end;
app_name := 'C:\WINDOWS\system32\notepad.exe';
command_line := '';
window_handle := ExecApplication (app_name, command_line, proc_id);
end;
In the code above, we run Notepad. Here windows_handle is the handle of Notepad window.4. put this on FormClose event:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseMessage (proc_id);
end;
5. Example
Here are examples of what we can do with the application's handle:
procedure TForm1.cmdDoSomethingClick(Sender: TObject);
begin
if window_handle > 0 then
SetWindowText (window_handle, PChar ('Hello')); // change title
ShowWindow (window_handle, SW_SHOW); // activate the window
PostMessage (window_handle, WM_CLOSE, 0, 0); // close the window
end;
Source : Here
0 comments:
Post a Comment