Die Community zu .NET und Classic VB.
Menü

VB.NET-Tipp 0123: Systemmenü bei Form mit FormBorderStyle = None verwenden

 von 

Beschreibung

Bei einer Form mit FormBorderStyle = None steht normalerweise das Systemmenü nicht zur Verfügung. Dieses Beispiel zeigt wie bei einer Form mit FormBorderStyle = None das Systemmenü dennoch verwendet werden kann. Gleichzeitig wird dadurch auch das Systemmenü des Eintrags in der Taskleiste wieder sichtbar.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Framework-Version(en):

.NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5

.NET-Version(en):

Visual Basic 2005, Visual Basic 2008

Download:

Download des Beispielprojektes [11,09 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 2005
' Option Strict:    An
'
' Referenzen: 
'  - System
'  - System.Data
'  - System.Deployment
'  - System.Drawing
'  - System.Windows.Forms
'  - System.Xml
'
' Imports: 
'  - Microsoft.VisualBasic
'  - System
'  - System.Collections
'  - System.Collections.Generic
'  - System.Data
'  - System.Drawing
'  - System.Diagnostics
'  - System.Windows.Forms
'

' ##############################################################################
' ################################# Form1.vb ###################################
' ##############################################################################
Option Strict On
Option Explicit On

Imports System.Runtime.InteropServices

Public Class Form1

    Private Const HTCAPTION As Integer = 2
    Private Const MF_BYCOMMAND As Integer = &H0&
    Private Const MF_GRAYED As Integer = &H1&
    Private Const TPM_RETURNCMD As Integer = &H100
    Private Const SC_MOVE As Integer = &HF010&
    Private Const WM_SYSCOMMAND As Integer = &H112

    Private SysMove As Boolean = False

    <DllImport("user32.dll", EntryPoint:="EnableMenuItem")> _
    Private Shared Function EnableMenuItem( _
        ByVal hMenu As IntPtr, _
        ByVal wIDEnableItem As Integer, _
        ByVal wEnable As Integer) As Integer
    End Function

    <DllImport("user32.dll", EntryPoint:="ReleaseCapture")> _
    Private Shared Function ReleaseCapture() As Integer
    End Function

    <DllImport("user32.dll", EntryPoint:="GetSystemMenu")> _
    Private Shared Function GetSystemMenu( _
        ByVal hwnd As IntPtr, _
        ByVal bRevert As Integer) As IntPtr
    End Function

    <DllImport("user32.dll", EntryPoint:="TrackPopupMenuEx")> _
    Private Shared Function TrackPopupMenuEx( _
        ByVal hMenu As IntPtr, _
        ByVal wFlags As Integer, _
        ByVal x As Integer, _
        ByVal y As Integer, _
        ByVal hWnd As IntPtr, _
        ByVal lpTpm As Integer) As Integer
    End Function

    Protected Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            Const WS_SYSMENU As Integer = &H80000
            Const WS_MAXIMIZEBOX As Integer = &H10000
            Const WS_MINIMIZEBOX As Integer = &H20000
            Dim oReturn As CreateParams = MyBase.CreateParams
            oReturn.Style = oReturn.Style Or WS_SYSMENU Or _
                WS_MAXIMIZEBOX Or WS_MINIMIZEBOX
            Return oReturn
        End Get
    End Property

    Protected Overrides Sub WndProc(ByRef m As Message)

        If m.Msg = WM_SYSCOMMAND Then

            Select Case m.WParam.ToInt32

                Case SC_MOVE

                    If Not SysMove Then
                        SetMovingCursor()
                        SysMove = True
                        Return
                    End If

            End Select

        End If

        MyBase.WndProc(m)
    End Sub

    Private Sub SetMovingCursor()

        Windows.Forms.Cursor.Position = _
            New Point(Me.Left + (Me.Width \ 2), Me.Top)

        Me.Cursor = Cursors.SizeAll

    End Sub

    Private Sub Form1_Load(ByVal sender As Object, _
        ByVal e As System.EventArgs) Handles Me.Load

        ' kann auch schon in der IDE eingestellt werden
        Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None

    End Sub

    Private Sub Form1_MouseDown(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown

        If SysMove Then

            ReleaseCapture()

            Me.WndProc(Message.Create(Me.Handle, WM_SYSCOMMAND, _
                CType(SC_MOVE Or HTCAPTION, IntPtr), IntPtr.Zero))

            Me.Cursor = Cursors.Default

            SysMove = False
        End If

    End Sub

    Private Sub Form1_MouseUp(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp

        Dim hSysMenu As IntPtr = GetSystemMenu(Me.Handle, 0)

        Select Case Me.WindowState
            Case FormWindowState.Normal
                EnableMenuItem(hSysMenu, SC_MOVE, MF_BYCOMMAND)
            Case FormWindowState.Maximized
                EnableMenuItem(hSysMenu, SC_MOVE, MF_BYCOMMAND Or MF_GRAYED)
        End Select

        Dim MenuCmd As Integer = TrackPopupMenuEx(hSysMenu, TPM_RETURNCMD, _
            Me.Left + e.X, Me.Top + e.Y, Me.Handle, 0)

        Me.WndProc(Message.Create(Me.Handle, WM_SYSCOMMAND, _
            CType(MenuCmd, IntPtr), IntPtr.Zero))

    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.

offene Windowsfenster ermitteln - Lutz Petzold 28.01.12 13:12 40 Antworten