SetWindowPos每次都会将窗口移动到不同的位置

本文关键字:位置 移动 窗口 SetWindowPos | 更新日期: 2023-09-27 17:58:36

我有一个Windows应用程序(我正在用C#编写),它以一个无边框的最大化窗口开始。

当用户点击应用程序中的按钮时,我想恢复窗口(即删除最大化状态),将其调整到一定大小,并将其移动到屏幕的右下角。

我的问题是,在正确调整窗口大小的同时,对SetWindowPos()的调用并不总是将其放置在屏幕的右下角。有时确实如此,但有时窗口会被放在屏幕的其他地方(几乎就像它在"跳跃"一样,原因我忽略了)。

我做错了什么?

这是我的密码。请注意,我将-1作为第二个参数传递给SetWindowPos,因为我希望我的窗口位于其他窗口的顶部。

public void MoveAppWindowToBottomRight()
{
    Process process = Process.GetCurrentProcess();
    IntPtr handler = process.MainWindowHandle;
    ShowWindow(handler, 9); // SW_RESTORE = 9
    int x = (int)(System.Windows.SystemParameters.PrimaryScreenWidth - 380);
    int y = (int)(System.Windows.SystemParameters.PrimaryScreenHeight - 250);
    NativePoint point = new NativePoint { x = x, y = y };
    ClientToScreen(handler, ref point);
    SetWindowPos(handler, -1, point.x, point.y, 380, 250, 0);            
}
[StructLayout(LayoutKind.Sequential)]
public struct NativePoint
{
    public int x;
    public int y;
}

SetWindowPos每次都会将窗口移动到不同的位置

您应该删除以下行:

NativePoint point = new NativePoint { x = x, y = y };
ClientToScreen(handler, ref point);

并将您的呼叫更改为:

SetWindowPos(handler, -1, x, y, 380, 250, 0);

调用ClientToScreen()毫无意义,因为您所拥有的坐标已经是屏幕坐标。

您的窗口每次都会得到不同的位置,因为当您调用ClientToScreen()时,它将基于窗口的当前位置创建新的坐标。这意味着每次调用函数时,坐标都会有所不同。


此外,如果要考虑任务栏大小,则应使用Screen.WorkingArea属性而不是SystemParameters.PrimaryScreen***:

int x = (int)(Screen.PrimaryScreen.WorkingArea.Width - 380);
int y = (int)(Screen.PrimaryScreen.WorkingArea.Height - 250);