Download the Sizing and Moving control source code (16kb)
Before you Begin
This project requires the SSubTmr.DLL component. Make sure you have loaded and registered this before trying the project.
VB's control over moving and sizing isn't much - basically you have the Resize event,
as has been the case since VB1. Windows gives you a lot more control over moving and sizing
forms if you need it though. For example, try resizing an undocked tool window in MS Office.
You will see that the size snaps so groups of buttons or controls are kept on the same
This sample demonstrates how to get access to all the more sophisticated moving and sizing
messages, and how to use them to control your window's resize without the flickering and
jumping to position you get if you try to change size during VB's Resize event.
Return To Sender
Windows sends the following messages associated with moving and sizing which VB ignores :
The sample application shows how you can subclass these messages for a window and respond
correctly to them, providing the following new events for a window:
- WM_SIZING = &H214
This message is fired whilst the window is being resized. The lParam of the message
points to a RECT structure containing the desired position of the window. Any modifications
you make to this rectangle are passed back to Windows, which moves or sizes the window directly to
the size and position you specify.
- WM_MOVING = &H216
This message works the same way as WM_SIZING except it is fired whilst the window
is being moved.
- WM_ENTERSIZEMOVE = &H231
This message is fired when your window is about to start moving or sizing.
- WM_EXITSIZEMOVE = &H232
This message is fired when a moving or sizing operation on your window has completed.
- WM_SIZE = &H5
This message is fired whenever your window has its size changed by the SetWindowPos
function, for example when windows minimizes, maximizes or restores your window, or when
you call a VB function which changes the size of the window.
Controlling FullDrag State
The Full Window drag setting is a nice option in Windows, but for highly animated or
dynamic windows it can cause moving and sizing to be slow. Luckily there is a way
to control it on a window by window basis. You achieve this by subclassing for the
WM_ACTIVATE message to determine when the window you want to change the state
for is activate or not. When the window is activated, you can then call the
SystemParametersInfo function to turn off full-drag if it is enabled. When
the window is deactivated again, you simply reset the state to its original value.
Here is the code for checking and setting the full drag state:
Private Const SPI_GETDRAGFULLWINDOWS = 38
Private Const SPI_SETDRAGFULLWINDOWS = 37
Private Const SPIF_SENDWININICHANGE = &H2
Private Const SPIF_UPDATEINIFILE = &H1
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" _
(ByVal uAction As Long, ByVal uParam As Long, lpvParam As Any, ByVal fuWinIni As Long) As Long
Private m_bSwitchOff As Boolean
Private Sub pTurnOffFullDrag()
Dim lR As Long
' Get the full-drag state:
If Not (SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0&, lR, 0) = 0) Then
If Not lR = 0 Then
' Store the fact we are changing:
m_bSwitchOff = True
' Set the full-drag state:
lR = SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, 0&, ByVal 0&, SPIF_SENDWININICHANGE)
Private Sub pResetFullDrag()
If m_bSwitchOff Then
SystemParametersInfo SPI_SETDRAGFULLWINDOWS, 1&, ByVal 0&, SPIF_SENDWININICHANGE
m_bSwitchOff = False