externes programm minimieren/maximieren

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von iXclusiv.

    externes programm minimieren/maximieren

    Hallo,

    in meiner form habe ich 2 button, alle werden deaktiviert wenn der prozess NICHT läuft.

    wenn der prozess läuft ist button1 mit dem text Minimieren aktiv.

    Nun meine frage: wie kann ich den externen prozess denn minimieren bzw. mit dem zweiten button wieder maximieren?
    Das geht mit dem WindowsAPI. Du musst die Funktion ShowWindow() benutzen und ihr das Handle des zu steuernden Fensters und eine Konstante übergeben, die das Fenster je nach Wert minimiert oder maximiert. Es sind auch noch weitere Aktionen möglich.
    Das Handle bekommst du über eine Process-Instanz (Stichwort MainWindowHandle). Wenn du Hilfe bei der Deklaration brauchst, frag' nochmal nach.

    gruß
    hal2000
    Gruß
    hal2000
    dann wollen wir mal...

    Jedes Fenster hat eine eindeutige ID zugeodnet, welche "Handle" genannt wird.
    Diese ID wird von der WindowsAPI-Funktion erwartet, damit sie weiß, auf welches Fenster du dich nun beziehst.
    Also musst du das Handle ermitteln. Starte die Anwendung, die du später kontrollieren möchtest. Rufe den Task-Manager auf, suche den namen des Prozesses. Hier hilft die Funktion "Zu Prozess wechseln". --> Namen aufschreiben oder merken.

    Nun zum Code: Wie gesagt, bekommst du das Handle über eine Process-Instanz. Was machst du also? Du erstellst dir eine. In einer Methode, z.B. Button1_Click(...) ...

    VB.NET-Quellcode

    1. Dim p() As Process = Process.GetProcessesByName("AufgeschiebenerName") ' der Name den du dir aufgeschrieben hast, muss ohne die Endung eingetragen werden (also ohne .exe).
    2. Dim hwnd As IntPtr = p(0).MainWindowHandle

    Das wars an dieser Stelle - in hwnd hast du das Handle.

    Weiter mit der Deklaration:

    VB.NET-Quellcode

    1. Private Declare Auto Function ShowWindow Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal nCmdShow As Int32) As Int32

    So deklarierst du eine WindowsAPI-Funktion (das ist mehr oder weniger immer dasselbe).

    Nun fehlt noch die Konstante, die die Funktion im zweiten Parameter erwartet. Für die Anweisung "Fenster verstecken" ist sie Null (0) (NICHT "Nothing")
    "Fenster anzeigen" ist der Wert 5, manchmal auch 9 (je nachdem, ob das Fenster geschlossen oder minimiert war)

    VB.NET-Quellcode

    1. Private Const SW_HIDE As Int32 = 0
    2. Private Const SW_SHOW As Int32 = 5
    3. Private Const SW_RESTORE As Int32 = 9

    Das kommt über die Anweisung "Declare Auto....."

    In deiner Click-Methode kannst du deine Funktion nun aufrufen:

    VB.NET-Quellcode

    1. ShowWindow(hwnd, SW_SHOW) 'Probier' die Konstanten durch, im MSDN gibts alle (allgemeiner Link unten).


    Bei diesem Aufruf sollte ein Fenster, das im Hintergrund ist und gerade von anderen Fenstern überdeckt wird, nach vorne kommen.
    Ein in die Taskleiste minimiertes Fenster kommt durch Einsetzen von SW_RESTORE wieder zum Vorschein.

    ich hoffe, ich habe alles verständlich geschrieben, sonst hilfts ja nix.

    hier noch der Link:
    msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

    gruß
    hal2000

    EDIT: Was mir noch aufgefallen ist: Speichere das Handle irgendwo. Es ist sehr schwierig es (ohne weitere Hilfsmittel) wiederzubekommen, wenn das Fenster mit SW_HIDE versteckt wurde.

    hal2000
    Gruß
    hal2000

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „hal2000“ ()

    Hi,

    wie speicher ich den handle denn am besten ab? Also minimieren funzt, leider wie du ja schon sagst das wiederherstellen nicht :(

    und ehm hab da noch ne frage, wie kann ich denn ermitteln ob das fenster vomprozess weg ist?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „iXclusiv“ ()

    Hi,

    entweder bin ich blöd oder es geht einfach nicht... das Fenster was ich minimiere ist eig. volbild (musste ich aber anders setzen weil noch probleme mit dem overlay da sind, flakkert die ganze zeit nur -.-)

    VB.NET-Quellcode

    1. Public Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
    2. Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
    3. Public Declare Auto Function ShowWindow Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal nCmdShow As Int32) As Int32
    4. Public Const SW_HIDE As Int32 = 0 'Versteckt das Fenster
    5. Public Const SW_MAXIMIZE As Int32 = 3 'Maximiert das Fenster
    6. Public Const SW_MINIMIZE As Int32 = 6 'Minmiert das Fenster
    7. Public Const SW_NORMAL As Int32 = 1 'Aktiviert das Fenster
    8. Public Const SW_RESTORE As Int32 = 9 'Stellt das Fenster wieder her
    9. Public Const SW_SHOW As Int32 = 5 'Zeigt das Fenster an, auch wenn es versteckt ist
    10. Public Const SW_SHOWMAXIMIZED As Int32 = 3 'Zeigt das Fenster an und Maximiert es
    11. Public Const SW_SHOWMINIMIZED As Int32 = 2 'Zeigt das Fenster an und Minimiert es
    12. Public Const SW_SHOWMINNOACTIVE As Int32 = 7 'Minimiert das Fenster aber aktiviert es nicht
    13. Public Const SW_SHOWNA As Int32 = 8 'Zeigt das Fenster an aber aktiviert es nicht
    14. Public Const SW_SHOWNOACTIVATE As Int32 = 4 'Zeigt das Fenster an ohne es zu aktivieren
    15. Public Const SW_SHOWNORMAL As Int32 = 1 'Zeigt das Fenster und aktiviert dies


    VB.NET-Quellcode

    1. Private Sub cmdMini_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdMini.Click
    2. Dim p() As Process = Process.GetProcessesByName("jamp") ' der Name den du dir aufgeschrieben hast, muss ohne die Endung eingetragen werden (also ohne .exe).
    3. Dim hwnd As IntPtr = p(0).MainWindowHandle
    4. ShowWindow(hwnd, SW_HIDE)
    5. cmdRestore.Enabled = True
    6. cmdMini.Enabled = False
    7. cmdMini.Visible = False
    8. cmdRestore.Visible = True
    9. cmdCloseJK3.Visible = True
    10. End Sub
    11. Private Sub cmdRestore_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRestore.Click
    12. Dim p() As Process = Process.GetProcessesByName("jamp") ' der Name den du dir aufgeschrieben hast, muss ohne die Endung eingetragen werden (also ohne .exe).
    13. ShowWindow(p(0).MainWindowHandle, SW_SHOW)
    14. cmdRestore.Enabled = False
    15. cmdMini.Enabled = True
    16. cmdMini.Visible = True
    17. cmdRestore.Visible = False
    18. cmdCloseJK3.Visible = True
    19. End Sub


    ich weiß echt nicht weiter ...... minimieren lässt es sich, aber es kommt weder zurück oder lässt sich in der taskleiste anzeigen.. einfach nix, es ist weg als ob keiner der genannten konstanzen funktionieren würde...
    ganz einfach - du deklarierst (vor den ganzen Subs) eine globale Variable "hwnd". Dor speicherst du in der Sub "cmdMin_Click" das Handle.
    In der Sub "cmdRestore_Click" kannst du dann die ersten zwei Zeilen weglassen, denn das Handle muss nicht mehr ermittelt werden (es steht ja schon in hwnd).

    Beispiel:

    VB.NET-Quellcode

    1. 'oben
    2. Dim hwnd As IntPtr
    3. 'in cmdMini
    4. hwnd = p(0).MainWindowHandle
    5. 'in cmdRestore
    6. --nix mehr, hwnd ist bereits bekannt. Nur noch ShowWindow(hwnd, SW_SHOW) aufrufen.--
    7. (und natürlich den Rest, den du noch einstellst (Visible etc.)


    gruß
    hal2000
    Gruß
    hal2000
    Hi,

    THX das funktioniert nun SUPER.

    Aber eine Frage hab ich noch besser gesagt 2.

    1. Wie kannich denn nun zu dem fenster eine nachricht schicken die das fenster verarbeiten kann
    2. Das Programm was gehided wird läuft in vollbild, und wenn ich mein overlay drüberlege flackert der overlay nur... wie kann ich das beheben?
    1. Das kommt drauf an, was das Fenster verarbeiten soll. Es gibt über 500 Nachrichtentypen, die du an Fenster schicken kannst. Du hast gerade zwei davon kennen gelernt XD.
    Du kannst z.B. eine Drag&Drop-Operation ausführen (per code). Oder Text auslesen / wieder reinschreiben. Mit den richtigen Aufrufen geht alles.

    2. Ich verstehe die Frage nicht...wie kannst du ein Overlay über ein verstecktes Fenster legen?

    gruß
    hal2000
    Gruß
    hal2000
    Hi,

    der Overlay flackert wenn das programm im vollbild läuft, muss ja den overlay aufrufen um das programm zu minimieren.

    es handelt sich um ein spiel was minimiert werden soll bzw. in dem overlay soll man weitere einstellungen vornehmen können.

    sozusagen das hier:

    sithempire-clan.com/Unbenannt.PNG

    nur für ein anderes spiel.

    Zu 1 den Text den ich sende ist "say blabla" damit wird im spiel sozusagen bekanntgemacht das ich das spiel minimiert habe.
    Frage 1 wird mit der Funktion SendKeys() beantwortet - bitte googeln ^^.
    Das sollte wegehen, wenn das Overlay als "SystemModal" angezeigt wird (wie der Taskmanager, wenn man ihn aufruft). Such auch hier mal im Netz, denn es ist spät und ich bin müde XD.
    Die zentralen Begriffe habe ich ja genannt...daran scheitert die Websuche oft.

    gruß
    hal2000
    Gruß
    hal2000
    Hi,

    mit Sendkeys sende ich so wie ich rausgefunden habe nur tastenkombinationen an das fenster ok sollte ja klappen was ich vorhabe. (wird aber ein langer string xD)

    das flackern hat sich EIN wenig verbessert jedoch verschwinded meine form doch noch und kehrt eine sekunde später wieder nach dem ich FixedToolWindow eingestellt habe, funktioniert also nicht 100% :(