7

I have a multi monitor setup and I want to paint a vertical and horizontal line as the user moves their cursor. The lines I want to paint should span all monitors. I'm not entirely sure how to adjust my form to make this possible since when i make it full screen it only maximizes to one monitor.

Do i have to make a form per monitor and send signals to each one when the cursor moves for it to repaint the line?

enter image description here

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace fitAllScreens
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            FullScreen();
        }


        public void FullScreen()
        {
            List<int> xBounds = new List<int>() {};
            List<int> yBounds = new List<int>() {};

            foreach (Screen screen in Screen.AllScreens)
            {
                var bounds = screen.Bounds;
                xBounds.Add(bounds.X);
                xBounds.Add(bounds.Right);
                yBounds.Add(bounds.Y);
                yBounds.Add(bounds.Bottom);
            }

            int minX = xBounds.Min();
            int maxX = xBounds.Max();
            int minY = yBounds.Min();
            int maxY = yBounds.Max();

            Console.WriteLine(minX + " - " + maxX + " - " + minY + " - " + maxY);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            var graphics = e.Graphics;
            base.OnPaint(e);

            // Draw ruler guides
            Console.WriteLine(Cursor.Position);

            var pos = this.PointToClient(Cursor.Position);

            using (var pen = new Pen(Color.Red))
            {
                pen.DashStyle = DashStyle.Dot;
                var screenBounds = Screen.PrimaryScreen.Bounds;
                graphics.DrawLine(pen, pos.X, screenBounds.Y, pos.X, screenBounds.Height);
                graphics.DrawLine(pen, screenBounds.X, pos.Y, screenBounds.Width, pos.Y);
            }
        }
    }
}
VillageTech
  • 1,968
  • 8
  • 18
