如何在没有我的Winform的情况下获取屏幕截图? [英] How Do I Get Screenshot Without My Winform On It?
问题描述
我有简单的窗体,只有几个按钮,其中一个应该暂时隐藏表格,将截图复制到剪贴板并返回表格。
这是代码:
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
也会为您提供实际保证隐藏窗口从屏幕渲染中过早的事件。
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.
由于我无法重现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窗口没问题在后台。
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.
这篇关于如何在没有我的Winform的情况下获取屏幕截图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!