really24
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?
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?
Just keep in mind that anywhere inside your code before lines like Me.Height = 1111
you must set the resize flag to false.
you must set the resize flag to false.
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
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.
there is no way to cancel pre-built in resize even in forms.
The only way is to go around it.
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.ptMaxPositio n.x = Bounds.left
typMinMaxInfo.ptMaxPositio n.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
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.ptMaxPositio
typMinMaxInfo.ptMaxPositio
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
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
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
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?
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?
ASKER
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
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)
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.