ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 28.03.2000

Diese Seite wurde zuletzt aktualisiert am 28.03.2000
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Pop-It-Yourself

Zurück...


Anzeige

(-hg) mailto:hg_userpopupmenu@aboutvb.de

Sicher werden auch Sie sich schon gefragt haben, wie Sie das eingebaute Kontext-Menü einer TextBox durch ein eigenes Popup-Menü ersetzen können. Dazu werden unter anderem meistens zwei Lösungen auf dem "Know-How-Markt gehandelt", die sie vielleicht bereits kennen werden.

So wird verschiedentlich vorgeschlagen, im MouseUp-Ereignis der TextBox diese vorübergehend zu sperren (Enabled = False), das eigene Popup-Menü anzuzeigen, und die TextBox anschließend wieder freizugeben (Enabled = True):

Private Sub TextBox_MouseUp(Button As...)
  If Button = vbRightButton Then
    TextBox.Enabled = False
    Popupmenu MeinPopupMenu
    TextBox.Enabled = True
    TextBox.SetFocus
  End If
End Sub

Diese Lösung funktioniert zwar offensichtlich ganz gut. Sie hat aber einen entscheidenden Nachteil, der den Einsatz dieser Lösung fast verbietet: Die TextBox verliert während dessen den Fokus. Das hat aber zur Folge, dass das LostFocus-Ereignis der TextBox ausgelöst wird, sobald es gesperrt wird. Ist (wie standardmäßig eingestellt) die Eigenschaft CausesValidation der TextBox gesetzt, wird auch noch das Validate-Ereignis ausgelöst. Sind dazu weitere Steuerelemente auf dem Form vorhanden, erhält ein anderes dieser Steuerelemente den Fokus - und dessen GotFocus-Ereignis wird ausgelöst. Wird die Enabled-Eigenschaft der TextBox nach dem Schließen des Popup-Menüs wieder auf True gesetzt, muss der Fokus wieder auf die TextBox zurück gesetzt werden - die beschriebene Ereignisreihenfolge wird im umgekehrten Sinne ausgelöst: Für das Steuerelement, das zwischenzeitlich den Fokus erhalten hatte, wird das LostFocus-Ereignis ausgelöst, gegebenenfalls dort auch das Validate-Ereignis, und bei der TextBox nun das GotFocus-Ereignis.

Sie können sich bestimmt ganz leicht die Nebeneffekte vorstellen, die hierbei Ihre Anwendung ganz schön ins Stolpern bringen können, wenn Sie die betreffenden LostFocus- und GotFocus-Ereignisse für ganz andere Zwecke zu ganz anderen Zeitpunkten erwarten, und wenn Sie, was bei Datenbank-Forms wohl mit Sicherheit der Fall sein dürfte, ausgiebig von Validate-Ereignissen Gebrauch machen. Diese Lösung können Sie also nur ruhigen Gewissens verwenden, wenn Sie die betroffenen Focus- und Validate-Ereignisse keinesfalls verwenden werden. Ja, da steht: "verwenden werden"! Denn falls Sie (oder jemand anderes) später, nach dem Einsatz der beschriebenen Popup-Menü-Lösung, doch noch diese Ereignisse verwenden und vielleicht nicht an die damit verbundenen Komplikationen denken sollten, kommen Sie in Teufels Küche...

Die zweite häufig vorgeschlagene Lösung setzt auf Subclassing - auf das Abfangen der Nachricht WM_CONTEXTMENU. An und für sich ist das die sauberste Lösung - sie hält sich an den vom System vorgegebenen Mechanismus. Subclassing lässt sich zwar mit Visual Basic und ein paar API-Techniken einrichten, ist aber eher eine Angelegenheit für Fortgeschrittene. Wenn Sie diese Technik beherrschen, wäre es die empfehlenswerteste Lösung. Sie können auch eines der als Freeware, Shareware oder kommerziell erhältlichen Subclassing-Controls verwenden. Falls Sie jedoch nur wegen des Kontext-Menüs ein Subclassing für die TextBox einrichten (ob mit VB-Code oder mit einem Subclassing-Control), wäre der Aufwand gemessen am Nutzen sehr hoch (und bei VB-Code-Subclassing die Gefahr von Instabilitäten und Abstürzen wäre ebenfalls recht hoch).

