ListBox1.Clear;
Wnd := GetWindow(Handle, gw_HWndFirst);
WHILEWnd <> 0 DO BEGIN{Hе показываем:}
IF(Wnd <> Application.Handle) AND{-Собственное окно}
IsWindowVisible(Wnd) AND{-Hевидимые окна}
(GetWindow(Wnd, gw_Owner) = 0) AND{-Дочернии окна}
(GetWindowText(Wnd, buff, sizeof(buff)) <> 0)
THEN BEGIN
GetWindowText(Wnd, buff, sizeof(buff));
ListBox1.Items.Add(StrPas(buff));
END;
Wnd := GetWindow(Wnd, gw_hWndNext);
END;
ListBox1.ItemIndex := 0;
end;
Как мне запустить какую-нибудь программу? А как подождать, пока эта программа не отработает? Как выяснить, работает ли программа или уже завершилась? Как принудительно закрыть выполняющуюся программу?
Nomadicрекомендует следующее:
A: WinExec() или ShellExecute. У второй больше возможностей.
(SO): CreateProcess() в параметре process info возвращает handle запущенного процесса. Вот и делаешь WaitForSingleObject(pi.hProcess, INFINITE);
(AA): (Win16) Delay можно взять из rxLib.
handle := WinExec( …);
ifhandle >= 32 then
while GetModuleUsage(handle) > 0 doDelay(nn);
else raise …
(AM): Чтобы выяснить, работает ли программа, используйте GetProcessTimes(), параметр lpExitTime.
(Win32) Для принудительного завершения процесса — TerminateProcess.
(Win16) (RR): Надо послать программе сообщение WM_QUIT:
Handle := Winexec(App, 0);
PostMessage(Handle, WM_QUIT, 0, 0);
Открытие выбранного файла в работающем приложении
Пангин Дмитрий Викторовичприслал письмо следующего содержания:
При программировании MDI-приложений возникает следующая задача: Если пользователь кликнул на файле, тип которого поддерживается создаваемым приложением, то, если приложение уже запущено, не нужно запускать новую копию приложения, а нужно открыть выбранный файл в уже работающем приложении. Я сделал это так (возможно есть более красивое решение):
\\ В файле проекта:
var
i: integer;
hMainForm:hwnd;
copyDataStruct:TCopyDataStruct;
ParamString: string;
WParam,LParam:integer;
begin
\\ ищем главное окно приложения, вместо Caption - nil,
\\ поскольку к заголовку главного окна может добавиться заголовок MDIChild
\\ (нужно позаботиться об уникальности имени класса главной формы)
hMainForm:= FindWindow('TMainForm', nil);
if hMainForm = 0 then begin
Application.Initialize;
Application.CreateForm(TFrmMain, frmMain);
fori:=1 toParamCount doTMainForm(Application.MainForm).OpenFile(ParamStr(i));
Application.Run;
end
else begin
ParamString:='';
fori:=1 toParamCount do begin
\\ запихиваем все параметры в одну строку с разделителями ?13
ParamString:=ParamString+ParamStr(i)+ #13;
end;
\\ создаем запись типа TCopyDataStruct
CopyDataStruct.lpData:=PChar(ParamString);
CopyDataStruct.cbData:=Length(ParamString);
CopyDataStruct.dwData:=0;
WParam:=Application.Handle;
LParam:=Integer(@CopyDataStruct);
\\ отсылаем сообщение WM_COPYDATA главному окну открытого приложения
SendMessage(hMainForm,WM_CopyData,WParam,LParam);
Application.Terminate;
end;
end.
\\ Обработчик сообщения WM_COPYDATA
procedureTMainForm.CopyData( varMsg: TWMCopyData);
var
ParamStr: string;
CopyDataStructure:TCopyDataStruct;
i:integer;
len:integer;
begin
CopyDataStructure:= Msg.CopyDataStruct^;
ParamStr:='';
len:= CopyDataStructure.cbData;
fori:=0 tolen-1 do begin
ParamStr:=ParamStr+(PChar(CopyDataStructure.lpData)+i)^;
end;
i:=0;
while not(Length(ParamStr)=0) do begin
ifisDelimiter(#13,ParamStr,i) then begin
OpenFile(Copy(ParamStr,0,i-1));
ParamStr:=Copy(ParamStr,i+1,Length(ParamStr)-i-1);
end;
inc(i);
end;
inherited;
end;
Убиваем активное приложение
The_Spriteприслал письмо следующего содержания:
Данная функция позволяет завершить выполнение любой активной программы по её classname или заголовку окна.
Совместимость: Все версии Delphi
Исходный код функции
procedureKillProgram(Classname : string; WindowTitle : string);
const
PROCESS_TERMINATE = $0001;
var
ProcessHandle : THandle;
ProcessID: Integer;
TheWindow : HWND;
begin
TheWindow := FindWindow(Classname, WindowTitle);
GetWindowThreadProcessID(TheWindow, @ProcessID);
Читать дальше