Die Community zu .NET und Classic VB.
Menü

VB.NET-Tipp 0037: Größenbegrenzung für MDI-Kindfenster

 von 

Beschreibung

Windows Forms-Formulare besitzen die Eigenschaften MinimumSize und MaximumSize, über die die kleinste und grösste Grösse angegeben werden kann, die das Formular einnehmen kann. Allerdings hat diese Eigenschaft keine Auswirkung auf Formulare, die als untergeordnete Formulare einer MDI-Umgebung angezeigt werden. In diesem Beispiel wird durch Verwendung von API-Aufrufen auch eine Grössenbegrenzung für MDI-Kinder ermöglicht.

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 [8,26 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.Drawing
'  - System.Windows.Forms
'

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

Imports Microsoft.VisualBasic
Imports System
Imports System.Drawing
Imports System.Runtime.InteropServices

' <remarks>
'   Basisklasse, die <c>System.Windows.Forms.Form</c> 
'   um Eigenschaften zur Grösseneinstellung erweitert.
' </remarks>
'
' Sollte MustInherit deklariert werden, was 
' aber dem Windows Forms-Designer Probleme macht.
'
Public Class ExtendedForm
    Inherits System.Windows.Forms.Form

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

    ' Wir subclassen nach dieser Message.
    Private Const WM_GETMINMAXINFO As Int32 = &H24

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure MINMAXINFO
        Public ptReserved As POINTAPI
        Public ptMaxSize As POINTAPI
        Public ptMaxPosition As POINTAPI
        Public ptMinTrackSize As POINTAPI
        Public ptMaxTrackSize As POINTAPI
    End Structure

    ' Deklarationen für die verwendeten API-Funktionen.
    Private Declare Sub CopyMemory Lib "kernel32.dll" _
      Alias "RtlMoveMemory" ( _
      ByVal lpDest As IntPtr, _
      ByRef lpSource As MINMAXINFO, _
      ByVal cBytes As Int32)

    Private Declare Sub CopyMemory Lib _
      "kernel32.dll" Alias "RtlMoveMemory" ( _
      ByRef lpDest As MINMAXINFO, _
      ByVal lpSource As IntPtr, _
      ByVal cBytes As Int32)

    ' Private Membervariablen zum Speichern #
    ' der Eigenschaftswerte.
    Private m_ptMaximizedLocation As Point
    Private m_sizeMaxTrackSize As Size
    Private m_sizeMaximumSize As Size
    Private m_sizeMinimumSize As Size


    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Select Case m.Msg
            Case WM_GETMINMAXINFO

                ' Dimensionieren einer Variablen, um die Daten 
                ' für die von Windows in lParam
                ' übergebenen Daten zu halten.
                Dim mmi As MINMAXINFO

                ' Kopieren der Struktur, die an lParam im 
                ' Speicher steht, in unseren UDT.
                Call CopyMemory(mmi, m.LParam, Len(mmi))

                With mmi
                    If Me.MaximumSize.Width <> 0 Then
                        .ptMaxSize.x = Me.MaximumSize.Width
                    End If
                    If Me.MaximumSize.Height <> 0 Then
                        .ptMaxSize.y = Me.MaximumSize.Height
                    End If
                    If Me.MaximumTrackSize.Width <> 0 Then
                        .ptMaxTrackSize.x = Me.MaximumTrackSize.Width
                    End If
                    If Me.MaximumTrackSize.Height <> 0 Then
                        .ptMaxTrackSize.y = Me.MaximumTrackSize.Height
                    End If
                    If Me.MinimumSize.Width <> 0 Then
                        .ptMinTrackSize.x = Me.MinimumSize.Width
                    End If
                    If Me.MinimumSize.Height <> 0 Then
                        .ptMinTrackSize.y = Me.MinimumSize.Height
                    End If
                    .ptMaxPosition.x = Me.MaximizedLocation.X
                    .ptMaxPosition.y = Me.MaximizedLocation.Y
                End With

                ' Zurückkopieren der angepassten Struktur an Windows.
                Call CopyMemory(m.LParam, mmi, Len(mmi))

                ' Zurückgeben von 0, das bedeutet, dass wir 
                ' die Message abgearbeitet haben.
                m.Result = IntPtr.Zero

                ' Ausstieg aus der Funktion, ohne VB seine 
                ' kleinen Händchen an die Message
                ' zu lassen.
                Return
        End Select

        ' Meldung an VB .NET weiterreichen.
        MyBase.WndProc(m)
    End Sub

    ' <summary>
    '   Gibt die minimale Grösse des Formulars 
    '   an oder gibt sie zurück.
    ' </summary>
    ' <value></value>
    '
    ' Überschatten wäre wahrscheinlich nicht erforderlich.
    '
    Public Shadows Property MinimumSize() As Size
        Get
            Return m_sizeMinimumSize
        End Get
        Set(ByVal Value As Size)
            m_sizeMinimumSize = Value
        End Set
    End Property

    ' <summary>
    '   Gibt die maximale Grösse des Formulars 
    '   an oder gibt sie zurück.
    ' </summary>
    ' <value>Maximale Grösse des Formulars.</value>
    '
    ' Überschatten wäre wahrscheinlich nicht erforderlich.
    '
    Public Shadows Property MaximumSize() As Size
        Get
            Return m_sizeMaximumSize
        End Get
        Set(ByVal Value As Size)
            m_sizeMaximumSize = Value
        End Set
    End Property

    ' <summary>
    '   Gibt die Position des Formulars, wenn 
    '   dieses in seiner Grösse begrenzt
    '   und maximiert dargestellt wird, an 
    '   oder gibt sie zurück.
    ' </summary>
    ' <value>Position des Formulars im maximierten Zustand.</value>
    Public Property MaximizedLocation() As Point
        Get
            Return m_ptMaximizedLocation
        End Get
        Set(ByVal Value As Point)
            m_ptMaximizedLocation = Value
        End Set
    End Property

    ' <summary>
    '   Gibt die maximale Track-Grösse des 
    '   Formulars an oder gibt sie zurück.
    ' </summary>
    ' <value>Maximale Track-Grösse des Formulars.</value>
    '
    ' Diese Eigenschaft ist für die Verwendung des 
    ' Formulars auf mehreren Bildschirmen interessant.
    ' Näheres dazu in der Dokumentation zu MINMAXINFO 
    ' in der MSDN.
    '
    Public Property MaximumTrackSize() As Size
        Get
            Return m_sizeMaxTrackSize
        End Get
        Set(ByVal Value As Size)
            m_sizeMaxTrackSize = Value
        End Set
    End Property
End Class
' ##############################################################################
' ################################ MainForm.vb #################################
' ##############################################################################
Option Explicit On 
Option Strict On
Option Compare Binary

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


    Private Sub btnLoadChild_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles btnLoadChild.Click

        Dim frm As New MyExtendedForm()
        frm.MdiParent = Me
        frm.Show()
    End Sub

    Private Sub btnLoadWindow_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles btnLoadWindow.Click

        Dim frm As New MyExtendedForm()
        frm.Show()
    End Sub
End Class
' ##############################################################################
' ############################# MyExtendedForm.vb ##############################
' ##############################################################################
Option Explicit On 
Option Strict On
Option Compare Binary

Imports System
Imports System.Drawing

' <remarks>
'   Beispielimplementierung für ein Formuar 
'   mit beschränkter Grösse.
' </remarks>
Public Class MyExtendedForm
    Inherits MinMaxFormSize.ExtendedForm


    Private Sub txtMinimumSizeHeight_Validating(ByVal sender As Object, _
        ByVal e As System.ComponentModel.CancelEventArgs) _
        Handles txtMinimumSizeHeight.Validating

        Dim d As Double
        If Double.TryParse(Me.txtMinimumSizeHeight.Text, _
            Globalization.NumberStyles.Integer And Not _
            Globalization.NumberStyles.AllowLeadingSign, Nothing, d) Then

            Dim s As New Size()
            s.Width = Me.MinimumSize.Width
            s.Height = CInt(d)
            Me.MinimumSize = s
        Else
            Me.txtMinimumSizeHeight.Text = "0"
        End If
    End Sub

    Private Sub txtMinimumSizeWidth_Validating(ByVal sender As Object, _
        ByVal e As System.ComponentModel.CancelEventArgs) _
        Handles txtMinimumSizeWidth.Validating

        Dim d As Double
        If Double.TryParse(Me.txtMinimumSizeWidth.Text, _
            Globalization.NumberStyles.Integer And Not _
            Globalization.NumberStyles.AllowLeadingSign, Nothing, d) Then

            Dim s As New Size()
            s.Width = CInt(d)
            s.Height = Me.MinimumSize.Height
            Me.MinimumSize = s
        Else
            Me.txtMinimumSizeWidth.Text = "0"
        End If
    End Sub

    Private Sub txtMaximumSizeHeight_Validating(ByVal sender As Object, _
        ByVal e As System.ComponentModel.CancelEventArgs) _
        Handles txtMaximumSizeHeight.Validating

        Dim d As Double
        If Double.TryParse(Me.txtMaximumSizeHeight.Text, _
            Globalization.NumberStyles.Integer And Not _
            Globalization.NumberStyles.AllowLeadingSign, Nothing, d) Then

            Dim s As New Size()
            s.Width = Me.MaximumSize.Width
            s.Height = CInt(d)
            Me.MaximumSize = s

            ' Sicherheitshalber auch diese Werte setzen, 
            ' sonst kann es zu Fehlern kommen.
            Me.MaximumTrackSize = s
        Else
            Me.txtMaximumSizeHeight.Text = "0"
        End If
    End Sub

    Private Sub txtMaximumSizeWidth_Validating(ByVal sender As Object, _
        ByVal e As System.ComponentModel.CancelEventArgs) _
        Handles txtMaximumSizeWidth.Validating

        Dim d As Double
        If Double.TryParse(Me.txtMaximumSizeWidth.Text, _
            Globalization.NumberStyles.Integer And Not _
            Globalization.NumberStyles.AllowLeadingSign, Nothing, d) Then

            Dim s As New Size()
            s.Width = CInt(d)
            s.Height = Me.MaximumSize.Height
            Me.MaximumSize = s

            ' Sicherheitshalber auch diese Werte setzen, 
            ' sonst kann es zu Fehlern kommen.
            Me.MaximumTrackSize = s
        Else
            Me.txtMaximumSizeWidth.Text = "0"
        End If
    End Sub

    Private Sub txtMaximizedLocationX_Validating(ByVal sender As Object, _
        ByVal e As System.ComponentModel.CancelEventArgs) _
        Handles txtMaximizedLocationX.Validating

        Dim d As Double
        If Double.TryParse(Me.txtMaximizedLocationX.Text, _
            Globalization.NumberStyles.Integer And Not _
            Globalization.NumberStyles.AllowLeadingSign, Nothing, d) Then

            Dim pt As New Point()
            pt.X = CInt(d)
            pt.Y = Me.MaximizedLocation.Y
            Me.MaximizedLocation = pt
        Else
            Me.txtMaximizedLocationX.Text = "0"
        End If
    End Sub

    Private Sub txtMaximizedLocationY_Validating(ByVal sender As Object, _
        ByVal e As System.ComponentModel.CancelEventArgs) _
        Handles txtMaximizedLocationY.Validating

        Dim d As Double
        If Double.TryParse(Me.txtMaximizedLocationY.Text, _
            Globalization.NumberStyles.Integer And Not _
            Globalization.NumberStyles.AllowLeadingSign, Nothing, d) Then

            Dim pt As New Point()
            pt.X = Me.MaximizedLocation.X
            pt.Y = CInt(d)
            Me.MaximizedLocation = pt
        Else
            Me.txtMaximizedLocationY.Text = "0"
        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 1 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 Timo Böhme am 31.07.2007 um 22:38

Hallo. Habe das nur schnell ausprobiert. Aber ich habe nicht verstanden was hier begrenz sein sollte. Für mich funktionierten die Fenster ohne Einschränkungseffekt.