Prozess im Vordergrund von eigener Anwendung erstellen?



  • Naja, kann sein dass es mit SetParent doch nicht geht.

    Was du machen willst wäre das Owner-Window zu ändern, nicht das Parent-Window.
    An einigen Stellen in der WinAPI werden für Parent und Owner die gleichen Funktionen/Member/Parameter verwendet, daher dachte ich es sollte mit SetParent funktionieren. Muss aber nicht sein dass das so ist, ich hab's nicht ausprobiert.

    Bzw. bist du sicher dass das Fenster der anderen Anwendung ein Top-Level Fenster ist? Wenn du SetParent auf ein Child-Window aufrufst, dann ist klar dass es danach IN deiner Form drinnen ist, und nicht davor -- weil halt Child Window.



  • Aaaaaah,

    hier
    http://stackoverflow.com/questions/133122/how-to-change-a-window-owner-using-its-handle
    steht dass man SetWindowLongPtr(..., GWLP_HWNDPARENT, ...) verwenden kann.

    Das könntest du mal probieren.



  • Das sieht vielversprechend aus!
    http://stackoverflow.com/questions/133122/how-to-change-a-window-owner-using-its-handle

    SetWindowLongPtr( win32window, GWL_HWNDPARENT, formhandle );
    

    Problem ist nur: laut MSDN ist die Funktion wie folgt deklariert:

    LONG_PTR WINAPI SetWindowLongPtr(
      _In_  HWND hWnd,
      _In_  int nIndex,
      _In_  LONG_PTR dwNewLong
    );
    

    Der dritte Parameter (dwNewLong) sollte laut Beispiel das Handle des Formulars (formhandle) sein. Natürlich kann ich als long kein HWND übergeben. 🙄

    [C++ Fehler]: E2034 Konvertierung von 'void *' nach 'long' nicht möglich

    Wie kann ich trotzdem das Handle des Formulars übergeben?



  • Einfach casten.

    reinterpret_cast<LONG_PTR>(deinHwndWert)

    Der reinterpret_cast ist in dem Fall auch kein Hack, sondern vom MS ganz klar so vorgesehen.

    Wichtig ist nur dass du die " ...Ptr " Funktion verwendest und auch LONG_PTR beim Casten verwendest, sonst bekommst du ein Problem wenn du mal für 64 Bit kompilierst.



  • ps:
    Wichtig:
    GWL ** P ** _HWNDPARENT statt GWL_HWNDPARENT verwenden wenn du SetWindowLong ** Ptr **verwendest.

    Sonst wird das mit 64 Bit vermutlich wieder net richtig funktionieren 🙂



  • Vielen Dank!! Funktioniert herrlich!!! 😃 😃

    Nur noch eine Kleinigkeit:
    Das andere Fenster sitzt im Vordergrund und minimiert sich auch mit. Man kann aber trotzdem noch das Parent-Formular bedienen. Muss man wirklich einen Timer oder Thread erstellen, der ein MessageBeep ausführt und den Fokus auf das Formular setzt, sobald man auf das Hauptformular klickt, oder kann man da auch mit der WinAPI arbeiten? 😉

    Trotzdem: Schön dass es funktioniert!! 👍



  • Welches Parent-Formular?
    Verstehe grad nicht was du meinst.
    Das Parent-Formular in deiner Applikation? Oder in der Fremden?

    Mach vielleicht mal Screenshots die das ganze verdeutlichen.

    Bzw. falls es um deine Applikation geht, kannst du natürlich auch hier Window-Ownership verwenden. Und/oder modale Dialoge.

    ps: Das ist immer noch ein Hack, und ich würde es nur begrenzt empfehlen. Es kann durchaus Applikationen geben die ... anfangen komische Dinge zu tun wenn man an ihren Fenstern in dieser Art rumpfuscht - also Owner-Window ändert oder dergleichen.

    pps: Das "ist in dem Fall auch kein Hack" oben bezieht sich auf den reinterpret_cast , nicht auf das Ändern des Owner-Windows.



  • Hier sind die Links zu den Filmen, die hoffentlich das Problem näher führen.

    Film1 (meine Anwendung):
    http://www.noctua-development.de-info.de/downloads/Meine_Anwendung.wmv

    Film2 (MessageBox Anwendung -> wie es sein sollte)
    http://www.noctua-development.de-info.de/downloads/MessageBox_Beispiel.wmv

    Natürlich könnte man diesen Effekt selber erzielen, aber ich habe die Hoffnung noch nicht aufgegeben, dass es etwas Hübsches aus der WinAPI gibt. 😃



  • OK, cool, ich denke jetzt hab' ich verstanden was du willst 💡 🙂
    Du willst bloss dass dein Dialog "gesperrt" ist, so lange das andere Programm läuft, korrekt?

    Das sollte doch einfach sein:
    Mach eine kleine Dialog-Klasse, die nen Mini-Dialog ala "[...warte auf externe Anwendung...]" oder so anzeigt (theoretisch könner man den Dialog, falls gewünscht, auch komplett unsichtbar bekommen).

    Dieser Dialog sollte vom Benutzer nicht schliessbar sein, also die entsprechenden Handler-Funktionen überschreiben (bei MFC wären das z.B. OnCancel und OnClose).

    Einfacherweise würde ich diesem Dialog dann auch die Aufgabe übertragen das externe Programm zu starten, und zu überwachen wann das externe Programm fertig wird (z.B. einfach nen Timer und dann mit WaitForSingleObject(hProcess, 0) periodisch checken ob der Prozess noch läuft). Und wenn der externe Prozess fertig ist, schliesst sich der Dialog von selbst.

    Und diesen Dialog rufst du dann einfach modal auf. Wodurch genau das selbe passiert wie bei einer MessageBox, nämlich dass das Fenster darunter blockiert wird.

    Wobei du dir überlegen solltest ob es nicht besser wäre einfach nur alle Controls (inklusive dem Fenster-schliess-"X") zu disablen während das externe Programm läuft. Ich persönlich finde das nämlich immer nervig dass ich, wenn so ein modales Gedöns offen ist, das darunterliegende Fenster nichtmal verschieben kann.



  • ps: Du kannst natürlich auch mal probieren was passiert wenn du EnableWindow(myDialog, false) aufrufst.
    Oder sonst ein wenig googeln ob es nen einfachen Mechanismus gibt den Effekt eines modalen Dialogs zu erreichen ohne eben einen modalen Dialog anzuzeigen.



  • Habe mich für SetParent entscheiden. 😉
    Meiner Meinung nach sauberer als modaler Dialog vor Anwendung (der nicht sichtbar wäre). Danach mit SetWindowLong und SetWindowPos in meinem Fenster positioniert. 😃
    Vielen Dank für eure Hilfe 👍

    Video zur fertigen Lösung:
    http://www.noctua-development.de-info.de/downloads/L%C3%B6sung.wmv



  • Waaaaaaaaah 😮

    Das ist jetzt der schlimmste Hack.
    Dir ist klar dass es sein kann dass das mit der nächsten 7-zip Version nimmer funktioniert?
    OK, unwahrscheinlich dass es überhaupt nimmer geht, aber ... sowas macht man halt normalerweise nicht, und daher wird von Programmen auch nicht erwartet dass sie mit sowas klarkommen.


Anmelden zum Antworten