DevCity.NET - http://devcity.net
Restricting Form Size - windows message subclassing example
http://devcity.net/Articles/30/1/20020226.aspx
Steven Sartain

Steven Sartain is a consultant currently designing and leading a VB.NET project using n-tier architecture and WebServices for Accuride International Ltd.

During his 8 year career as a developer and development lead, Steve has designed and implemented a diverse number of mission critical software solutions using VB, VBA, MS Access, C/C++, ASP, Delphi, DCOM & MTS, SQL Server, Oracle, SQL Anywhere and others. See his Resume for details.

He is also a Director of Iridium Software - a UK based bespoke software development house.

Steve is always open to take over a challenging programming opportunity. If you experience a need for a professional consultant who has all the necessary skills to take a proposition from first client meeting through to profitably and elegantly completed projects; I'm sure Steve could assist. See his Resume and Professional Statement for details.

 
by Steven Sartain
Published on 2/26/2002
 
Although VB.NET gives us a property to restrict the forms minimum and maximun sizes, this example aids in familiarising developers with the "new way" or peforming windows message subclassing.

Restricting Form Size - windows message subclassing example

Although VB.NET gives us a property to restrict the forms minimum and maximun sizes, this example aids in familiarising developers with the "new way" or peforming windows message subclassing.

Start a new project then add a form. Add the following code to the form:

'Author: Steven Sartain
'Last Revision: 28th August 2001
'Revision Notes: None
'Supported environments:
'                 Yes    No    Untested
'  VB4                    X
'  VB5                    X
'  VB6                    X
'  VB.NET(beta2)   X

Imports System.Windows.Forms
Imports System.ComponentModel

Namespace vbCity
  Namespace FormClasses
    Public Class frmRestricted
      Inherits Form

'#Region " Iridium form properties code "

      Private mFormMinSizemFormMaxSize As PointAPI

      <Category("FormSize"), _
          Description_
          "The Minimum height that the form can be sized to.")> _
      Public Property FormMinHeight() As Int32
        Get
          ' SCS - A return of zero indicates that it has not been 
          ' set.
           Return mFormMinSize.y
        End Get
        Set(ByVal Value As Int32)
          CheckBounds(ValueFalse)
          mFormMinSize.y = Value
        End Set
      End Property ' FormMinHeight
      
      <Category("FormSize"), _
          Description_
          "The Maximum height that the form can be sized to.")> _
      Public Property FormMaxHeight() As Int32
        Get
          ' SCS - A return of zero indicates that it has not been 
          ' set.
          Return mFormMaxSize.y
        End Get
        Set(ByVal Value As Int32)
          CheckBounds(ValueFalse)
          mFormMaxSize.y = Value
        End Set
      End Property ' FormMaxHeight

      <Category("FormSize"), _
          Description_
          "The Minimum width that the form can be sized to.")> _
      Public Property FormMinWidth() As Int32
        Get
          ' SCS - A return of zero indicates that it has not been 
          ' set.
          Return mFormMinSize.x
        End Get
        Set(ByVal Value As Int32)
          CheckBounds(ValueFalse)
          mFormMinSize.x = Value
        End Set
      End Property ' FormMinWidth
      
      <Category("FormSize"), _
          Description_
          "The Maximum width that the form can be sized to.")> _
      Public Property FormMaxWidth() As Int32
        Get
          ' SCS - A return of zero indicates that it has not been 
          ' set.
          Return mFormMaxSize.x
        End Get
        Set(ByVal Value As Int32)
          CheckBounds(ValueFalse)
          mFormMaxSize.x = Value
        End Set
      End Property ' FormMaxWidth
#End Region

      Private Sub CheckBounds(ByRef pintValue As Int32_
          ByVal pblnCheckWidth As Boolean)
        If pintValue < 0 Then
          pintValue = 0
        Else
          ' SCS - Check that the Co-ords are not outside of the 
          ' screen here?
          Dim ScreenPoint As System.Drawing.Rectangle
          ScreenPoint = Screen.PrimaryScreen.Bounds()

          If pblnCheckWidth Then
            If pintValue > ScreenPoint.Width Then pintValue = _
                ScreenPoint.Width
          Else
            If pintValue > ScreenPoint.Height Then pintValue = _
                ScreenPoint.Height
          End If

        End If
      End Sub

      Protected Overrides Sub WndProc_
          ByRef m As System.Windows.Forms.Message)
        If m.Msg = WM_GETMINMAXINFO Then
          Dim mmiStruct As MinMaxInfo

          MyBase.WndProc(m)
          ' SCS - Get the information from lParam into our 
          ' structure
          mmiStruct = CType(m.GetLParam(mmiStruct.GetType()), _
              MinMaxInfo)
          ' SCS - The following line does the same - I haven't yet 
          ' tested for speed to
          ' see which is the quickest
          '    mmiStruct = CType(Marshal.PtrToStructure(m.lParam, 
          ' mmiStruct.GetType), MinMaxInfo)
          ' SCS - Set new structure values where applicable
          With mmiStruct

            If Not (mFormMaxSize.x.Equals(0)) Then
              .ptMaxTrackSize.x = mFormMaxSize.x
            End If
            
            If Not (mFormMaxSize.y.Equals(0)) Then
              .ptMaxTrackSize.y = mFormMaxSize.y
            End If
            
            If Not (mFormMinSize.x.Equals(0)) Then
              .ptMinTrackSize.x = mFormMinSize.x
            End If
            
            If Not (mFormMinSize.y.Equals(0)) Then
              .ptMinTrackSize.y = mFormMinSize.y
            End If
            '.ptMaxPosition.x = 100
            '.ptMaxSize.x = 200
          End With
          ' SCS - Copy the information back into lParam
          Marshal.StructureToPtr(mmiStructm.LParamTrue)
          ' SCS - Return 0 because MSDN tells us to.
          m.Result() = New System.IntPtr()
        Else
          MyBase.WndProc(m)
        End If
      End Sub
    End Class
  End Namespace

  Namespace API
    Public Class clsGetMinMaxInfo
      
      'Microsoft.Win32.Interop.Win.WM_GETMINMAXINFO
      Public Const WM_GETMINMAXINFO As Int32 = 100

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

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

      <StructLayout(LayoutKind.Sequential)> _
      Public Structure WindowPos
        Public hwnd As Int32
        Public hWndInsertAfter As Int32
        Public x As Int32
        Public y As Int32
        Public cx As Int32
        Public cy As Int32
        Public flags As Int32
      End Structure
    End Class
  End Namespace

End Namespace
Generated using PrettyCode.Encoder