So habe ich nach einer dritten Lösung gesucht - und sie gefunden. Ich habe mich einfach einmal gefragt, ob man nicht das MouseUp-Ereignis bei einem anderen Steuerelement ankommen lassen könnte, statt bei der TextBox. Denn dann sollte - hoffentlich - das eingebaute Kontext-Menü der TextBox nicht in die Quere kommen. Nach nur kurzem Herumprobieren mit einer PictureBox stellte sich heraus, dass das sogar recht einfach geht: Aus dem MouseDown-Ereignis der TextBox heraus (wenn Button = vbRightButton) senden Sie mit der API-Funktion MSDN Library - API SendMessageSendMessage die Nachricht WM_RBUTTONDOWN an eine PictureBox. Damit die TextBox den Fokus nicht verliert, wird die PictureBox schon von vornherein beim Entwurf unsichtbar gemacht (Visible = False) oder gesperrt (Enabled = False). Beim Loslassen der rechten Maustaste wird dann tatsächlich das MouseUp-Ereignis der PictureBox ausgelöst. Setzen Sie noch vor dem Aufruf von SendMessage die Tag-Eigenschaft der PictureBox auf den Namen des gewünschten Popup-Menüs, können Sie im MouseUp-Ereignis der PictureBox dieses Menü wieder anhand der Tag-Eigenschaft aus der Controls-Collection herausfischen und anzeigen. Wie das nachfolgende (und herunterladbare) Beispiel-Form mit zwei TextBoxen und zwei verschiedenen Popup-Menüs zeigt, reicht sogar eine einzige PictureBox auf einem Form für diese Lösung aus: Anhand der Tag-Eigenschaft können Sie ja beliebig differenzieren und gegebenenfalls in weitere Hilfsprozeduren verzweigen.

Private Declare Function SendMessage Lib "user32" _
 Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
 ByVal wParam As Long, lParam As Any) As Long

Private Const WM_RBUTTONDOWN = &H204

Private Sub picPopupMenu_MouseUp(Button As Integer, _
 Shift As Integer, X As Single, Y As Single)

  On Error Resume Next
  PopupMenu Me.Controls(picPopupMenu.Tag), vbPopupMenuRightButton
End Sub

Private Sub Text1_MouseDown(Button As Integer, _
 Shift As Integer, X As Single, Y As Single)

  If chkUserMenu1.Value Then
    If Button = vbRightButton Then
      With picPopupMenu
        .Tag = "mnuText1"
        SendMessage .hwnd, WM_RBUTTONDOWN, 0&, 0&
      End With
    End If
  End If
End Sub

Private Sub Text2_MouseDown(Button As Integer, _
 Shift As Integer, X As Single, Y As Single)

  If chkUserMenu2.Value Then
    If Button = vbRightButton Then
      With picPopupMenu
        .Tag = "mnuText2"
        SendMessage .hwnd, WM_RBUTTONDOWN, 0&, 0&
      End With
    End If
  End If
End Sub

Das funktioniert offensichtlich bei allen Steuerelementen, nicht nur bei der TextBox, wenn Sie ein eingebautes Kontext-Menü unterdrücken wollen (Natürlich gilt das ausschließlich unter der Voraussetzung, dass sich das Steuerelement an die Konvention hält, das Kontext-Menü erst beim Loslassen der rechten Maustaste anzuzeigen). Und es funktioniert sogar bei Steuerelementen, bei denen auch das Abfangen der WM_CONTEXTMENU-Nachricht per Subclassing fruchtlos bleibt - zum Beispiel werden in Visual Basic geschriebene UserControls wohl kaum mit dieser Nachricht dienen, sondern wahrscheinlich ein Kontext-Menü einfach während eines internen MouseUp-Ereignisses anzeigen.


Beispiel-Form UserPopupMenu (userpopupmenu.zip - ca. 1,5 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikel

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche



Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer