4

I am developing a feedback system for an automotive company. On the billing desk, there is a dual monitor setup: one for a billing person and one for a customer who's giving feedback. My need is to duplicate a Windows form on both screens, as mirror images, So that the billing person can see what feedback the customer is giving.

I am using the code below for display on the secondary screen:

 Screen[] sc;
        Form f = new Form();
        sc = Screen.AllScreens;
        f.FormBorderStyle = FormBorderStyle.None;
        f.Left = sc[1].Bounds.Left;
        f.Top = sc[1].Bounds.Top;
        f.Height = sc[1].Bounds.Height;
        f.Width = sc[1].Bounds.Width;
        f.StartPosition = FormStartPosition.Manual;
        f.Show();

However, it will not mirror the form on the primary screen. I had also referred to the duplicate window question, but it will create different instances for the same form, which will not mirror the Windows form. How can I mirror it on both screens?

Community
  • 1
  • 1
Hot Cool Stud
  • 1,145
  • 6
  • 25
  • 50
  • 2
    Why negative vote? It seems to be a real question. – Oğuz Sezer Dec 18 '14 at 07:37
  • How do you expect the secondary form to mirror the original one? In your code, you are just opening a form (or so it seems, if `f` is a Form), but there's no code there that would mirror the original one at all. The `Color c = Color.Red;` line baffles me though – Jcl Dec 18 '14 at 08:23
  • f is object of Form. I am asking how can i mirror original one, in above code i had shown how i am opening form on secondary screen. – Hot Cool Stud Dec 18 '14 at 08:27
  • The need for mirroring is a very strange one and pretty unlikely to be appropriate. But you'll need to write a *lot* more code. Iterate the Controls and change the Location property. And every control needs to notify the other form when the customer modifies its content. Doing this in hardware with the second monitor simply displaying the same content as the first is a very trivial solution. – Hans Passant Dec 18 '14 at 08:44
  • @HansPassant if there's no need for the mirrored form to be editable (the question says it needs to be seen only), it's trivial to do it by mirroring a bitmap also, as I've shown in my sample project – Jcl Dec 18 '14 at 08:52

2 Answers2

5

One possible way to do it would be to capture the form that is inputting the data to a image on a timer (use a reasonable delay so that it's "almost realtime") and use it on a PictureBox on the secondary form. To capture the form to a image you do:

Bitmap bmp = new Bitmap(form.Width, form.Height);
form.DrawToBitmap(bmp, new Rectangle(Point.Empty, bmp.Size));

Then you assign bmp as the image to the PictureBox on the other form.

I've made a quick sample project and uploaded it here: https://www.dropbox.com/s/pjuk3zvpbglhodb/SOTestMirror.zip?dl=0

Lacks opening the form on the secondary screen and styling, but shows a possible way to do it

The result is: Result

For the record: I have no clue why when DrawToBitmap is called on a form it copies to the bitmap using a Windows 7 chrome instead of the Windows 8 one... that's interesting, to say the least (and I'd say a bug). That's running on Win 8.1. (Since I haven't seen this mentioned anywhere, I've opened a bug on Connect: https://connect.microsoft.com/VisualStudio/feedback/details/1059444/in-windows-8-drawtobitmap-on-a-form-draws-the-windows-7-chrome)

Jcl
  • 27,696
  • 5
  • 61
  • 92
  • is there any way by which i can capture secondary screen instead of form. – Hot Cool Stud Dec 18 '14 at 08:31
  • Yes, see this answer: http://stackoverflow.com/questions/362986/capture-the-screen-into-a-bitmap to capture the screen to a bitmap – Jcl Dec 18 '14 at 08:32
0

Here are simple code that take a screenshot from the extended screen and display in the picture box. you can save to image file as well.

Add this code in timer to refresh screen at some interval.

private Bitmap bmpScreenshot;
bmpScreenshot = new Bitmap(Screen.AllScreens[1].Bounds.Width,
                                           Screen.AllScreens[1].Bounds.Height,
                                           PixelFormat.Format32bppArgb);

Graphics.FromImage(bmpScreenshot).CopyFromScreen(Screen.AllScreens[1].Bounds.X,
                                         Screen.AllScreens[1].Bounds.Y,
                                         0,
                                         0,
                                         Screen.AllScreens[1].Bounds.Size,
                                         CopyPixelOperation.SourceCopy);

pictureBox1.Image = bmpScreenshot;
pictureBox1.Refresh();
GC.Collect();

you also can get the screenshot of primary screen.

Dhaval
  • 62
  • 8
  • That code is available in this other answer which I commented to the OP: http://stackoverflow.com/questions/362986/capture-the-screen-into-a-bitmap (and **should** be a comment since it's not answering the original question). Also, the `GC.Collect()` at the bottom is completely unneeded (at least for the purpose of what the OP is trying to achieve), try to avoid recommending it unless there's a specific need for it. Check http://blogs.msdn.com/b/ricom/archive/2004/11/29/271829.aspx – Jcl Dec 30 '14 at 16:46