JokerMartini
  • 5,674
  • 9
  • 83
  • 193
  • 1
    I'm not sure this is possible. You can't know the physical alignment of the different monitors. –  Dec 17 '19 at 19:39
  • 1
    @Amy But you know the bounding box, and that should be enough. – GSerg Dec 17 '19 at 19:39
  • 1
    I would try creating one huge form (x2 the dimensions of the bounding box of all monitors) in the shape of a cross (by setting most of its area to be transparent) and just moving that form around. Windows will do the rest. – GSerg Dec 17 '19 at 19:40
  • How would i know that im properly creating a form that spans monitors that may be vertical and super tall. I was hoping there would be a solution – JokerMartini Dec 17 '19 at 19:46
  • Monitors positions and layout can be changed as well – Pavel Anikhouski Dec 17 '19 at 19:59
  • Can't work, Winforms has a rock-hard check that prevents a window getting larger than the screen it is on. You'll need a little controller class that is aware of all three forms and subscribe their events. Don't forget dpiAware. – Hans Passant Dec 17 '19 at 22:25
  • See the notes here: [Using SetWindowPos with multiple monitors](https://stackoverflow.com/a/53026765/7444103). If I understood the requirements correctly, the code to get the DC of each Monitor in the VirtualScreen (and Paint on them all) is at the bottom of it. What Hans Passant wrote about is mandatory (so, don't skip the *about DpiAwareness* section, in case your app is not DpiAware). – Jimi Dec 18 '19 at 00:52
  • I think you should be able to do this with the Win32 API, with some basic windows primitives. I think you would create two "windows", one for the vertical line, and another for the horizontal line. – MicroservicesOnDDD Oct 09 '20 at 06:39

1 Answers1

1

I edited your code so it can fit all screens (I test it on 2 screens and it worked well).

 public partial class Form1 : Form
{

    int minX;
    int maxX;
    int minY;
    int maxY;
    public Form1()
    {
        InitializeComponent();
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
        this.FormBorderStyle = FormBorderStyle.None;
        this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
        this.DoubleBuffered = true;

        FullScreen();
        CreateCloseButtons();

    }

    private void CloseButtons_Click(object sender, EventArgs e)
    {
        Application.Exit();
    }

    public void FullScreen()
    {
        List<int> xBounds = new List<int>() { };
        List<int> yBounds = new List<int>() { };

        foreach (Screen screen in Screen.AllScreens)
        {
            var bounds = screen.WorkingArea;
            xBounds.Add(bounds.X);
            xBounds.Add(bounds.Right);
            yBounds.Add(bounds.Y);
            yBounds.Add(bounds.Bottom);
        }

        minX = xBounds.Min();
        maxX = xBounds.Max();
        minY = yBounds.Min();
        maxY = yBounds.Max();


        this.Location = new Point(minX, minY);
        //this.Location = this.PointToClient(new Point(minX, minY));
        this.Size = new Size(maxX - minX, maxY - minY);

    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        Console.WriteLine(this.Location.X + " - " + this.Location.Y);
        Console.WriteLine(this.Size.Width + " - " + this.Location.Y);
        base.OnMouseMove(e);
        Invalidate(false);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        var pos = this.PointToClient(Cursor.Position);

        using (var pen = new Pen(Color.Red))
        {
            pen.Width = 2;
            pen.DashStyle = DashStyle.Dot;
            e.Graphics.DrawLine(pen, pos.X, minY, pos.X, this.Height);
            e.Graphics.DrawLine(pen, minX, pos.Y, this.Width, pos.Y);
        }
    }



    private void CreateCloseButtons()
    {

        Button button1 = new System.Windows.Forms.Button();
        Button button2 = new System.Windows.Forms.Button();
        Button button3 = new System.Windows.Forms.Button();
        Button button4 = new System.Windows.Forms.Button();

        button1.Click += CloseButtons_Click;
        button2.Click += CloseButtons_Click;
        button3.Click += CloseButtons_Click;
        button4.Click += CloseButtons_Click;

        // 
        // top right
        // 
        button1.BackColor = System.Drawing.Color.Red;
        button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
        button1.ForeColor = System.Drawing.SystemColors.ButtonFace;
        button1.Location = new System.Drawing.Point(0, 0);
        button1.Name = "button1";
        button1.Size = new System.Drawing.Size(21, 23);
        button1.TabIndex = 0;
        button1.Text = "X";
        button1.UseVisualStyleBackColor = false;
        // 
        // bottom left
        // 
        button2.BackColor = System.Drawing.Color.Red;
        button2.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
        button2.ForeColor = System.Drawing.SystemColors.ButtonFace;
        button2.Location = new System.Drawing.Point(0, this.Height - 23);
        button2.Name = "button2";
        button2.Size = new System.Drawing.Size(21, 23);
        button2.TabIndex = 1;
        button2.Text = "X";
        button2.UseVisualStyleBackColor = false;
        button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
        // 
        // bottom right
        // 
        button3.BackColor = System.Drawing.Color.Red;
        button3.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
        button3.ForeColor = System.Drawing.SystemColors.ButtonFace;
        button3.Location = new System.Drawing.Point(this.Width - 21, this.Height - 23);
        button3.Name = "button3";
        button3.Size = new System.Drawing.Size(21, 23);
        button3.TabIndex = 2;
        button3.Text = "X";
        button3.UseVisualStyleBackColor = false;
        button3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
        // 
        // top right
        // 
        button4.BackColor = System.Drawing.Color.Red;
        button4.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
        button4.ForeColor = System.Drawing.SystemColors.ButtonFace;
        button4.Location = new System.Drawing.Point(this.Width - 21, 0);
        button4.Name = "button4";
        button4.Size = new System.Drawing.Size(21, 23);
        button4.TabIndex = 3;
        button4.Text = "X";
        button4.UseVisualStyleBackColor = false;
        button4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));



        this.Controls.Add(button4);
        this.Controls.Add(button3);
        this.Controls.Add(button2);
        this.Controls.Add(button1);
    }


}
amin29 a
  • 121
  • 1
  • 7