Запустить приложение и получить дескриптор окна

Vadik(R)

Well-known member
12.12.2007
469
0
#1
Здраствуйте, уважаемые форумчане!
Мне требуется запустить из своей программы ещё какую-то программу и получить дескриптор её окна. Только не пойму как сделать. Вот, что пытался:
Код:
procedure TForm1.Timer1Timer(Sender: TObject);
Var
H : HWND;
begin
H:=ShellExecute(Handle, PChar('open'), PChar('http://www.yandex.ru/'), Nil, Nil, SW_SHOWNORMAL);
DestroyWindow(H);
end;
И так пробовал:
Код:
procedure TForm1.Timer1Timer(Sender: TObject);
Var
H : HWND;
begin
H:=WinExec('explorer.exe http://www.yandex.ru/', SW_SHOWNORMAL);
DestroyWindow(H);
end;
Дестрой я делал для того, что бы узнать правильно ли я получил дескриптор или нет. Как оказалось - нет, так как IE с Яндексом не закрывается.
Знаю, что ещё есть функция CreateProcess, но с ней ни разу не работал, там слишком много параметров.
В общем, вопрос всё тот же: как запустить программу и получить дескриптор её окна?
 
S

Silver Wind

#2
И ShellExecute, и WinExec возвращают код ошибки (расшифровку смотри в help`е) или 0, если все в порядке, но никак не дескриптор окна. Более того запущенная программа может вообще не иметь окна.
Знаю, что ещё есть функция CreateProcess, но с ней ни разу не работал, там слишком много параметров.
Вот с ней как раз таки советую разобраться на будущее, примеров хватает, все равно ShellExecute и WinExec сводятся к ее вызову. А дополнительные параметры еще пригодятся :(

Т.о. запускайте программу любым из перечисленных способов. А вот для поиска окна воспользуйтесь FindWindow.
Для закрытия приложения найденному окну можно послать сообщение WM_CLOSE.

Еще вариант - воспользоваться всетаки CreateProcess для создания процесса, а для завершения TerminateProcess.
 
Z

zubr

#3
Если хендл нужен для закрытия окна, то действительно лучше воспользоваться TerminateProcess, запуская программу с помощью CreateProcess. А если все таки нужен хендл окна (для других целей), то вот тебе вариант:
Код:
unit New;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

var
SearchHandle:HWND;

function EnumProc(h:HWND; lParam:DWord):boolean; stdcall;
var
ProcessId, z:cardinal;
begin
Result:=True;
GetWindowThreadProcessId(h, ProcessId);
If ProcessId=lParam then
begin
SearchHandle:=h;
Result:=False;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
si:STARTUPINFO;
pi:PROCESS_INFORMATION;
buf:array[1..100] of char;
begin
ZeroMemory(@si, sizeof(si));
si.cb:=SizeOf(si);
CreateProcess(nil, 'Путь к экзешнику\MyExe.exe', nil, nil, false,
0, nil, nil, si, pi);
SearchHandle:=0;
While SearchHandle=0 do
begin
EnumWindows(@EnumProc, pi.dwProcessId);
Application.ProcessMessages;
end;
SendMessage(SearchHandle, WM_CLOSE, 0, 0);
end;

end.
Сообщение WM_CLOSE, также как и WM_DESTROY будет работать не с любой программой. Так что для проверки лучше сделай свою программку.
 

Vadik(R)

Well-known member
12.12.2007
469
0
#5
CreateProcess - конечно, обалденная вещь, но вот пока не пойму:
Код:
...
si.cb:=SizeOf(si);
si.wShowWindow:=SW_HIDE;
si.cb:=SizeOf(si);
CreateProcess(nil, 'MyExe.exe', nil, nil, false, 0, nil, nil, si, pi);
...
Почему приложение всё равно запускается не в скрытом режиме?
P. S. Хотелось бы узнать, как запускать приложения в другом оконном режиме, но только с использованием CreateProcess, то есть без ShellExecute и WinExec.
 
Z

zubr

#6
wShowWindow
If dwFlags specifies STARTF_USESHOWWINDOW, this member can be any of the SW_ constants defined in Winuser.h. Otherwise, this member is ignored.
For GUI processes, wShowWindow specifies the default value the first time ShowWindow is called. The nCmdShow parameter of ShowWindow is ignored. In subsequent calls to ShowWindow, the wShowWindow member is used if the nCmdShow parameter of ShowWindow is set to SW_SHOWDEFAULT.