当我尝试用这个窗口拖动时,窗口会跳跃并闪烁:
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);
}
WM_MOVE
,WM_MOVING
,WM_WINDOWPOSCHANGING
或其他移动事件必须在拖动窗口时继续触发,因为我希望检查每个新位置。Location = new Point(0, y);
触发了另一个移动事件(应忽略此事件)请帮忙!
答案 0 :(得分:3)
以下是使用WM_WINDOWPOSCHANGING并修改WINDOWPOS结构的示例:
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);
}
}
答案 1 :(得分:0)
这应该做你想要的:
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建议LocationChanged
事件,它可以很好地工作。在此示例中,窗口在0, 0
处冻结,直到鼠标指针超出500, 500
框:
private void Form1_LocationChanged(Object sender, EventArgs e)
{
if (MousePosition.X > 500 || MousePosition.Y > 500)
Location = MousePosition;
else
Location = new Point(0, 0);
}