Guten Abend,
ich arbeite mich gerade ein wenig in c# ein. Leider habe ich noch sehr wenig Erfahrung.
Folgendes Problem beschäftigt mich jetzt schon seit einiger Zeit, was ich nicht gelöst bekomme.
Ich möchte ein zweites Fenster auf einem externen Monitor öffnen. Mit folgendem Code konnte ich mir schon die Informationen der Bildschirme ziehen:
foreach (var screen in System.Windows.Forms.Screen.AllScreens)
{
listBox1.Items.Add("Device Name:" + screen.DeviceName);
listBox1.Items.Add("Bounds:" + screen.Bounds.ToString());
listBox1.Items.Add("Working Area: " + screen.WorkingArea.ToString());
listBox1.Items.Add("PrimaryScreen: " + screen.Primary.ToString());
listBox1.Items.Add("");
}
Mit folgender Funktion kann ich mir das Fenster anpassen:
private void Anzeige (int screenIdx, int xPos, int yPos, int xDim, int yDim)
{
Screen monitor = Screen.AllScreens[screenIdx];
Rectangle rect = monitor.WorkingArea;
f3.StartPosition = FormStartPosition.Manual;
f3.Location = new Point(xPos, yPos);
f3.Size = new Size(xDim, yDim);
f3.BackColor = Color.Red;
f3.Show();
}
Wenn ich nun als screenIdx eine 0 setze, öffnet das Fenster am linken oberen Bildschirmrand. Bei einer 1 das Gleiche. Bei einer 2 stürzt das Programm ab, weil das Array natürlich nur bis 1 geht.
Mein Hauptbildschirm ist links, der zweite Monitor rechts. Also wäre ich davon ausgegangen, dass links 0 und rechts 1 ist.
Wo liegt der Fehler?
Vielen Dank schon mal und es wäre sehr nett wenn die Antworten auf "Sendung mit der Maus" Niveau wären, damit auch ich sie umsetzen kann.
Ich schaue mir mal den Code an:
private void Anzeige (int screenIdx, int xPos, int yPos, int xDim, int yDim)
{
// Den gewünschten Screen/Monitor auswählen - OK
Screen monitor = Screen.AllScreens[screenIdx];
// Den Arbeitsbereich des Monitors auslesen - OK
Rectangle rect = monitor.WorkingArea;
// Und nun? Was fängst du mit dem rect nun an?
f3.StartPosition = FormStartPosition.Manual;
f3.Location = new Point(xPos, yPos);
f3.Size = new Size(xDim, yDim);
f3.BackColor = Color.Red;
f3.Show();
}
Also du holst dir den Monitor, davon den Arbeitsbereich um dann damit nichts zu machen.
Die Arbeit kannst du dir doch auch sparen, und somit würde der folgende Code das Gleiche machen:
private void Anzeige (int screenIdx, int xPos, int yPos, int xDim, int yDim)
{
f3.StartPosition = FormStartPosition.Manual;
f3.Location = new Point(xPos, yPos);
f3.Size = new Size(xDim, yDim);
f3.BackColor = Color.Red;
f3.Show();
}
Wenn du das Fenster an den Arbeitsbereich des gewählten Screens anpassen willst, dann brauchst du aber die ganzen Parameter nicht, denn die Werte holst du dir aus der rect
Variable:
private void Anzeige (int screenIdx)
{
Screen monitor = Screen.AllScreens[screenIdx];
Rectangle rect = monitor.WorkingArea;
// Wir verwenden die Werte von rect
f3.StartPosition = FormStartPosition.Manual;
f3.Location = rect.Location;
f3.Size = rect.Size;
f3.BackColor = Color.Red;
f3.Show();
}
Hat die Blume einen Knick, war der Schmetterling zu dick.
Und wenn die übergebenen Parameter xPos
/ yPos
die relative Position angeben sollen, dann noch die Werte dazuaddieren:
f3.Location = new Point(rect.X + xPos, rect.Y + yPos);
Zitat von Th69
Und wenn die übergebenen Parameter
xPos
/yPos
die relative Position angeben sollen, dann noch die Werte dazuaddieren:
Dann sollte man die aber auch konsequent umbenennen in xOffset
und yOffset
f3.Location = new Point(rect.X + xOffset, rect.Y + yOffset);
und man müsste diese Werte auch noch von der Höhe und Breite abziehen, sonst schiebt man das Fenster über den Bildschirmrand hinaus
Hat die Blume einen Knick, war der Schmetterling zu dick.
Hallo Zusammen,
erstmal vielen Dank für die Antworten.
Die ganzen Skalierungswerte hätten eigentlich nicht darein gemusst.
Über die Skalierung xPos und yPos habe ich es schon versucht. Das heißt den Hauptbildschirm auslesen und den dann als Offset benutzen. Dann kommt das Fenster nicht an der oberen linken Ecke des 2. Bildschirms an sondern leider irgendwo. Obwohl es das laut Auflösung der Bildschirme tun sollte (1920 Pixel in x Richtung).
Aus diesem Grund würde ich das Fenster gerne über den Screenindex zuweisen. Aber wie schon beschrieben funktioniert das nicht.
private void Anzeige (int screenIdx, int xPos, int yPos, int xDim, int yDim)
{
//Das hier tut nicht wie es soll hab ich den Anschein
Screen monitor = Screen.AllScreens[screenIdx];
f3.Size = new Size(xDim, yDim);
f3.BackColor = Color.Red;
f3.Show();
}
Das hier öffnet das Fenster immer am Hauptmonitor
//Tut das gleiche, sollte es aber doch nicht?
Anzeige(1, 0, 0, 500, 500);
Anzeige(0, 0, 0, 500, 500);
Oder wo ist der Denkfehler?
Zitat von Tom3419
Oder wo ist der Denkfehler?
Wenn du immer die GLEICHEN Werte bei der Form setzt, warum sollte die Form an einer anderen Stelle erscheinen?
Dieser Code
Screen monitor = Screen.AllScreens[screenIdx];
holt nur einen Wert aus einer Auflistung. Punkt. Mehr macht er nicht. Er stellet nichts irgenwie wo ein!
Der Code, der das was du möchtest macht, den habe ich schon hier gezeigt. Also ist es eher ein Lese- als ein Denkfehler
Hat die Blume einen Knick, war der Schmetterling zu dick.
Wie schon weiter oben erwähnt sollte das hier funktionieren.
private void Anzeige(int screenIdx, int xPos, int yPos, int xDim, int yDim)
{
Screen monitor = Screen.AllScreens[screenIdx];
Rectangle screenArea = monitor.WorkingArea;
f3.StartPosition = FormStartPosition.Manual;
f3.BackColor = Color.RebeccaPurple;
f3.Size = new Size(xDim, yDim);
f3.Location = new Point(screenArea.X + xPos, screenArea.Y + yPos);
}
Zitat von Tom3419
in c# ein. ...wenig Erfahrung.
Kurzer Exkurs: Programmierung ist die Frage wie sich der Compiler (z.B. C#) verhält, wenn er im Quellcode auf ein Schlüsselwort (auch i.V. mit anderen Schlüsselwörtern) (nicht) trifft. Den Compiler interessiert auch nur die formelle Korrektheit des Codes (also z.B. nicht das und wo da ein Fenster geöffnet werden soll). Und was der C#-Compiler als korrektes Schlüsselwort anerkennt, hängt auch der jeweiligen Compiler-Version ab.
Aus menschlicher Sicht soll(te) man die Codebasis so strukturieren das (häufige) Änderungen oder Erweiterungen nur an einer Stelle vorzunehmen sind.
Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