Die Community zu .NET und Classic VB.
Menü

VB.NET-Tipp 0001: Popupmenus per API ausgerichtet anzeigen

 von 

Beschreibung

Dieses Beispiel zeigt, wie man über API-Funktionen ein Pop-Up-Menü erstellt, das auch ein Untermenü besitzt und dieses mit verschiedenen Ausrichtungen anzeigt.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Framework-Version(en):

.NET Framework 1.0, .NET Framework 1.1, .NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5

.NET-Version(en):

Visual Basic 2002, Visual Basic 2003, Visual Basic 2005, Visual Basic 2008

Download:

Download des Beispielprojektes [4,02 KB]

' 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!

' Projektversion:   Visual Studio 2002/2003
' Option Strict:    An
' Option Explicit:  An
'
' Referenzen: 
'  - System
'  - System.Windows.Forms
'  - System.Drawing
'

' ##############################################################################
' ################################ MainForm.vb #################################
' ##############################################################################
Option Explicit On 
Option Strict On
Option Compare Binary

Imports Microsoft.VisualBasic
Imports System
Imports System.Runtime.InteropServices
Imports System.Windows.Forms

' <remarks>
'   Hauptformular der Anwendung.
' </remarks>
Public Class MainForm
    Inherits System.Windows.Forms.Form

    Private Declare Function CreatePopupMenu _
      Lib "user32.dll" () As IntPtr
    Private Declare Function DestroyMenu _
      Lib "user32.dll" (ByVal hMenu As IntPtr) As Int32
    Private Declare Function AppendMenu _
      Lib "user32.dll" Alias "AppendMenuA" ( _
      ByVal hMenu As IntPtr, _
      ByVal wFlags As Int32, _
      ByVal wIDNewItem As IntPtr, _
      ByVal lpNewItem As String) As Int32
    Private Declare Function ClientToScreen _
      Lib "user32.dll" ( _
      ByVal hWnd As IntPtr, _
      ByRef lpPoint As POINTAPI) As Int32
    Private Declare Function TrackPopupMenu _
      Lib "user32.dll" ( _
      ByVal hMenu As IntPtr, _
      ByVal wFlags As Int32, _
      ByVal x As Int32, _
      ByVal y As Int32, _
      ByVal nReserved As Int32, _
      ByVal hWnd As IntPtr, _
      ByVal lpRect As Int32) As IntPtr
    Private Declare Function EnableMenuItem _
      Lib "user32.dll" ( _
      ByVal hMenu As IntPtr, _
      ByVal wIDEnableItem As IntPtr, _
      ByVal wEnable As Int32) As Int32

    Private Const MF_INSERT As Int32 = &H0
    Private Const MF_CHANGE As Int32 = &H80
    Private Const MF_APPEND As Int32 = &H100
    Private Const MF_DELETE As Int32 = &H200
    Private Const MF_REMOVE As Int32 = &H1000
    Private Const MF_BYCOMMAND As Int32 = &H0
    Private Const MF_BYPOSITION As Int32 = &H400
    Private Const MF_SEPARATOR As Int32 = &H800
    Private Const MF_ENABLED As Int32 = &H0
    Private Const MF_GRAYED As Int32 = &H1
    Private Const MF_DISABLED As Int32 = &H2
    Private Const MF_UNCHECKED As Int32 = &H0
    Private Const MF_CHECKED As Int32 = &H8
    Private Const MF_USECHECKBITMAPS As Int32 = &H200
    Private Const MF_STRING As Int32 = &H0
    Private Const MF_BITMAP As Int32 = &H4
    Private Const MF_OWNERDRAW As Int32 = &H100
    Private Const MF_POPUP As Int32 = &H10
    Private Const MF_MENUBARBREAK As Int32 = &H20
    Private Const MF_MENUBREAK As Int32 = &H40
    Private Const MF_UNHILITE As Int32 = &H0
    Private Const MF_HILITE As Int32 = &H80
    Private Const MF_SYSMENU As Int32 = &H2000
    Private Const MF_HELP As Int32 = &H4000
    Private Const MF_MOUSESELECT As Int32 = &H8000

    Private Const TPM_RETURNCMD As Int32 = &H100
    Private Const TPM_RIGHTBUTTON As Int32 = &H2
    Private Const TPM_RIGHTALIGN As Int32 = &H8
    Private Const TPM_LEFTBUTTON As Int32 = &H0
    Private Const TPM_LEFTALIGN As Int32 = &H0
    Private Const TPM_CENTERALIGN As Int32 = &H4

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure POINTAPI
        Public x As Int32
        Public y As Int32
    End Structure

    Private m_hPopup As IntPtr
    Private m_hEdit As IntPtr
    Private m_intAlignment As Int32

    ' Das sind eigentlich Konstanten, nur man 
    ' kann keine IntPtr-Konstanten definieren.
    Private ID_BEEP As IntPtr = New IntPtr(&H6000)
    Private ID_SEPERATOR As IntPtr = New IntPtr(&H6001)
    Private ID_DISABLED As IntPtr = New IntPtr(&H6002)
    Private ID_MSGBOX As IntPtr = New IntPtr(&H6003)
    Private ID_EDIT As IntPtr = New IntPtr(&H6004)
    Private ID_PASTE As IntPtr = New IntPtr(&H6005)


    Private Sub MainForm_MouseUp( _
      ByVal sender As Object, _
      ByVal e As System.Windows.Forms.MouseEventArgs) _
      Handles MyBase.MouseUp
        If e.Button = MouseButtons.Right Then
            If m_hPopup.Equals(IntPtr.Zero) Then

                ' Untermenü erstellen.
                m_hEdit = CreatePopupMenu()

                ' Einige Elemente dem Untermenü hinzufügen.
                AppendMenu(m_hEdit, MF_STRING, ID_EDIT, "&Edit")
                AppendMenu(m_hEdit, MF_STRING, ID_PASTE, "&Paste")

                ' Unser Pop-Up-Menü erstellen.
                m_hPopup = CreatePopupMenu()

                ' Einen Eintrag hinzufügen.
                AppendMenu(m_hPopup, MF_STRING, ID_BEEP, _
                  "&Sound a ""Beep""")

                ' Einen Separator hinzufügen.
                AppendMenu(m_hPopup, MF_STRING Or MF_SEPARATOR, _
                  ID_SEPERATOR, vbNullString)

                ' Eintrag, dem ein Untermenü hinzugefügt wird, hinzufügen.
                AppendMenu(m_hPopup, MF_STRING Or MF_POPUP, _
                  m_hEdit, "Popup &Menu")

                ' Ein weiterer Eintrag.
                AppendMenu(m_hPopup, MF_STRING, ID_DISABLED, _
                  "&A Disabled Item")

                ' Zuöetzt hinzugefügtes Menüelement deaktivieren.
                EnableMenuItem(m_hPopup, ID_DISABLED, _
                  MF_BYCOMMAND Or MF_DISABLED Or MF_GRAYED)

                ' Letzter Menüeintrag.
                AppendMenu(m_hPopup, MF_STRING, _
                  ID_MSGBOX, "&Display a MessageBox")
            End If

            Dim pt As POINTAPI
            With pt

                ' Position, an der das Menü angezeigt werden soll.
                .x = e.X
                .y = e.Y

                ' In Bildschirmkoodinaten umwandeln.
                ClientToScreen(Me.Handle, pt)

                ' Pop-Up-Menü anzeigen.
                Dim ptrSelectedItem As IntPtr = TrackPopupMenu( _
                  m_hPopup, TPM_RETURNCMD Or m_intAlignment, _
                  .x, .y, 0, _
                  Me.Handle, 0)
                If ptrSelectedItem.Equals(ID_BEEP) Then
                    Beep()
                ElseIf ptrSelectedItem.Equals(ID_MSGBOX) Then
                    MessageBox.Show("This is a MessageBox.", _
                      "Menü gewählt", _
                      MessageBoxButtons.OK, _
                      MessageBoxIcon.Information)
                ElseIf ptrSelectedItem.Equals(ID_EDIT) Then
                    MessageBox.Show("You chose ""Edit"".", _
                      "Menü gewählt", _
                      MessageBoxButtons.OK, _
                      MessageBoxIcon.Information)
                ElseIf ptrSelectedItem.Equals(ID_PASTE) Then
                    MessageBox.Show("You chose ""Paste"".", _
                      "Menü gewählt", _
                      MessageBoxButtons.OK, _
                      MessageBoxIcon.Information)
                End If
            End With
        End If
    End Sub

    Private Sub MainForm_Closing( _
      ByVal sender As Object, _
      ByVal e As System.ComponentModel.CancelEventArgs) _
      Handles MyBase.Closing
        If m_hPopup.Equals(IntPtr.Zero) Then
            DestroyMenu(m_hPopup)
            DestroyMenu(m_hEdit)
        End If
    End Sub

    Private Sub cboAlignment_SelectedIndexChanged( _
      ByVal sender As System.Object, _
      ByVal e As System.EventArgs) _
      Handles cboAlignment.SelectedIndexChanged
        If Me.cboAlignment.SelectedIndex = 0 Then
            m_intAlignment = TPM_LEFTALIGN
        ElseIf Me.cboAlignment.SelectedIndex = 1 Then
            m_intAlignment = TPM_CENTERALIGN
        Else
            m_intAlignment = TPM_RIGHTALIGN
        End If
    End Sub
End Class

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 2 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 Herfried K. Wagner [AVB] am 09.08.2004 um 12:28

@Jens: Nach entsprechender Anpassung der Deklaration sollte die Funktion auch unter VB6 funktionieren (http://www.activevb.de/rubriken/apikatalog/deklarationen/enablemenuitem.html).

Kommentar von Jens am 04.11.2003 um 10:10

Hab versucht das ganze auf VB 6 zu portieren das meiste geht auch, hab aber´n Problem mit:

Function EnableMenuItem Lib "user32.dll"

Aber wahrscheinlich geht das nur bei .NET! Hat jmd. ne andre Lösung für VB 6