Laden...

Windows Form auf Bildschirm 2 öffnen

Letzter Beitrag vor 12 Tagen 8 Posts 235 Views
Windows Form auf Bildschirm 2 öffnen

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 😉