People have posted code to drag a borderless form using a Windows Message, both on this forum and in the CodeBank. This method has a drawback: you can't drag the form higher than the top of the screen -- or rather you can, but it immediately flips back again when you release the mouse button. I would like to change that behaviour.
After some time poring over the stream of windows messages, I found that the flip-back occurs whenever there is a WM_CAPTURECHANGED message immediately followed by a WM_WINDOWPOSCHANGING. The latter message contains a pointer to a WINDOWPOS Structure in its LParam field. Apparently it is possible to annul the impending change of position by setting the NOMOVE flag of that WINDOWPOS.
Here's how I've defined WINDOWPOS:
vb.net Code:
<System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)> _
Public Structure WindowPos
Public hWnd As IntPtr
Public hWndInsertAfter As IntPtr
Public x As Integer
Public y As Integer
Public w As Integer
Public h As Integer
Public flags As UInt32
End Structure
Here's my WndProc Sub:
vb.net Code:
Private DontMove As Boolean
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If Me.Top < 0 Then
If m.Msg = WM_CAPTURECHANGED Then
DontMove = True
ElseIf m.Msg = WM_WINDOWPOSCHANGING AndAlso DontMove = True Then
Dim wPos As WindowPos = DirectCast(m.GetLParam((New WindowPos).GetType), WindowPos)
wPos.flags = wPos.flags Or CUInt(SWP_NOMOVE)
m.LParam = New IntPtr(AddressOf wPos)
DontMove = False
Else
DontMove = False
End If
End If
MyBase.WndProc(m)
End Sub
I have two syntax problems here. Line 7 gets past the syntax checker but it seems a rather elaborate way to get the WINDOWPOS. I'm not even sure if it works yet. Is there a more direct way to get the structure through the LParam pointer? Line 9 gives a syntax error because AddressOf apparently requires a method as its argument. Is there another way to set m.LParam to point at my modified WINDOWPOS structure?
Advice and any comments gratefully received. BB