AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Externes Programm in Panel laufen lassen
Thema durchsuchen
Ansicht
Themen-Optionen

Externes Programm in Panel laufen lassen

Ein Thema von Jelly · begonnen am 25. Aug 2005 · letzter Beitrag vom 25. Aug 2005
Antwort Antwort
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#1

Externes Programm in Panel laufen lassen

  Alt 25. Aug 2005, 11:55
Hallo,

In Bezug auf diesen Thread nutze ich folgenden Code, um aus einer Anwendung 1 eine 2. zu starten, die dann in einem Panel aus Anwendung 1 angezeigt werden soll:
Delphi-Quellcode:
        
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
        StartupInfo.cb := SizeOf(StartupInfo);
        StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
        StartupInfo.wShowWindow := SW_SHOWNORMAL ;
        if Command <> ''
        then StartName := format ('%s "%s"',[Filename,CommandText])
        else StartName := Filename ;
        FPID := 0 ;
        if CreateProcess(nil,@StartName[1],nil,nil,false,CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,nil,nil,StartupInfo,ProcessInfo) then begin
            FPID := Processinfo.dwProcessID ;

            //sleep(2000) ;

            t1 := now ;
            repeat
               if SearchMode = smByClassname
               then FItems.Owner.ChildHandle := FindWindow (PChar(ClassName),nil)
               else FItems.Owner.ChildHandle := FindWindow (nil,PChar(FormCaption)) ;
            until (FItems.Owner.ChildHandle <> 0) or (now-t1 > EncodeTime(0,0,5,0)) ;

            { Eventuell im Panel anzeigen }
            if RunInPanel then begin
                if (FItems.Owner.ChildHandle <> 0) and assigned(Panel) then begin
                    Windows.SetParent(FItems.Owner.ChildHandle, Panel.Handle);
                    ShowWindow(FItems.Owner.ChildHandle, SW_MAXIMIZE);
                end else begin
                    ShowMessage ('Panel Problem') ;
                end ;
            end ; { im Panel anzeigen }
        end else begin
            Showmessage ('konnte Programm nicht starten') ;
        end ;
Es taucht dabei ein skuriles Phänomen auf. Die 2. Anwendung wird gestartet, jedoch maximized im gesamten Desktop, statt im Panel. Lass ich eine Sleep(2000) Pause nach der Prozesserzeugung den Ablauf bremsen, so klappts einwandfrei... Nun ist diese Sleep-Lösung aber sicherlich nicht die feine englische Art.

Das Komische daran ist, dass ich vor if RunInPanel then begin... sowohl Handle als auch FPID habe. Warum funktioniert der Code nicht zum Anzeigen des Forms im Panel ?
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Externes Programm in Panel laufen lassen

  Alt 25. Aug 2005, 12:41
durch das Sleep wird sichergestellt das die andere Anwendung fertig gerstartet ist und du somit das richtige Handle hast. Du schreibst zwar das du schon zuvor das richtige hast aber dem wird nicht so sein. Wenn die zweite Anwendung zum Beispiel mit Delphi erstellt wurde und der Style fsStayOnTop ist so wird an dieser Stelle wo das property gesetzt wird das Fenster neu erzeugt und somit ist das alte Handle nicht mehr gültig.
Zu deiner Sleep-Variante: Das ist eine ziemlich schlechte Lösung, denn wenn der Rechner ausgelastet ist kann es durchaus passieren das dein Sleep zu kurz ist..
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
teebee

Registriert seit: 17. Jan 2003
Ort: Köln
460 Beiträge
 
Delphi 6 Professional
 
#3

Re: Externes Programm in Panel laufen lassen

  Alt 25. Aug 2005, 13:11
Zitat von MSDN:
The WaitForInputIdle function enables a thread to suspend its execution until the specified process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronizing a parent process and a newly created child process. When a parent process creates a child process, the CreateProcess function returns without waiting for the child process to finish its initialization. Before trying to communicate with the child process, the parent process can use WaitForInputIdle to determine when the child's initialization has been completed. For example, the parent process should use WaitForInputIdle before trying to find a window associated with the child process.
Schau Dir mal MSDN-Library durchsuchenWaitForInputIdle an. Vielleicht ist das ja was für Dich.

Gruß, teebee
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#4

Re: Externes Programm in Panel laufen lassen

  Alt 25. Aug 2005, 14:00
@SirThornberry:
Deine Erklärung leuchtet mir zwar ein, nur bringst mich nicht wirklich weiter. Ich weiss, dass Sleep schlecht ist, deshalb such ich ja nach einer anderen Lösung.

@teebee:
Hab mir mal deine Funktion angekuckt, scheint aber auch nicht zu klappen... Statt des sleep hab ich jetzt ml Folgendes eingebaut:
WaitForInputIdle (ProcessInfo.hProcess,50000) ; Ohne Erfolg.
  Mit Zitat antworten Zitat
teebee

Registriert seit: 17. Jan 2003
Ort: Köln
460 Beiträge
 
Delphi 6 Professional
 
#5

Re: Externes Programm in Panel laufen lassen

  Alt 25. Aug 2005, 16:23
So wie es aussieht, ist das eigentliche Problem nicht das Fensterhandle des erzeugten Prozesses, sonst bliebe der ja unsichtbar. Irgendwie scheint Panel.Handle Null zu sein, dann ist der Parent automatisch der Desktop. Wie das jetzt aber mit dem sleep zusammenhängt ist mir leider nicht klar.
Laut PSDK soll man übrigens noch den Fensterstil WS_CHILD des untergeordneten Fensters setzen und WS_POPUP löschen, bevor man SetParent aufruft, wenn der Parent nicht Null ist
Zitat von MSDN:
For compatibility reasons, SetParent does not modify the WS_CHILD or WS_POPUP window styles of the window whose parent is being changed. Therefore, if hWndNewParent is NULL, you should also clear the WS_CHILD bit and set the WS_POPUP style after calling SetParent. Conversely, if hWndNewParent is not NULL and the window was previously a child of the desktop, you should clear the WS_POPUP style and set the WS_CHILD style before calling SetParent.
Gruß, teebee
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#6

Re: Externes Programm in Panel laufen lassen

  Alt 25. Aug 2005, 16:38
Zitat von teebee:
...bevor man SetParent aufruft, wenn der Parent nicht Null ist
Zitat von MSDN:
...after calling SetParent.
Also wohl eher danach.

Aber wie mache ich das?

Wenn ich die Anwendung nicht im Panel starten lasse, hab ich das Handle des Hauptfensters. Läufts im Panel, scheint sich dieses Handle bei der Initialisierung wohl irgendwie zu ändern, da ein SetParent nichts mehr bewirkt.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:20 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz