2016-07-25 37 views
0

我有一个Windows应用程序(我正在用C#编写)以无界限的最大化窗口开始。SetWindowPos每次都将窗口移动到不同的位置

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

我的问题是,调用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; 
} 
+0

[SystemParameters.PrimaryScreenWidth](https://msdn.microsoft.com /en-us/library/system.windows.systemparameters.primaryscreenwidth.aspx)和[SystemParameters.PrimaryScreenHeight](https://msdn.microsoft.com/en-us/library/system.windows.systemparameters.primaryscreenheight.aspx)不要占用任务栏占用的空间。这与这个问题的问题无关。这是你需要解决的另一个bug。 – IInspectable

回答

6

您应该删除这些行:

NativePoint point = new NativePoint { x = x, y = y }; 

ClientToScreen(handler, ref point); 

,您的电话更改为:

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

调用ClientToScreen()是没有意义的,你必须已经是屏幕坐标的坐标。

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


另外,如果你想利用任务栏的大小考虑,你应该利用Screen.WorkingArea property代替SystemParameters.PrimaryScreen***

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

感谢IInspectable指出有关任务栏的事情。 –

+0

谢谢@ visual-vincent,我不知道SetWindowPos根据相对位置创建新坐标。我发现我需要的是'MoveWindow',它为顶层窗口计算相对于屏幕左上角的新坐标。 –

+0

@AlbertoVenturini:Nonononono,它是'ClientToScreen()',它创建相对于当前位置的新坐标。正如我所说,这是你应该删除的电话,抱歉不清楚。你仍然可以使用'SetWindowPos()'。 –

相关问题