Link to home
Start Free TrialLog in
Avatar of really24
really24Flag for United States of America

asked on

Capture a Specific Type of Resize Event

The Resize event gets called when ever I change the Left,Top,Width or Height properties in the code

For Example:
Me.Height = 1111
Me.Width = 1111

The Resize event also gets called when a user drags and resizes the form using the mouse.

My Question is:

How do I differentiate between the two? I only want certain resize code to get executed when the user drags. But if I just put the code in the resize event it gets called also when I do something like Me.Height and I don't want that.

Any Suggestions?
Avatar of unknown_routine
unknown_routine
Flag of United States of America image

Hi,

to skip the code when using Me.Height = 1111
 or Me.Width = 1111 you need a flag , blnResize





Dim blnResize As Boolean  '<=== flag put this on the top of your form
 
Private Sub Command1_Click()
blnresize = False
Me.Height = 1111
blnresize = False
Me.Width = 1111

End Sub

Private Sub Form_Resize()

If blnResize=true Then
  'do some action
   MsgBox "drag happened"
Else ' Do Nothing

End If

blnResize = True

End Sub




Now code inside resize  execued  only when user Drag-Resizes the form.

regards.
Just keep in mind that anywhere inside your code before lines like Me.Height = 1111
 you must set the resize flag to false.
Avatar of really24

ASKER

Yes, I thought about doing this, but I was actually hoping there was another way ...
If the user sizes a window, the form gets the WM_SIZING message.  The bad news is that VB doesn't expose that in the interface.  The good news is that you can subclass your form to intercept or just detect the messages.

Here is an example of how to do this in VB.  If you need more help, just ask.

"Maintaining Form Aspect Ratio During Resizing"
http://vbnet.mvps.org/index.html?code/subclass/aspectratio.htm
really24 :

there is no way to cancel pre-built in resize even in forms.

The only way is to go around it.
Avatar of Mike Tomlinson
Here is an example of two different kinds of form sizing restrictions in action.  One prevents the user from moving the from outside the specified screen coordinates and causes the maximized form to fill that region.  The other keeps the form inside the bounding area as it is resized and prevents the from from being minimized past a specified size.

Between the two sizing restrictions, you should be able to do anything you want with the form.

Create a new project and add a Module.  Paste the code below into the appropriate areas as labeled.

Regards,

Idle_Mind

' ----------------------------------------------------------
' Form1
' ----------------------------------------------------------
Option Explicit

Private Sub Form_Load()
    ' my system is set @ 1024x768 resolution

    ' form may not move/resize past these coordinates
    Bounds.left = 256
    Bounds.top = 192
    Bounds.right = 768
    Bounds.bottom = 576
   
    ' define the minimum size of the form
    minWidth = 125
    minHeight = 100
   
    ' subclass the window
    HookWindow Me.hwnd
End Sub

Private Sub Form_Unload(Cancel As Integer)
    HookWindow Me.hwnd
End Sub

' ----------------------------------------------------------
' Module1
' ----------------------------------------------------------
Option Explicit

Private Type POINTAPI
    x As Long
    y As Long
End Type

Type RECT
   left As Long
   top As Long
   right As Long
   bottom As Long
End Type

Private Type MINMAXINFO
    ptReserved As POINTAPI
    ptMaxSize As POINTAPI
    ptMaxPosition As POINTAPI
    ptMinTrackSize As POINTAPI
    ptMaxTrackSize As POINTAPI
End Type

Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private Const GWL_WNDPROC As Long = (-4)
Private Const WM_GETMINMAXINFO = &H24
Public Const WM_MOVING = &H216
Public Const WM_SIZING = &H214

Public Const WMSZ_LEFT = 1
Public Const WMSZ_RIGHT = 2
Public Const WMSZ_TOP = 3
Public Const WMSZ_TOPLEFT = 4
Public Const WMSZ_TOPRIGHT = 5
Public Const WMSZ_BOTTOM = 6
Public Const WMSZ_BOTTOMLEFT = 7
Public Const WMSZ_BOTTOMRIGHT = 8

Public Bounds As RECT
Public minWidth As Single
Public minHeight As Single

Private lPrevProc As Long

Public Sub HookWindow(ByVal lHandle As Long)
    If lPrevProc = 0 Then
        lPrevProc = SetWindowLong(lHandle, GWL_WNDPROC, AddressOf HookProc)
    Else
        Call SetWindowLong(lHandle, GWL_WNDPROC, lPrevProc)
    End If
End Sub

