I have a simple MDI application with a few children windows.
That being said, how can I change the children windows in such a way that they are not moveable.
I know I can do this at design time, but I want them initially to be moveable, and allow the user to "lock" and "unlock" the windows while the program is running...to keep windows from being moved accidentally.
You have two options, both of which involve subclassing.
Either: 1 Intercept the WM_SIZING/WM_MOVING messages and set the parameters of the RECT structure pointed to by lParam to the location you want your form to be stuck at.
2 Intercept the WM_NCHITTEST and always return HTCLIENT thus fooling Windows into thinking your form has no caption or borders that can be selected.
The good news is that both of these are fairly straight forward if you use the EventVB.dll thus:
Code:
'\\ Form declarations
Dim WithEvents vbLink As EventVB.ApiFunctions
Dim WithEvents vbWnd As EventVB.ApiWindow
Dim bLocked As Boolean
'\\ Start subclassing when form loads
Private Sub Form_Load()
Set vbLink = New EventVB.ApiFunctions
Set vbWnd = New EventVB.ApiWindow
vbWnd.hwnd = Me.hWnd
vbLink.SubclassedWindows.Add vbWnd
End Sub
'\\ Stop subclassing when form unloads
Private Sub Form_Unload()
vbLink.SubclassedWindows.Remove vbWnd
Set vbWnd = Nothing
Set vbLink = Nothing
End Sub
'\\ Option 1 - prevent the WM_SIZING/WM_MOVING having any effect
Private Sub vbWnd_Sizing(ByVal SizeEdges As EventVB.WindowSizingEdges, DragRectangle As EventVB.APIRect)
If blocked Then
With DragRectangle
.Left = vbWnd.RECT.Left
.Right = vbWnd.RECT.Right
.Top = vbWnd.RECT.Top
.Bottom = vbWnd.RECT.Bottom
End With
End If
End Sub
Private Sub vbWnd_Moving(ByVal MoveEdges As EventVB.WindowSizingEdges, MoveRectangle As EventVB.APIRect)
If blocked Then
With MoveRectangle
.Left = vbWnd.RECT.Left
.Right = vbWnd.RECT.Right
.Top = vbWnd.RECT.Top
.Bottom = vbWnd.RECT.Bottom
End With
End If
End Sub
'\\ Option 2 - fool the hittest
Private Sub vbWnd_HitTest(ByVal x As Long, ByVal y As Long, ReturnValue As EventVB.enHitTestResult, Override As Boolean)
If bLocked Then
ReturnValue = HTCLIENT
Override = True
End If
End Sub
I was hoping to prevent movement of the CHILDREN within the MDI. I tried this code with the hWnd of a child window, and it was still able to be moved...
Your version works perfectly, but when I try the EXACT implementation on my MDI array, it doesn't prevent the window from moving! What could possibly be the problem?