如何在没有我的Winform的情况下获取屏幕截图? [英] How Do I Get Screenshot Without My Winform On It?

查看:87
本文介绍了如何在没有我的Winform的情况下获取屏幕截图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有简单的窗体,只有几个按钮,其中一个应该暂时隐藏表格,将截图复制到剪贴板并返回表格。

这是代码:



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:

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;
}





在某些情况下,当我点击按钮并从剪贴板粘贴图像时,我会看到我的winform。

据我所知,这是因为屏幕截图是在屏幕实际重新绘制之前拍摄的。

有没有办法避免这种影响?



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?

推荐答案

一个可能的解决方法:

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





通过隐藏()的可见性控制超出了消息队列,所以这不是一个可靠的调用,就顺序而言操作。正如我所发现的,即使是最低的消息传递优先级 SystemIdle 也会为您提供实际保证隐藏窗口从屏幕渲染中过早的事件。



-SA



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


由于我无法重现MSPaint.exe和剪贴板的问题,这是我的测试程序,完成,减少到只有一个文件(不包括项目文件):

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):
/*
    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



说明:从头开始创建项目,确保上面只显示了3个引用的程序集,删除所有文件,添加上面显示的一个源文件。

有趣的观察: [STAThread] 对于剪贴板操作至关重要,它无法正常工作在 [MTAThread]



如果应用程序窗口最大化没问题,如果MSPaint.exe窗口没问题在后台。



-SA


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


这篇关于如何在没有我的Winform的情况下获取屏幕截图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