Is there anyway to control where you can move a form?
So if i move a form, it can only be moved on the vertical axis and when i try to move it horizontally, nothing happens.
I dont want a buggy implementation like locationchanged or move event and poping it back inline. I no there is a way using something like a WndProc override but after searching for a while, i couldnt find anything. Please help
You would most likely want to override WndProc and handle the WM_MOVING message. According to MSDN:
The WM_MOVING message is sent to a
window that the user is moving. By
processing this message, an
application can monitor the position
of the drag rectangle and, if needed,
change its position.
This would be a way to do it, however, you would obviously need to tweek it for your needs:
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace VerticalMovingForm
{
public partial class Form1 : Form
{
private const int WM_MOVING = 0x0216;
private readonly int positionX;
private readonly int positionR;
public Form1()
{
Left = 400;
Width = 500;
positionX = Left;
positionR = Left + Width;
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MOVING)
{
var r = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
r.Left = positionX;
r.Right = positionR;
Marshal.StructureToPtr(r, m.LParam, false);
}
base.WndProc(ref m);
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
}
}
For example:
using System.Runtime.InteropServices;
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x216) // WM_MOVING = 0x216
{
Rectangle rect =
(Rectangle) Marshal.PtrToStructure(m.LParam, typeof (Rectangle));
if (rect.Left < 100)
{
// compensates for right side drift
rect.Width = rect.Width + (100 - rect.Left);
// force left side to 100
rect.X = 100;
Marshal.StructureToPtr(rect, m.LParam, true);
}
}
base.WndProc(ref m);
}
The above code sets a minimum lefthand position of 100.
There is no need to recreate the RECT structure, like driis did, the .NET native Rectangle works fine. However, you have to set the location via the X property, since Left is a Get only property.
VB.NET Version:
Protected Overloads Overrides Sub WndProc(ByRef m As Message)
If m.Msg = &H216 Then
' WM_MOVING = 0x216
Dim rect As Rectangle = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(Rectangle)), Rectangle)
If rect.Left < 100 Then
' compensates for right side drift
rect.Width = rect.Width + (100 - rect.Left)
' force left side to 100
rect.X = 100
Marshal.StructureToPtr(rect, m.LParam, True)
End If
End If
MyBase.WndProc(m)
End Sub