Sicher kennen Sie das: Sie wollen ein Programm beenden und nach dem Klick auf das "X" ist die Anwendung nicht beendet, sondern es taucht eine MessagBox auf, die fragt, ob man sich wirklich sicher ist. Dieses Phänomen kann schnell zum Ärgernis werden, wenn Sie ein Programm erstellen, welches fremde Programme automatisch beenden soll. Denn: Die TopLevel-Anwendung wird in den meisten Fällen nicht mehr ansprechbar sein. D.h. es klebt Ihnen eine MessageBox mit unbekanntem Handel im Vordergrund und Sie können die Anwendung nicht mehr standardmäßig beenden (nur noch Killen! - aber das kann ungewünschte Nebeneffekte mit sich bringen!). Leider bietet Visual Basic keine eigne Funktion, die eine Messagebox erkennt und so habe ich mit Hilfe des Win32 API mehrere Funktionen geschrieben, die das erledigen. Mit deren Hilfe ist es möglich, MessagBoxes bestimmter Fenster zu erkennen, deren Handle zu bekommen, um dann gegebenenfalls darauf reagieren zu können. P.S: Mit ein bisschen Mehraufwand lässt sich dieser Code auch so umschreiben, dass systemweit alle Messagboxen ausgelesen werden können. Statt des Anwendungshandle durchlaufen Sie mit der API- Funktion EnumWindows alle Toplevel-Fenster und schon bekommen Sie alle Msgbox-Handles des Systems. Der nachfolgende Code muss in ein Modul eingefügt werden. Option Explicit ' zunächst die benötigten API-Funktionen Private Declare Function GetParent Lib "user32" ( _ ByVal hwnd As Long) As Long Private Declare Function GetWindowThreadProcessId Lib "user32" ( _ ByVal hwnd As Long, _ lpdwProcessId As Long) As Long Private Declare Function GetWindow Lib "user32" ( _ ByVal hwnd As Long, _ ByVal wCmd As Long) As Long Private Declare Function EnumThreadWindows Lib "user32.dll" ( _ ByVal dwThreadId As Long, _ ByVal lpfn As Long, _ ByVal lParam As Long) As Long Private Declare Function GetClassName Lib "user32" _ Alias "GetClassNameA" ( _ ByVal hwnd As Long, _ ByVal lpClassName As String, _ ByVal nMaxCount As Long) As Long Private Const MsgClass = "#32770" ' Nur zum Zwischenspeichern des Handels der ' Callbackfunktion Public MsgWnd As Long Public TopLevelHandle As Long ' Diese Funktion liefert bei Erfolg den Handle der MsgBox Public Function FindFirstMsgbox(hwnd As Long) As Long MsgWnd = 0 Call EnumThreadWindows(GetWindowThreadProcessId(hwnd, _ ByVal 0&), AddressOf FindMsgbox, 0&) FindFirstMsgbox = MsgWnd End Function ' Callback-Funktion zum Auffinden einer MessageBox Public Function FindMsgbox(ByVal hwnd As Long, _ ByVal lParam As Long) As Long If IsMsgBox(hwnd) = True Then MsgWnd = hwnd FindMsgbox = 0 Else FindMsgbox = 1 End If End Function ' Prüft, ob das Fenster eine Messagebox ist Public Function IsMsgBox(hwnd As Long) As Boolean Dim lpClassName As String * 7 Dim Retval As Byte lpClassName = Space(256) Retval = GetClassName(hwnd, lpClassName, 256) IsMsgBox = (MsgClass = Left$(lpClassName, Retval)) End Function Um das ganze jetzt einmal zu testen, benötigen wir eine Form, darauf ein Timer-Steuerelement (Timer1) und ein Label (Label1). Fügen Sie anschliessend nachfolgenden Code in den Codeteil der Form: Option Explicit ' Funktion, um das Handle der TopLevel-Anwendung ' zu ermitteln (anhand des exakten Fenstertitels) Private Declare Function FindWindow Lib "user32" _ Alias "FindWindowA" ( _ ByVal lpClassName As String, _ ByVal lpWindowName As String) As Long ' Einlesen eines Fenstertitels und anschließende ' Überprüfung ob Messagebox vorhanden Private Sub Form_Load() Dim PID As Long Dim MSGBOXhWnd As Long Dim S As String S = InputBox("Geben sie den Fenstertitel " & _ "der Anwendung ein, " & "die auf eine Messagbox " & _ "überprüft werden soll.", "Fenster-Titel", "") TopLevelHandle = FindWindow(vbNullString, S) If TopLevelHandle = 0 Then Label1.Caption = "Konnte das Fenster nicht finden ..." Else ' Timer-Intervall auf 1 Sekunde festlegen Timer1.Interval = 1000 Call Timer1_Timer End If End Sub ' Sekündliche Überprüfung ob Messagebox vorhanden Private Sub Timer1_Timer() Dim MSGBOXhWnd As Long ' Suche mir die erste verfügbare Messagebox des ' Programmes und gebe dessen Handle zurück !! MSGBOXhWnd = FindFirstMsgbox(TopLevelHandle) If MSGBOXhWnd <> 0 Then Label1.Caption = "Messagebox gefunden!!! " & _ "Handle der MsgBox: " & MSGBOXhWnd & vbCrLf & _ "Handle der Anwendung: " & hwnd Else Label1.Caption = "KEINE Messagebox gefunden!!!" End If End Sub Starten Sie nun eine fremde Anwendung und wählen dort irgendeine Funktion bei der eine MessageBox erscheint. Öffnen Sie z.B. den Windows-Editor, geben einen kurzen Text ein und klicken dann auf das Schliessen-Symbol. Jetzt erscheint eine MsgBox mit dem Hinweis, ob die aktuelle Datei gespeichert werden soll. Lassen Sie die MsgBox zunächst am Bildschirm stehen... Starten Sie nun das VB Beispielsprojekt, und geben in der Einagbe-Aufforderung Unbenannt - Editor ein. Darauf wird sowohl der Fensterhandle des Windows-Editors, als auch der Handle der MsgBox angezeigt. Dieser Tipp wurde bereits 23.987 mal aufgerufen.
Anzeige
![]() ![]() ![]() (einschl. Beispielprojekt!) Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! - nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten - Symbol-Galerie mit mehr als 3.200 Icons im modernen Look Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m. |
Neu! sevCommand 4.0 ![]() Professionelle Schaltflächen im modernen Design! Mit nur wenigen Mausklicks statten auch Sie Ihre Anwendungen ab sofort mit grafischen Schaltflächen im modernen Look & Feel aus (WinXP, Office, Vista oder auch Windows 8), inkl. große Symbolbibliothek. Tipp des Monats ![]() Dieter Otter sevTabStrip: Rechtsklick auf Reiter erkennen Eine Funktion, mit der sich prüfen lässt, auf welchen Tab-Reiter ein Mausklick erfolgte TOP Entwickler-Paket ![]() TOP-Preis!! Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1866.50 EUR... |
||||||||||||||||
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein. |