PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SetWindowPos -- Mehr links ist wünschenswert


Dr.Doom
2019-05-23, 16:00:20
Howdy!

Ich möchte das Hauptfenster einer MFC/MDI-Anwendung (C++) auf einen zweiten Monitor versetzen und dort maximieren.
Ich habe bereits mit der Funktion EnumDisplayMonitors (https://docs.microsoft.com/de-de/windows/desktop/api/winuser/nf-winuser-enumdisplaymonitors) Informationen über die angeschlossenen Monitore eingesammelt.

Der Ursprung des Hauptmonitors ist erwartungsgemäss bei (0,0), der zweite Monitor links vom Hauptmonitor angeordnet. Beide Monitore haben die FulHD-Auflösung.
Interessanterweise ist das Ganze beim zweiten Monitor schon um zwei Pixel nach unten versetzt. Der Ursprung ist hier nicht (-1920,0), sondern (-1920,2) -- warum ist das so? (Bild (https://www.forum-3dcenter.org/vbulletin/attachment.php?attachmentid=66679&stc=1&d=1558618579))

Versetze ich das Hauptfenster mittels SetWindowPos nach links auf den zweiten Monitor (Bild (https://www.forum-3dcenter.org/vbulletin/attachment.php?attachmentid=66680&stc=1&d=1558618579)), ist das Fenster aber nicht weit genug plaziert worden (Bild (https://www.forum-3dcenter.org/vbulletin/attachment.php?attachmentid=66678&stc=1&d=1558618579), Ausschnitt Bildschirm links oben).
Im Hintergrund meiner Anwendung sieht man noch das MS Outlook-Fenster (schwarzer "Datei"-Button).

Auf dem Bild (https://www.forum-3dcenter.org/vbulletin/attachment.php?attachmentid=66678&stc=1&d=1558619731) sieht man auch einen schwarzen Rand (oben). Dieser ist aber nur auf dem Screenshot zu sehen. Das im Hintergrund sichtbare Outlook-Fenster ist bereits maximiert.

Hat jemand eine Antwort auf die Warums?
.

Gast
2019-05-23, 16:26:43
Ich weiß nicht, ob Dir das hilft, aber ich hatte kürzlich ein ähnliches Problem: Ich muss aus meinem eigenen Programm heraus einen Screenshot des Programmfensters machen. Dazu verwende ich GetWindowRect (und paar BitBlt-Sachen und sowas, was jetzt keine Rolle spielt) und stellte dabei fest, dass das ermittelte RECT ebenfalls in seiner Left-Eigenschaft um zwei Pixel daneben liegt. Reproduzierbar, auf mehreren Rechnern, alle mit Windows 10.

Ich vermute, dass es da irgendwelche Inkompatibilitäten mit dem Client- und dem Nonclient-Bereich des Fensters gibt in Bezug auf diese API-Funktionen, diese stammen ja schließlich noch aus Windows-95-Zeiten (oder so). Seitdem gab es XP, Vista und 7 mit Aero Glass, jetzt 10, immer mit einem anderen Window-System.

Ich hab' es schulterzuckend abgetan und korrigiere eben Left (und damit auch Right) um zwei Pixel. Ist allerdings ein Programm, das nur ich selbst nutze, ein professioneller Entwickler muss hier wohl noch etwas mehr recherchieren.

Zur Anordnung der beiden Schirme: In den Windows-Anzeigeeinstellungen kann man die Schirme durchaus versetzt arrangieren. Vielleicht ist das bei Dir der Fall?

Marscel
2019-05-23, 19:24:24
Eine Erklärung kann ich dir nicht liefern, du kannst allerdings mal gucken, ob SetWindowPlacement (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowplacement) das gewünschte Ergebnis liefert.

Das mit den zwei Pixeln Offset hört sich für mich nach einer Einstellung auf dem Computer an.

Gast
2019-05-23, 22:31:12
Soweit ich weiß ist das Problem, dass 0,0 vom Fenster nicht da ist wo man es unbedingt erwartet.

Um das Fenster herum ist noch der Fensterrahmen, der nicht zum Koordinatenbereich des Fensters zählt.
Wenn du ein Fenster manuell auf die volle Größe des Bildschirmes ziehst und anschließend das Fenster maximierst siehst, dass der Rahmen etwas schmäler wird und die Fläche für die Anwendung etwas größer.

Dieser Unterschied sind die paar Pixel die von der perfekten 0,0-Positionierung abweichen.

Gast
2019-05-24, 08:16:53
Soweit ich weiß ist das Problem, dass 0,0 vom Fenster nicht da ist wo man es unbedingt erwartet.

Um das Fenster herum ist noch der Fensterrahmen, der nicht zum Koordinatenbereich des Fensters zählt.
Wenn du ein Fenster manuell auf die volle Größe des Bildschirmes ziehst und anschließend das Fenster maximierst siehst, dass der Rahmen etwas schmäler wird und die Fläche für die Anwendung etwas größer.

Dieser Unterschied sind die paar Pixel die von der perfekten 0,0-Positionierung abweichen.
Ja, das ist der sogenannte Non-Clientbereich, den ich ansprach. Das ist hier aber nicht die eigentliche Ursache.

Gnafoo
2019-05-26, 02:14:27
Zur Anordnung der beiden Schirme: In den Windows-Anzeigeeinstellungen kann man die Schirme durchaus versetzt arrangieren. Vielleicht ist das bei Dir der Fall?

Das hätte ich auch zuerst vermutet. Ich würde mal die Monitore mit EnumDisplayMonitors() und GetMonitorInfo() durchiterieren und die genauen Monitor/WorkArea-Rectangles ausgeben. Evtl. ist da ja tatsächlich etwas verschoben?

Dr.Doom
2019-06-03, 14:54:35
(1) Die zwei "Bonus-Pixel" am oberen Rand lagen tatsächlich an einer minimal verschobenen Bildschirmanordnung im Windows.

(2) Dass sich das Hauptfenster nicht vollständig bildschirmfüllend aufziehen lässt (siehe Bild im Startbeitrag (https://www.forum-3dcenter.org/vbulletin/attachment.php?attachmentid=66678&stc=1&d=1558618576)), habe ich noch nicht überwunden und auch nicht verstanden.

Die Monitordimensionen sind ja bereits ermittelt worden (s. Startbeitrag). Ich versetze das Hauptfenster an den Ursprung des linken Monitors (Hauptanzeigemonitor steht direkt vor mir, links daneben der zweite Monitor).

Mit GetWindowRect ermittle ich die Dimension/Position, dann maximiere ich das Fenster und ermittle erneut Dim&Pos.
(siehe Bild unten für Daten)

Wenn das Fenster maximiert ist, fehlt nur der dünne grau/schwarze Rand des Fensters, der hier (https://www.forum-3dcenter.org/vbulletin/attachment.php?attachmentid=66678&stc=1&d=1558618576) im nicht-maximierten Zustand noch zu sehen ist.
Ein Screenshot vom maximierten Fenster lohnt nicht: schliesst halt wie gewünscht mit dem linken Bildschirmrand ab.

Dimension und Position des maximierten Fensters, das den Bildschirm nun ausfüllt, liegen jetzt allerdings neun Pixel ausserhalb der sichtbaren Bildschirmfläche. :confused:


Hat das was mit der Breite des Rahmens zu tun? Wobei ich das nicht glauben kann, da der dünne/schwarze Rahmen (Bild (https://www.forum-3dcenter.org/vbulletin/attachment.php?attachmentid=66678&stc=1&d=1558618576)) keine neun Pixel breit ist ((un)vermessen aufgestellte Behauptung).

Ich habe auch versucht, die Breite des Rahmen bzw. der Rahmen zu bestimmen (siehe Bild unten). Zwei unterschiedliche GetSystemMetrics-Abfrage haben ich gefunden, aber weder die eine, noch die andere, noch beide zusammen ergeben "neun" Pixel.

Gibt's da noch eine Abfrage, welche die Lücke zur "vollen Neun" schließt oder eine andere, die sofort die "Neun" liefert?

https://www.forum-3dcenter.org/vbulletin/attachment.php?attachmentid=66802&stc=1&d=1559563918