В данной статье рассмотрим, как запустить внешнее приложение из Delphi и получить к нему доступ, чтобы интегрировать его главное окно в TFrame. Пример кода будет использован на языке Object Pascal, который является основным для Delphi.
Шаг 1: Запуск приложения
Для начала необходимо запустить приложение, используя функцию ShellExecuteEx или CreateProcess. Эти функции позволят получить дескриптор процесса.
Пример использования CreateProcess:
uses
Windows;
function CreateProcessNewApplication: Boolean;
var
zAppName: array[0..512] of char;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin
StrPCopy(zAppName, 'C:\Windows\System32\notepad.exe'); // Путь к исполняемому файлу
FillChar(StartupInfo, SizeOf(StartupInfo), 0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_SHOWNORMAL;
if CreateProcess(nil, PChar(zAppName), nil, nil, False, 0, nil, nil, @StartupInfo, ProcessInfo) then
begin
// Здесь может быть ожидание, пока процесс не станет инертным (WaitForInputIdle)
// ...
Result := True;
end
else
Result := False;
end;
Шаг 2: Ожидание готовности приложения
После запуска приложения необходимо дождаться, пока оно полностью загрузится и начнет цикл обработки сообщений. Для этого используется функция WaitForInputIdle.
Шаг 3: Получение дескриптора главного окна
После того как процесс запущен и готов к работе, необходимо получить дескриптор главного окна этого процесса. Это можно сделать, перебрав все окна системы и сравнив процесс, к которому они принадлежат, с искомым.
type
TEnumData = record
WHdl: HWND;
WPid: DWORD;
WTitle: String;
end;
PEnumData = ^TEnumData;
function EnumWindowsProcMatchPID(WHdl: HWND; EData: PEnumData): Boolean; stdcall;
var
Wpid: DWORD;
begin
Result := True; // Продолжить перебор
GetWindowThreadProcessID(WHdl, @Wpid);
if (EData.WPid = Wpid) and IsWindowVisible(WHdl) then
begin
EData.WHdl := WHdl;
Result := False; // Прервать перебор
end;
end;
function GetWinHandleFromProcId(ProcId: DWORD): HWND;
var
EnumData: TEnumData;
begin
ZeroMemory(@EnumData, SizeOf(EnumData));
EnumData.WPid := ProcId;
EnumWindows(@EnumWindowsProcMatchPID, LPARAM(@EnumData));
Result := EnumData.WHdl;
end;
Шаг 4: Интеграция окна в TFrame
После получения дескриптора главного окна приложения, можно интегрировать его в TFrame, используя функции SetParent и ShowWindow.
var
SlaveWinHdl: HWND;
ProcessId: DWORD;
begin
ProcessId := ProcessIdFromYourProcessInfo; // Получение ProcessId из ProcessInfo
SlaveWinHdl := GetWinHandleFromProcId(ProcessId);
if SlaveWinHdl <> 0 then
begin
Windows.SetParent(SlaveWinHdl, FrameHandle); // FrameHandle - это дескриптор TFrame
ShowWindow(SlaveWinHdl, SW_SHOWMAXIMIZED);
end;
end;
Заключение
Таким образом, мы запустили внешнее приложение, получили доступ к его главному окну и интегрировали его в TFrame. Важно помнить о закрытии дескрипторов процессов после выполнения операций, чтобы избежать утечки ресурсов.
Статья пошагово описывает процесс интеграции окна внешнего приложения в TFrame в среде разработки Delphi.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS