Author Topic: Calibrate two screens  (Read 5148 times)

Offline jolmash

  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
on: January 23, 2008, 10:01:06 PM
How can I calibrate two screens? I mean, one screen in my desktop, another projecting.

Thanks in advance



Offline atomriot

  • *
  • Posts: 177
  • Karma: +16/-0
    • View Profile
Reply #1 on: January 24, 2008, 10:56:48 AM
I put this in another thread but i think it is better suited here

Quote
oh yeah, i had to add that because we commonly just extend our desktop for our conference room and it initially only worked with the default screen.
this is my calibration form constructor from CalibrationFrom.cs
Code: [Select]
        public frmCalibration(bool useThis,int left,int top)
        {
            [color=red]this.Location = new Point(left, top);
           
            Rectangle rect = new Rectangle();
            Screen[] allScreens = Screen.AllScreens;
            int x = left;
            int y = top;
            int width = 0;
            int height = 0;
            if (Screen.AllScreens.Length > 1 && !useThis)
            {
                foreach (Screen screen in allScreens)
                {
                    if (screen.Bounds.X < x)
                        x = screen.Bounds.X;
                    if (screen.Bounds.Y < y)
                        y = screen.Bounds.Y;
                    if (screen.Bounds.Right > width)
                        width = screen.Bounds.Right;
                    if (screen.Bounds.Bottom > height)
                        height = screen.Bounds.Bottom;
                }
                rect = new Rectangle(x, y, width, height);
            }
            else
            {
                rect = Screen.GetBounds(new Point(left+1,top+1));
            }[/color]

            InitializeComponent();
            this.FormBorderStyle = FormBorderStyle.None;
            this.Left = rect.Left;
            this.Top = rect.Top;
            this.Size = new Size(rect.Width, rect.Height);
            this.Text = "Calibration - Working area:" + Screen.GetWorkingArea(this).ToString() + " || Real area: " + Screen.GetBounds(this).ToString();

            this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyPress);

           
            screenHeight = rect.Height;
            screenWidth = rect.Width;

            bCalibration = new Bitmap(screenWidth, screenHeight, PixelFormat.Format24bppRgb);
            gCalibration = Graphics.FromImage(bCalibration);
            pbCalibrate.Left = 0;
            pbCalibrate.Top = 0;
            pbCalibrate.Size = new Size(rect.Width, rect.Height);
           
            gCalibration.Clear(Color.White);

            BeginInvoke((MethodInvoker)delegate() { pbCalibrate.Image = bCalibration; });
        }

the changed part is pretty much everything before the InitializeComponent(); line.

this is my main form constructor

Code: [Select]
public frmMain()
{
            CheckForIllegalCrossThreadCalls = false;
            screenWidth = Screen.GetBounds(this).Width;
            screenHeight = Screen.GetBounds(this).Height;
            screenTop = Screen.GetBounds(this).Top;
            screenLeft = Screen.GetBounds(this).Left;

            if (Screen.AllScreens.Length > 1)
            {
                Screen[] allScreens = Screen.AllScreens;
                foreach (Screen screen in allScreens)
                {
                    if (screen.Bounds.Right > screenWidth)
                        screenWidth = screen.Bounds.Right;
                    if (screen.Bounds.Bottom > screenHeight)
                        screenHeight = screen.Bounds.Bottom;
                    if (screen.Bounds.Top < screenTop)
                        screenTop = screen.Bounds.Top;
                    if (screen.Bounds.Left < screenLeft)
                        screenLeft = screen.Bounds.Left;
                }
            }
            InitializeComponent();
            CanCalibrate = true;
}

and then i have the methods that handle checking if those radio buttons are selected

Code: [Select]
        private void btnCalibrate_Click(object sender, EventArgs e)
        {
            if (CanCalibrate)
            {
                if (cf == null)
                {
                    if (rdoBtnCurrent.Checked)
                    {
                        cf = new frmCalibration(true, Screen.GetBounds(this).Left, Screen.GetBounds(this).Top);
                    }
                    else
                    {
                        cf = new frmCalibration(false,0,0);
                    }
                    cf.Show();
                }
                if (cf.IsDisposed)
                {
                    if (rdoBtnCurrent.Checked)
                    {
                        cf = new frmCalibration(true, Screen.GetBounds(this).Left, Screen.GetBounds(this).Top);
                    }
                    else
                    {
                        cf = new frmCalibration(false,0,0);
                    }
                    cf.Show();
                }
                calibrationState = 1;
                doCalibration();
            }
        }

        private void Screens_CheckedChanged(object sender, EventArgs e)
        {
            screenWidth = Screen.GetBounds(this).Width;
            screenHeight = Screen.GetBounds(this).Height;
            screenTop = Screen.GetBounds(this).Top;
            screenLeft = Screen.GetBounds(this).Left;

            if (Screen.AllScreens.Length > 1 && !rdoBtnCurrent.Checked)
            {
                Screen[] allScreens = Screen.AllScreens;
                foreach (Screen screen in allScreens)
                {
                    if (screen.Bounds.Right > screenWidth)
                        screenWidth = screen.Bounds.Right;
                    if (screen.Bounds.Bottom > screenHeight)
                        screenHeight = screen.Bounds.Bottom;
                    if (screen.Bounds.Top < screenTop)
                        screenTop = screen.Bounds.Top;
                    if (screen.Bounds.Left < screenLeft)
                        screenLeft = screen.Bounds.Left;
                }
            }
        }


you also have to adjust the calling of the calibration

Code: [Select]
        public void doCalibration(){
            if (cf == null)
                return;
            int x = screenLeft;
            int y = screenTop;
            int size = 25;
            Pen p = new Pen(Color.Red);
            int crossX = 0;
            int crossY = 0;
            switch (calibrationState)
            {
                case 1:
                    crossX = (int)(screenWidth * calibrationMargin);
                    crossY = (int)(screenHeight * calibrationMargin);
                    x += (int)(screenWidth * calibrationMargin);
                    y += (int)(screenHeight * calibrationMargin);

                    cf.showCalibration(crossX, crossY, size, p);
                    dstX[calibrationState - 1] = x;
                    dstY[calibrationState - 1] = y;
                    break;
                case 2:
                    crossX = screenWidth - (int)(screenWidth * calibrationMargin);
                    crossY = (int)(screenHeight * calibrationMargin);
                    x += screenWidth - (int)(screenWidth * calibrationMargin);
                    y += (int)(screenHeight * calibrationMargin);
                    cf.showCalibration(crossX, crossY, size, p);
                    dstX[calibrationState - 1] = x;
                    dstY[calibrationState - 1] = y;
                    break;
                case 3:
                    crossX = (int)(screenWidth * calibrationMargin);
                    crossY = screenHeight - (int)(screenHeight * calibrationMargin);
                    x += (int)(screenWidth * calibrationMargin);
                    y += screenHeight -(int)(screenHeight * calibrationMargin);
                    cf.showCalibration(crossX, crossY, size, p);
                    dstX[calibrationState - 1] = x;
                    dstY[calibrationState - 1] = y;
                    break;
                case 4:
                    crossX = screenWidth - (int)(screenWidth * calibrationMargin);
                    crossY = screenHeight - (int)(screenHeight * calibrationMargin);
                    x += screenWidth - (int)(screenWidth * calibrationMargin);
                    y += screenHeight -(int)(screenHeight * calibrationMargin);
                    cf.showCalibration(crossX, crossY, size, p);
                    dstX[calibrationState - 1] = x;
                    dstY[calibrationState - 1] = y;
                    break;

everything after this in the DoCalibration() method is default. so dont just replace that entire method because then you wont get the case 5 or default

thats pretty much it. basically it should check which screen it is using. you have to pass a bool into the calibration form to tell it to use multiples or not.

hopefully this works for you, i might have left something else out but if so then let me know. it was fun to figure out and is definitely worth digging through the code because it gives you a better understanding of it.

once i get the project done and cleaned up, perhaps it can be put up on the download section as a supplemental project. I could not have gotten this far without Johnny's work, thats for sure.

Details, details. Things to do. Things to get done. Don't bother me with details, just tell me when they're done.
--
James Lionel Price



Offline takai

  • *
  • Posts: 27
  • Karma: +0/-0
    • View Profile
Reply #2 on: May 29, 2008, 11:25:45 PM
Has the code for this been put online somewhere.

Ive used the code snippets you have provided and it is currently pulling the dimensions of the right display, but is still displaying the calibration pattern on display 1.