Question

When I try to drag my window with this the window jumps and flickers around:

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_MOVE)
    {
        int x = (m.LParam.ToInt32() & 0xffff);
        int y = ((m.LParam.ToInt32() >> 16) & 0xffff);

        if (x < 500)
            Location = new Point(0, y);
        else
            base.WndProc(ref m);
    }
    else
        base.WndProc(ref m);
}
  • must stop jumping
  • WM_MOVE, WM_MOVING, WM_WINDOWPOSCHANGING or other move event must continue firing while dragging the window because I want every new position to be checked.
  • another problem is Location = new Point(0, y); fires another move event (this one should be ignored)

Please help!

Was it helpful?

Solution

Here's an example of using WM_WINDOWPOSCHANGING and modifying the WINDOWPOS structure:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    public struct WINDOWPOS
    {
        public IntPtr hwnd;
        public IntPtr hwndInsertAfter;
        public int x;
        public int y;
        public int cx;
        public int cy;
        public uint flags;
    }

    public const int WM_WINDOWPOSCHANGING = 0x46;

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_WINDOWPOSCHANGING:
                WINDOWPOS wp = (WINDOWPOS)System.Runtime.InteropServices.Marshal.PtrToStructure(m.LParam, typeof(WINDOWPOS));
                if (true) // ... if somecondition ...
                {
                    // modify the location with x,y:
                    wp.x = 0;
                    wp.y = 0;
                }
                System.Runtime.InteropServices.Marshal.StructureToPtr(wp, m.LParam, true);
                break;
        }

        base.WndProc(ref m);
    }

}

OTHER TIPS

This should do what you want:

protected override void WndProc(ref Message message)
{
    const Int32 WM_SYSCOMMAND = 0x0112;
    const Int32 SC_MOVE = 0xF010;

    switch (message.Msg)
    {
        case WM_SYSCOMMAND:
            Int32 command = message.WParam.ToInt32() & 0xfff0;
            if (command == SC_MOVE)
            {
                Left = 0;
                Top = 0;
                return;
            }
            break;
    }

    base.WndProc(ref message);
}

Hans Passant suggested the LocationChanged event, and it can work quite nicely. In this example, the window is frozen at 0, 0 until the mouse pointer gets outside of a 500, 500 box:

private void Form1_LocationChanged(Object sender, EventArgs e)
{
    if (MousePosition.X > 500 || MousePosition.Y > 500)
        Location = MousePosition;
    else
        Location = new Point(0, 0);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top