VB 5/6-Tipp 0489: Fremde Fenster in eigenes Fenster einbinden
von Klaus Langbein
Beschreibung
Mit diesem Tipp kann man fremde Anwendungen wie z.B. Notepad "kidnappen" und in sein eigenes Fenster einbinden.
Schwierigkeitsgrad: | Verwendete API-Aufrufe: FindWindowA (FindWindow), GetDesktopWindow (GetDeskTopWindow), MoveWindow, SetParent, SetWindowTextA (SetWindowText), ShowWindow | Download: |
'Dieser Quellcode stammt von http://www.activevb.de 'und kann frei verwendet werden. Für eventuelle Schäden 'wird nicht gehaftet. 'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. 'Ansonsten viel Spaß und Erfolg mit diesem Source! '------------ Anfang Projektdatei Kidnapper.vbp ------------ '--------- Anfang Formular "Form1" alias Form1.frm --------- ' Steuerelement: Schaltfläche "Command2" ' Steuerelement: Schaltfläche "Command1" ' ' --------------------------------------------------------- ' Achtung! Man muss das fremde Programm auf jeden Fall ' beenden oder wieder ins Desktop setzen bevor das eigene ' Fenster geschlossen wird. ' Um dieses Beispiel einfach zu halten, wurde auf Shellexecute ' OpenProcess und TerminateProcess (siehe Tip 147) verzichtet. ' Autor: K. Langbein (E-Mail: Klaus@ActiveVB) Option Explicit Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, _ ByVal hWndNewParent As Long) As Long Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _ ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, _ ByVal X As Long, ByVal y As Long, ByVal nWidth As Long, _ ByVal nHeight As Long, ByVal bRepaint As Long) As Long Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, _ ByVal nCmdShow As Long) As Long Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" ( _ ByVal hwnd As Long, ByVal lpString As String) As Long Private Declare Function GetDeskTopWindow Lib "user32" _ Alias "GetDesktopWindow" () As Long Private lhwnd As Long Private ret As Long Private Sub Command1_Click() Dim ltop As Long Dim lleft As Long Dim lwidth As Long Dim lheight As Long ' Notepad starten Call Shell("notepad", vbHide) ' Warten bis vollstaendig geladen Call pause(0.2) ' Handle des neuen Notepad-Fensters feststellen lhwnd = FindWindow("Notepad", vbNullString) If lhwnd <> 0 Then Command1.Enabled = False Command2.Enabled = True ' Jetzt wird das Fenster geklaut Call SetParent(lhwnd, Me.hwnd) ' Ausmasse festlegen (Scalemode von Form1 muss Pixel sein) ltop = Command1.Top + Command1.Height lleft = 0 lwidth = Me.ScaleWidth lheight = Me.ScaleHeight - ltop ' Neue Ausmasse setzen Call MoveWindow(lhwnd, lleft, ltop, lwidth, lheight, 1) ' Caption zuweisen ret = SetWindowText(lhwnd, "Kidnapped Notepad") ' Sichtbar machen ret = ShowWindow(lhwnd, 1) End If End Sub Sub pause(ByVal pause As Single) Dim t As Single t = Timer Do DoEvents Loop Until (Timer - t) >= pause End Sub Private Sub Command2_Click() Dim dh As Long ' Handle des Desktop bestimmen dh = GetDeskTopWindow() ' Programm wieder in den Desktop setzen. Call SetParent(lhwnd, dh) Command1.Enabled = True Command2.Enabled = False End Sub Private Sub Form_Unload(Cancel As Integer) Call Command2_Click End Sub '---------- Ende Formular "Form1" alias Form1.frm ---------- '------------- Ende Projektdatei Kidnapper.vbp -------------
Tipp-Kompatibilität:
Windows/VB-Version | Win32s | Win95 | Win98 | WinME | WinNT4 | Win2000 | WinXP |
VB4 | |||||||
VB5 | |||||||
VB6 |
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.
Archivierte Nutzerkommentare
Klicken Sie diesen Text an, wenn Sie die 15 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.
Kommentar von Jojo am 27.10.2010 um 22:59
Ich habe mal eine Frage:
Ich versuche schon einige Zeit den explorer in den Code einzubauen. Leider klappt das nie....... Hat jemand eine Lösung wie ich statt notepad den explorer einbinde?
Vielen Dank
Kommentar von Tilman am 08.08.2008 um 00:58
Funzt (dank diesem Code hier) auch in Delphi: http://www.delphi-forum.de/viewtopic.php?t=85516
@Wolfram Glitzer: das liegt daran dass die programme dann nicht mehr als eigenständige Anwendungen gefundne werden. Und wenn ein Programm verhindern will dass es sich selbst zweimal startet, dann prüft es zu beginn ob es bereits ein Formular mit dem selben Namen gibt - in diesem Fall ist das ja nicht mehr der Fall. Lösung: Man müsste beim Fangen einfach ein (unsichtbares) neues Formular mit dem selben namen wie dem gefangenen erstellen. Dieses Formular muss aber als eigenständige Anwendung erkannt werden (ka. obs reicht handle = getDesktopWindow zu setzen).
Grüße
Tilman
Kommentar von Stefan Massopust am 07.06.2008 um 14:42
Hallo,
Kann es sein, daß der Tipp nicht bei Vista funktioniert?
Kommentar von Olaf Böhm am 14.07.2006 um 22:54
Von der Idee her, ist das ganze ja recht nett, aber praktisch ist sowas kaum zu gebrauchen (mal von nem Quick'n'Dirty-Tool mal abgesehen). Hat sich mal jemand angeschaut, was dabei rauskommt, wenn man das Elternfenster durch ein anderes Fenster überlappt und dann mal auf den "Kidnapped Notepad" klickt? Die Fenster bleiben beide hinter dem verdeckendem Fenster! Auch der Umbau zu einer MDI-Version ändert daran nichts. Erst wenn man auf das Elternfenster klickt, kommt dieses wieder in den Vordergrund. Ich hab mich schon dumm und dämlich danach gesucht, wie man es besser machen könnte - herausgekommen ist leider nichts, sonst hätte ich dieses Wissen gerne mit euch geteilt. Falls jemand 'ne Idee hat, wie man echte MDI-Childs aus einer externen Anwendung macht... - Echte MDI-Fenster holen die Elternform mit in den Vordergrund, wenn man draufklickt, echte MDI-Fenster übergeben ihr Menü an das Elternfenster, echte MDI-Fenster tragen sich in die Fensterliste ein... 2B continued... - Laßt mich nicht dumm sterben!
Kommentar von Heike Unger am 02.07.2006 um 19:02
Gibt es zu diesem Source auch eine Variante für .NET (vb 2005)? Die automatische Konvertierung von vb6 nach vb2005 funktioniert hier leider nicht! Nach Behebung aller syntaktischen Fehler erhalte ich beim Aufruf der mittels Declare Anweisung aufgenommenen Funktionen immer "PInvokeStackImbalance wurde erkannt". Der Code wird dann zwar scheinbar ausgeführt, allerdings wird das Notepad-Fenster nicht "gefangen".
Kommentar von Andreas Ressel am 24.08.2004 um 15:09
Funktioniert sehr gut. Für nicht MS-Anwendungen die ProcessID ermitteln (siehe Tips) und das RetVal bestimmen und in hwnd setzen >> gefangen.
Für MDI: Einfach in diesem Beispiel Form1 durch MDIForm ersetzen (Routinen übernehmen) und voila >> gefangen. Da es dann keinen Sinn macht, das gekidnappte Prog zurück an den Desktop zu übergeben: Einfach unter "kill" den hwnd nicht auf Desktop setzen sonder mit SendMessage (siehe Tips) schließen.
Kommentar von Wolfram Glitzner am 13.07.2004 um 19:43
Hallo
funktioniert im wesentlichen ganz Klasse :-), ist jedoch die
'gekidnappte Anwendung' eine Anwendung die sich normalerweise nur einmal starten läßt, läßt sie sich nun mehr sowohl in der der gidnappte Form als auch als normale
EXE starten. :-(
Hat jemand eine Idee, womit sich diese kleine Problem lösen läßt ?
Kommentar von Markus am 04.06.2004 um 21:12
Hallo,
dieser tipp ist zwar klasse.. allerdings hätte ich da eine frage zu.
wie kann man fenster klauen, die in einer anderen sitzung laufen (terminalserver)?
Kommentar von Rainbird am 04.05.2004 um 21:06
Ganz große Klasse!
Kommentar von Simeon am 06.01.2004 um 09:46
Könnte man damit auch den Desktop in eine Form einbinden?
Kommentar von Jens Iggena am 07.10.2003 um 21:02
wenn man über SetWindowLong Notepad als Child-Style-Window definieren würde, würde dann das Focus Problem evtl. nicht verschwinden?
Kommentar von Buchholz am 16.08.2003 um 17:38
Tipp 0489 mag ja mit Nodetpad funktionieren, aber nicht mit anderer externer Anwendung die nicht von Microsoft ist
Kommentar von Daniel Pramel am 16.06.2003 um 10:12
Ziemlich nützlich um GUIs seiner ActiveX-dll-plugins in der hostanwendung anzuzeigen :-)
Danke
Kommentar von Mabuse am 29.10.2002 um 18:10
Kann man dem gefangenen Fenster auch irgendwie den Style MDICHILD verpassen, damit sich das Fenster dann wie ein echtes MDI-Child-Form verhält (z.B. das die Anwendung den Fokus nicht verliert, wenn das gefangene Fenster aktiv ist)?
Kommentar von Möglichkeit am 09.10.2002 um 13:33
hm, meiner Meinung nach kann man das auch mit einer MDI Form und einer Browser Form erreichen... die BrwfORM läuft dann auch nur in der MDI - Form
gruss E-T