如何移动窗口像我想要的WinApi
本文关键字:我想要 WinApi 窗口 何移动 移动 | 更新日期: 2023-09-27 18:17:09
当我尝试用这个拖动我的窗口时,窗口会跳跃和闪烁:
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);
触发另一个移动事件(这个应该被忽略)
请帮忙!
下面是一个使用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);
}
}
这应该是你想要的:
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);
}