Uruchomienie aplikacji wewnątrz innej aplikacji

0

Witam
Czy istnieje mozliwosc w wlasnej aplikacji napisanej w delphi odpalic inna aplikacje i w jaki sposob to zrobic? efekt wizualny jaki chce uzyskac jest w zalaczniku!

program-w-programie02.png

0

To okienko wewnętrzne (z tytułem Arabic...) - na tym zrzucie który dałeś - to może być przesunięte (np. w prawo) - i wtedy wystaje poza okno (z tytułem Form1), które jest w tle?
Czy może chcesz tak, żeby to okno wewnętrzne było zawsze wewnątrz tego okna zewnętrznego?

0

To zwykłe MDI… :D

0

StefanN, oczywiscie iz zawszse wewnatrz okna Delphi, moznasie chyba domyslec ze w paincie zrobilem efekt na poczekaniu dla wyjasnienia efektu jaki chce uzyskac ;]

Innymi slowy zamiast na pulpicie windows'a, Forma w Delphi bedzie pulpitem tego programu. Podejrzewam iz trzeba beddzie kombinowac cos z uchwytami, lecz nie mam zielonego pojecia jak to wykonac.

0
Stefan_3N napisał(a):

Ten obrazek jest chyba zmontowany. Autor pyta o możliwość odpalenia innej aplikacji wewnątrz (czyli jakby przechwycenie obcej aplikacji i ciągniecie jej do swojego okna).

Dokladnie ta furious programming! dokladnie o to mi chodzi, cos jak MDI.

Byc moze gdybym usiadl na tym, sam to wykombinowalbym ale nie mam na to mocy przeborowych. Skoro tak namietnie wyjasnilismy sobie o co mi chodzi, b prosze o posty z gotowa informacja jak to wykonac lub wasze sugestie w jakim isc kierunku!

1

Odpal ten zew. program, pobierz uchwyt do jego okna i zmień mu parenta – zobacz co się stanie.

3
  1. Uruchamiasz apkę jakkolwiek funkcją, która zwróci uchwyt procesu
  2. Szukasz jego okna głównego okna za pomocą EnumWindows i sprawdzenia procesu GetWindowThreadProcessId dodatkowo czy to okno główne warunek GetWindow(handle, GW_OWNER) = 0
  3. Za pomocą Winapi.Windows.SetParent zmieniasz rodzina na okno w którym ma apka być dokowana oczywiście może to być kontrolka no. Panel.
  4. Teraz już tylko MoveWindow aby dostosować rozmiary i położenie okna uruchamianej aplikacji
  5. I dajmy ją na wierzch a więc SetForegroundWindow.
2

tu masz przykład Putty na formie

0
bronex napisał(a):

efekt wizualny jaki chce uzyskac jest w zalaczniku!

Ten program, to jest przecież przeglądarka...
Skoro tak, to osadź sobie TWebBrowser lub inne Chromium i do dzieła.
Jeśli to normalna apka Windows, to @kAzek napisał co i jak.

3

Z ciekawości sprawdziłem w Lazarusie czy to zadziała – wygląda na to, że tak. Okna osadzonych programów znajdują się wewnątrz okna naszej aplikacji, maksymalizacja ładnie dopasowuje je do rodzica, a minimalizacja tworzy miniaturki u dołu:

preview.png

Luźny kod testowy niżej (bez zabezpieczeń), a źródła i filmik poglądowy w załącznikach.

type
  PEnumData = ^TEnumData;
  TEnumData = record
    ProcessID: THandle;
    WindowHandle: THandle;
  end;

function EnumProc(AHandle: THandle; AEnumData: LongInt): LongBool; stdcall;
var
  EnumData: PEnumData absolute AEnumData;
  ProcessID: THandle;
begin
  Result := True;

  if GetWindow(AHandle, GW_OWNER) = 0 then
  begin
    GetWindowThreadProcessId(AHandle, @ProcessID);

    if ProcessID = EnumData^.ProcessID then
    begin
      EnumData^.WindowHandle := AHandle;
      Result := False;
    end;
  end;
end;

procedure TMainForm.EmbedApplication(const AAppName: String);
var
  Process: TProcess;
  EnumData: TEnumData;
begin
  Process := TProcess.Create(Self);
  Process.Executable := AAppName;
  Process.ShowWindow := swoHide;
  Process.Execute();

  Sleep(1000);

  EnumData.ProcessID := Process.ProcessID;
  EnumData.WindowHandle := 0;

  Windows.EnumWindows(@EnumProc, LongInt(@EnumData));

  Windows.SetParent(EnumData.WindowHandle, CWorkspacePanel.Handle);
  Windows.ShowWindow(EnumData.WindowHandle, SW_SHOW);
  Windows.SetForegroundWindow(EnumData.WindowHandle);

  Process.Free();
end;

procedure TMainForm.CNewPaintButtonClick(Sender: TObject);
begin
  EmbedApplication('mspaint');
end;

procedure TMainForm.CNewNotepadButtonClick(Sender: TObject);
begin
  EmbedApplication('notepad');
end;

Aby zrobić to dobrze, należy przede wszystkim zastąpić wywołanie Sleep czymś sensowniejszym. No i pasuje też uchwyty osadzonych programów (PID i uchwyt okna) gdzieś przechowywać, żeby nie narobić syfu w systemie i ładnie po sobie posprzątać. Albo te procesy ubijać, albo je odpinać od naszego programu, np. ustawiając im pulpit jako rodzica, albo wysyłać komunikaty do okien, aby same się zamknęły (np. postraszyć je komunikatem WM_QUERYENDSESSION ;) ).

Mimo wszystko z takim rozwiązaniem jest masa problemów. Pomijając już konieczność sprzątania po sobie, to problem stanowią okna dialogowe, otwierane przez osadzone aplikacje – te nie blokują okna-rodzica. Trzeba też zadbać o dopasowywanie okien osadzonych do okna-rodzica, kiedy to główne się rozciąga, a któreś osadzone jest zmaksymalizowane. Ogólnie to trzeba się narobić, aby takie rozwiązanie miało ręce i nogi i nie robiło bajzlu w systemie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0