Chcę uruchomić aplikację z Delphi i uzyskać do niej uchwyt, dzięki czemu mogę osadzić główne okno aplikacji na ramce typu TFrame. Do tej pory próbowałem:Jak uruchomić aplikację i uzyskać do niej dostęp za pomocą Delphi?
Function TFrmEmbeddedExe.StartNewApplication : Boolean;
var
SEInfo: TShellExecuteInfo;
ExitCode : DWORD;
begin
FillChar(SEInfo, SizeOf(SEInfo), 0) ;
SEInfo.cbSize := SizeOf(TShellExecuteInfo) ;
with SEInfo do
begin
fMask := SEE_MASK_NOCLOSEPROCESS;
Wnd := self.Handle;
lpFile := PChar(self.fexecuteFileName) ;// Example could be 'C:\Windows\Notepad.exe'
nShow := SW_SHOWNORMAL;//SW_HIDE;
end;
if ShellExecuteEx(@SEInfo) then
begin
sleep(1500);
self.fAppWnd := FindWindow(nil, PChar(self.fWindowCaption)); //Example : 'Untitled - Notepad'
if self.fAppWnd <> 0 then
begin
Windows.SetParent(self.fAppWnd, SEInfo.Wnd);
ShowWindow(self.fAppWnd, SW_SHOWMAXIMIZED);
result := true;
end
else
result := false;
end
else
result := false;
end ;
Powyższy kod faktycznie działa, ale FindWindow znajdzie danym instans danej aplikacji zacząłem. Chcę osadzić dokładnie te instancje, które przeszedłem. Jeśli więc Notepad był uruchamiany kilka razy, nie ma możliwości, aby uzyskać poprawny za pomocą FindWindow.
Próbowałem:
Function TfrmEmbeddedExe.CreateProcessNewApplication : Boolean;
var
zAppName: array[0..512] of char;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
Res : DWORD;
DoWait : Boolean;
begin
DoWait := False;
StrPCopy(zAppName, self.fexecuteFileName); //'C:\Windows\Notepad.exe'
FillChar(StartupInfo, Sizeof(StartupInfo), #0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_SHOWNORMAL;
if CreateProcess (zAppName,
nil, { pointer to command line string }
nil, { pointer to process security attributes }
nil, { pointer to thread security attributes }
false, { handle inheritance flag }
CREATE_NEW_CONSOLE or { creation flags }
NORMAL_PRIORITY_CLASS,
nil, { pointer to new environment block }
nil, { pointer to current directory name }
StartupInfo, { pointer to STARTUPINFO }
ProcessInfo) then { pointer to PROCESS_INF }
begin
if DoWait then //just set it to false... so it will never enter here
begin
WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
GetExitCodeProcess(ProcessInfo.hProcess, Res);
end
else
begin
self.fAppWnd := ProcessInfo.hProcess;
Windows.SetParent(self.fAppWnd, self.Handle);
ShowWindow(self.fAppWnd, SW_SHOWMAXIMIZED);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
result := true;
end
else begin
Result := false;
end;
end;
Proszę nie uruchamiać Powyższy kod! Daje to dziwne rezultaty, polegające na wybieraniu pozornie losowego okna w dowolnym miejscu we wszystkich działających aplikacjach i osadzaniu (nawet pozycje menu z menu startowego systemu Windows).
Więc w zasadzie potrzebuję, jak uruchomić aplikację i zgarnąć uchwyt do głównego okna aplikacji.
Każda pomoc jest bardzo ceniona
Pozdrowienia
Jens Fudge
Uchwyt procesu nie jest uchwytem okna. Zobacz http://stackoverflow.com/questions/1888863/how-to-get-main-window-handle-from-process-id –
Czytając tytuł, miałem właśnie wejść i nalegać, że to * musi * być duplikat, ale po zobaczeniu, że osadzasz tę aplikację na własną, to odróżnia ją od siebie. Świetne pytanie. –
Nie dodawaj podpisów do swojego posta. [StackOverflow pokazuje już dla ciebie] (http://stackoverflow.com/faq#signatures). – Deanna