2016-07-25 24 views
0

Ich habe eine Windows-Anwendung (die ich in C# schreibe), die mit einem maximierten Fenster ohne Grenzen beginnt.SetWindowPos verschiebt Fenster zu verschiedenen Positionen jedes Mal

Wenn der Benutzer auf eine Schaltfläche in der Anwendung klickt, möchte ich das Fenster wiederherstellen (dh den maximierten Status entfernen), die Größe auf eine bestimmte Größe ändern und es in die untere rechte Ecke des Bildschirms verschieben.

Mein Problem ist, dass der Aufruf an SetWindowPos(), während die Größe des Fensters korrekt ändert, es nicht immer in der unteren rechten Ecke des Bildschirms platziert. Manchmal tut es das, aber manchmal ist das Fenster anderswo auf dem Bildschirm platziert (fast so, als ob es "herumspringen" würde, aus einem Grund, den ich ignoriere).

Was mache ich falsch?

Hier ist mein Code. Beachten Sie, dass ich -1 als zweiten Parameter an SetWindowPos übergeben, weil ich möchte, dass sich mein Fenster über jedem anderen Fenster befindet.

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:


Auch, wenn Sie in der Taskleiste Größe berücksichtigen wollen, sollten Sie die Screen.WorkingArea property anstelle des SystemParameters.PrimaryScreen*** nutzen /en-us/library/system.windows.systemparameters.primaryscreenwidth.aspx) und [SystemParameters.PrimaryScreenHeight] (https://msdn.microsoft.com/en-us/library/system.windows.systemparameters.primaryscreenheight.aspx) Berücksichtigen Sie nicht den von der Taskleiste belegten Speicherplatz. Das hat nichts mit der Frage zu tun. Es ist ein weiterer Fehler, den Sie ansprechen müssen. – IInspectable

Antwort

6

sollten Sie diese Zeilen entfernen:

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

ClientToScreen(handler, ref point); 

Und Ihren Anruf ändern:

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

Aufruf ClientToScreen() macht keinen Sinn, da die Koordinaten, die Sie haben, sind screenen bereits Koordinaten.

Ihr Fenster erhält jedes Mal eine andere Position, denn wenn Sie ClientToScreen() aufrufen, werden neue Koordinaten basierend auf auf der aktuellen Position des Fensters erstellt. Dies bedeutet, dass bei jedem Aufruf der Funktion die Koordinaten unterschiedlich sind.

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

Guthaben zu IInspectable für das Aufzeigen der Sache über die Taskleiste. –

+0

Danke @ Visual-Vincent, ich wusste nicht SetWindowPos erstellt neue Koordinaten basierend auf einer relativen Position. Ich fand heraus, dass der Aufruf, den ich brauche, 'MoveWindow' ist, das für Top-Level-Fenster neue Koordinaten relativ zur oberen linken Ecke des Bildschirms berechnet. –

+0

@AlbertoVenturini: Nonononono, es ist 'ClientToScreen()', das neue Koordinaten relativ zur aktuellen Position erzeugt. Wie gesagt, das ist der Anruf, den Sie entfernen sollten, tut mir leid, dass Sie nicht klar sind. Sie können weiterhin 'SetWindowPos()' verwenden. –