2016-07-25 80 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()'。 –

相關問題