Click here to Skip to main content
15,895,142 members
Please Sign up or sign in to vote.
4.43/5 (3 votes)
See more:
I have simple windows form with few buttons, one of them should temporarily hide the form, copy the screenshot to the clipboard and return the form back.
Here is the code:

C#
private void ButtonClick(object sender, EventArgs e)
{
    Hide();
    Clipboard.SetImage(ScreenShot());
    Show();
}

private Image ScreenShot()
{
    var screenSize = Screen.PrimaryScreen.Bounds.Size;
    var image = new Bitmap(screenSize.Width, screenSize.Height);
    using (var g = Graphics.FromImage(image))
    {
        g.CopyFromScreen(Point.Empty, Point.Empty, screenSize);
    }
    return image;
}


In some cases when i click the button and paste the image from clipboard somewhere i see my winform on it.
As i understand this happens because screenshot is taken before the screen is actually repainted.
Is there any way to avoid this effect?
Posted
Comments
Sergey Alexandrovich Kryukov 10-May-15 15:20pm    
Pretty interesting question; I up-voted with my 4.
—SA

One possible work-around it this:
C#
this.Opacity = 0;
System.Windows.Forms.Clipboard.SetImage(ScreenShot());
this.Opacity = 1;


Visibility control through Hide() goes outside of the message queue, so this is not a reliable call, in terms of order of operation. As I found, even the lowest messaging priority SystemIdle gives you the event which is too early to actually guarantee hide the window from screen rendering.

—SA
 
Share this answer
 
v2
Comments
[no name] 10-May-15 16:30pm    
The workaround with zero opacity seems to be working, but i've found a case when it doesn't and which is stably reproduced on my computer: i open Paint application, put my form to the top left corner of the screen, press the button, then i switch to the Paint, press ctrl+v and see my winform.
Sergey Alexandrovich Kryukov 10-May-15 17:13pm    
I did not know anything about the other case. Will you accept the answer formally?

Please ask another question about your Paint and Ctrl+V and explain it all in detail. Ctrl+V should mean clipboard use with the UI, this is a different thing; and you did not describe it in all the detail.

—SA
[no name] 10-May-15 17:53pm    
I've accepted, thank you for your solution.
However, i don't understand why "this is a different thing", i used Paint just for viewing the result of screeshoting and noticed that if i make the shot of it - i can see the same thing as for using Hide - i see wrong image in the clipboard - screenshot is taken before the screen is repainted. So if i just save the result as .BMP image on the hard drive and open - the result is the same - this doesn't look like clipboard use with the UI.
first step: i opened paint
link1
second step: i just putted my form to the top left corner
link2
third step: the result image
link3
the result image via save_button:
link4
Sergey Alexandrovich Kryukov 10-May-15 20:57pm    
This is a different question. Perhaps there is something in common in some aspects I did not understand yet, but please see the last comments by Sascha Lefèvre and my last reply.

Let's see. You don't use Paint "for viewing". Paint is actually a WM_PAINT handler, where you render graphics. And we are talking about rendering whole screen after hiding. Are you talking of the same application changing Opacity and taking a screen shot? How is it related to "save"?

—SA
[no name] 11-May-15 11:55am    
It seems like a confusion with a word "Paint". What i've meant was not firing a control's event called "Paint". :)
There is windows application in "accessories" group, which allows you to make some drawings and also paste the images from Clipboard.
What i've done - was opening this application at background behind my Form, making a screen shot via my Form and then viewing it in Paint application.
So we are talking about rendering whole screen after hiding.
Having the Paint in background, i've changed the opacity of my Form, then i took the screenshot and see the effect just as after hiding.
And i am concerning if there is a possibility to be 100% sure that i will have clean screenshot.
Thanks.
As I could not reproduce the problem with MSPaint.exe and the clipboard, here is my test program, complete, reduced to just one file (not counting project file):
C#
/*
    Referenced assemblies:
    1) System;
    2) System.Windows.Forms;
    3) System.Drawing;
    4) Nothing else.
*/
namespace HideAndCopyForm {
    using System;
    using System.Windows.Forms;
    using System.Drawing;

    public class MainForm : Form {

        public MainForm() {
            Button btn = new Button();
            btn.Text = "&Test";
            btn.Parent = this;
            btn.Click += (sender, eventArgs) => {
                this.Opacity = 0;
                System.Windows.Forms.Clipboard.SetImage(ScreenShot());
                this.Opacity = 1;
            }; //btn.Click
        } //MainForm

        Image ScreenShot() {
            var screenSize = Screen.PrimaryScreen.Bounds.Size;
            var image = new Bitmap(screenSize.Width, screenSize.Height);
            using (var g = Graphics.FromImage(image)) {
                g.CopyFromScreen(Point.Empty, Point.Empty, screenSize);
            }
            return image;
        } //ScreenShot

        [STAThread]
        static void Main() {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        } //Main

    } //class MainForm

} //namespace HideAndCopyForm

Instructions: create project from scratch, makes sure there are only 3 referenced assemblies shown above, remove all files, add exactly one source file shown above.
Interesting observation: [STAThread] is essential for the clipboard operation, it cannot work in [MTAThread].

No problem if the application window is maximized, no problem if MSPaint.exe window is in background.

—SA
 
Share this answer
 
Comments
[no name] 14-May-15 14:08pm    
Well, i'm not sure how creating project without designer and with less references impacts on the code execution...
Here are both cases, just copypasted your whole complete solution:
http://screencast.com/t/8fiI42ukt
Tested it on other computer with more powerful cpu, but without discrete gpu - it reproduces the same way.
Sergey Alexandrovich Kryukov 14-May-15 14:21pm    
No, I did not mean that these detail could impact anything. I just wanted to provide 100% of the code, just in case. My idea is: if you don't have a clever idea, try out a stupid one. :-)
If so many detail are already matched, anything at all could look suspicious.
Unfortunately, I don't have so many things to test it, and not so much time...
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900