Public Function HookProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim typMinMaxInfo As MINMAXINFO
    Dim rc As RECT
   
    Select Case uMsg
        Case WM_GETMINMAXINFO
            Call CopyMemory(ByVal typMinMaxInfo, ByVal lParam, Len(typMinMaxInfo))
           
            ' make form maximize into bounding rectangle
            typMinMaxInfo.ptMaxPosition.x = Bounds.left
            typMinMaxInfo.ptMaxPosition.y = Bounds.top
            typMinMaxInfo.ptMaxSize.x = Bounds.right - Bounds.left
            typMinMaxInfo.ptMaxSize.y = Bounds.bottom - Bounds.top
                       
            Call CopyMemory(ByVal lParam, ByVal typMinMaxInfo, Len(typMinMaxInfo))
             
        Case WM_SIZING
            CopyMemory rc, ByVal lParam, Len(rc)
           
            ' enforce minimum size
            Select Case wParam
                Case WMSZ_LEFT
                    If rc.right - rc.left < minWidth Then
                        rc.left = rc.right - minWidth
                    End If
                   
                Case WMSZ_RIGHT
                    If rc.right - rc.left < minWidth Then
                        rc.right = rc.left + minWidth
                    End If
                   
                Case WMSZ_TOP
                    If rc.bottom - rc.top < minHeight Then
                        rc.top = rc.bottom - minHeight
                    End If
                   
                Case WMSZ_BOTTOM
                    If rc.bottom - rc.top < minHeight Then
                        rc.bottom = rc.top + minHeight
                    End If
               
                Case WMSZ_TOPLEFT
                    If rc.bottom - rc.top < minHeight Then
                        rc.top = rc.bottom - minHeight
                    End If
                    If rc.right - rc.left < minWidth Then
                        rc.left = rc.right - minWidth
                    End If
               
                Case WMSZ_TOPRIGHT
                    If rc.bottom - rc.top < minHeight Then
                        rc.top = rc.bottom - minHeight
                    End If
                    If rc.right - rc.left < minWidth Then
                        rc.right = rc.left + minWidth
                    End If
                   
                Case WMSZ_BOTTOMLEFT
                    If rc.bottom - rc.top < minHeight Then
                        rc.bottom = rc.top + minHeight
                    End If
                    If rc.right - rc.left < minWidth Then
                        rc.left = rc.right - minWidth
                    End If
                   
                Case WMSZ_BOTTOMRIGHT
                        If rc.bottom - rc.top < minHeight Then
                        rc.bottom = rc.top + minHeight
                    End If
                    If rc.right - rc.left < minWidth Then
                        rc.right = rc.left + minWidth
                    End If
                   
            End Select
           
            ' keep form inside bounding rectangle
            If rc.left < Bounds.left Then
                rc.left = Bounds.left
            End If
            If rc.top < Bounds.top Then
                rc.top = Bounds.top
            End If
            If rc.right > Bounds.right Then
                rc.right = Bounds.right
            End If
            If rc.bottom > Bounds.bottom Then
                rc.bottom = Bounds.bottom
            End If
           
            CopyMemory ByVal lParam, rc, Len(rc)
           
        Case WM_MOVING
            CopyMemory rc, ByVal lParam, Len(rc)
           
            ' keep form inside bounding rectangle
            If rc.left < Bounds.left Then
                rc.right = rc.right + (Bounds.left - rc.left)
                rc.left = Bounds.left
            End If
            If rc.top < 192 Then
                rc.bottom = rc.bottom + (Bounds.top - rc.top)
                rc.top = Bounds.top
            End If
            If rc.right > 768 Then
                rc.left = rc.left - (rc.right - Bounds.right)
                rc.right = Bounds.right
            End If
            If rc.bottom > Bounds.bottom Then
                rc.top = rc.top - (rc.bottom - Bounds.bottom)
                rc.bottom = Bounds.bottom
            End If
            CopyMemory ByVal lParam, rc, Len(rc)
           
    End Select
    HookProc = CallWindowProc(lPrevProc, hwnd, uMsg, wParam, lParam)
End Function
Avatar of TMacT
TMacT

Hi,

You can declare a variable in the FORM header to act as as flag, then set it in the Form_MouseDown and Form_MouseUp subs. During the Resize event, if the MOUSE button is being clicked, then the User is dragging the form.

Would that do the trick ?

... TMacT
TMacT,

The Form_MouseDown and Form_MouseUp events don't fire when you move or resize a form.

Idle_Mind
Nevermind. That does not work.
the point is that diabling the form_resize event when form actually resizes like Me.Height = 1111
might not be a good practice.

 This mightl resolve your problem for now, but re-customizing evets, will create bugs, that are "very hard to find".


Just curious, Why do you need this behavior?
Idle_Mind,
          On the code you posted... how do you define bottom and right? When I changed top and left to 0,0 and bottom to 1000 it didn't work right. The form could only travel left and right but not down. I also tried uping the bottom number but that didn't do anything.

Thanks
I'm so sorry, I forgot to change one of the values after I did some testing with it.  Change the WM_MOVING case to this:

        Case WM_MOVING
            CopyMemory rc, ByVal lParam, Len(rc)
           
            ' keep form inside bounding rectangle
            If rc.left < Bounds.left Then
                rc.right = rc.right + (Bounds.left - rc.left)
                rc.left = Bounds.left
            End If
            If rc.top < Bounds.top Then
                rc.bottom = rc.bottom + (Bounds.top - rc.top)
                rc.top = Bounds.top
            End If
            If rc.right > Bounds.right Then
                rc.left = rc.left - (rc.right - Bounds.right)
                rc.right = Bounds.right
            End If
            If rc.bottom > Bounds.bottom Then
                rc.top = rc.top - (rc.bottom - Bounds.bottom)
                rc.bottom = Bounds.bottom
            End If
            CopyMemory ByVal lParam, rc, Len(rc)

ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial