You can control the docking behavior of a form by processing the WM_WINDOWPOSCHANGING message. The following code docks the form to the working area boundaries as you move the form or even size it.
Paste the following code and try moving/sizing the form.
Form code.
___
[tt]
Private Sub Form_Load()
Dock hWnd, 15
End Sub[/tt]
___
Module code.
___
[tt]
Option Explicit
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
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
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByRef lpvParam As Any, ByVal fuWinIni As Long) As Long
Const WM_SYSCOMMAND = &H112
Const SC_SIZE = &HF000&
Const SC_MOVE = &HF010&
Const WM_WINDOWPOSCHANGING = &H46
Const SPI_GETWORKAREA = 48
Const GWL_WNDPROC = -4
Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Type WINDOWPOS
hWnd As Long
hWndInsertAfter As Long
x As Long
y As Long
cx As Long
cy As Long
flags As Long
End Type
Dim lpWndProc As Long
Dim SysCmdType As Long 'sizing or moving
Dim DockDist As Long 'docking distance
Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Select Case uMsg
Case WM_SYSCOMMAND
SysCmdType = wParam And &HFFF0&
Debug.Print Hex(wParam)
Case WM_WINDOWPOSCHANGING
Dim wp As WINDOWPOS, rc As RECT
SystemParametersInfo SPI_GETWORKAREA, 0, rc, 0
CopyMemory wp, ByVal lParam, Len(wp)
Select Case SysCmdType
Case SC_MOVE
If Abs(wp.x - rc.Left) < DockDist Then wp.x = rc.Left
If Abs(wp.y - rc.Top) < DockDist Then wp.y = rc.Top
If Abs(wp.x + wp.cx - rc.Right) < DockDist Then wp.x = rc.Right - wp.cx
If Abs(wp.y + wp.cy - rc.Bottom) < DockDist Then wp.y = rc.Bottom - wp.cy
Case SC_SIZE
If Abs(wp.x - rc.Left) < DockDist Then wp.cx = wp.cx + wp.x - rc.Left: wp.x = rc.Left
If Abs(wp.y - rc.Top) < DockDist Then wp.cy = wp.cy + wp.y - rc.Top: wp.y = rc.Top
If Abs(wp.x + wp.cx - rc.Right) < DockDist Then wp.cx = rc.Right - wp.x
If Abs(wp.y + wp.cy - rc.Bottom) < DockDist Then wp.cy = rc.Bottom - wp.y
End Select
CopyMemory ByVal lParam, wp, Len(wp)
End Select
WndProc = CallWindowProc(lpWndProc, hWnd, uMsg, wParam, lParam)
End Function
Sub Dock(hWnd As Long, DockingDistance As Long)
lpWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WndProc)
DockDist = DockingDistance
End Sub[/tt]
___
Note that different adjustments are required for docking when you move the form or size it. If your form is not sizable, then you can remove the "Case SC_SIZE" portion of the code in the Select Case structure in the window procedure, to make the code simple.
Thxs for your reply but it's not exactly what I'm looking for. I'm trying to have a dockable form inside a Main Form (like Properties in Visual Basic Environment) not in the Windows Working Area.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.