【问题标题】:How to access Clipboard from System.Timers.Timer [duplicate]如何从 System.Timers.Timer 访问剪贴板 [重复]
【发布时间】:2019-04-30 22:25:27
【问题描述】:

当某个条件在某个时间点为真时,我正在尝试从我的应用程序中捕获屏幕截图并将其设置为picturebox.Image。这种情况必须反复检查。 为了检查这种情况,我使用了System.Timers.Timer。但是Clipboard.GetImage() 不起作用。

我已经尝试了以下代码,但它不起作用。

timer = new System.Timers.Timer();
timer.Interval = 10000; //I'm checking the condition every 10 second or so
timer.Elapsed += OnTimedEvent;
timer.AutoReset = true;
timer.Enabled = true;
void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
{
            if(myCondition==true)
               GetScreenshot();
}
void GetScreenshot()
{
            try
            {
                SendKeys.SendWait("{PRTSC}");
                Thread.Sleep(500);

                var image = Clipboard.GetImage();

                pictureBox1.Image = image;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
}

这不起作用,如果我尝试保存图像,则会出现Object reference not set 类异常。

我在某处读到它是由于计时器为 MTA 而发生的,因此它无法访问剪贴板。我曾尝试使用System.Windows.Forms.Timer,但由于我猜是持续检查,这会减慢程序速度。

有什么简单的方法可以让它在不降低性能的情况下工作。 我对 C# 很陌生,所以对某个解决方案的工作原理进行一些描述会很有帮助。

【问题讨论】:

  • 您是否尝试在代码中截取屏幕截图而不是在某处发送密钥?
  • 虽然您所做的听起来没有错,但使用以下代码可以很好地实现类似的结果:code.msdn.microsoft.com/windowsdesktop/…
  • 听起来myCondition == true时只需要截图。您是否考虑过将myCondition 设为属性,然后从那里调用GetScreenshot()(在setter 中,并且仅在value == true 时)?

标签: c#


【解决方案1】:

Clipboard.GetImage 返回存储在剪贴板中的图像。 剪贴板是有些复杂的存储;有可能同时存储不同类型的不同数据,应该作为一个全新的话题来讨论。

但是,您提到您想要屏幕截图。剪贴板本身没有捕获屏幕的功能,除非特定软件截取屏幕截图并将其放入剪贴板。例如 PrtScr 按钮就是这样做的。

This link 但是,如果您想自己捕获屏幕,可能会有所帮助:

Bitmap bmpScreenshot = new Bitmap(Screen.PrimaryScreen.WorkingArea.Width,
                       Screen.PrimaryScreen.WorkingArea.Height,
                       PixelFormat.Format32bppArgb);

Graphics gfxScreenshot = Graphics.FromImage(bmpScreenshot);


gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.WorkingArea.X,
                        Screen.PrimaryScreen.WorkingArea.Y,
                        0,
                        0,
                        Screen.PrimaryScreen.WorkingArea.Size,
                        CopyPixelOperation.SourceCopy);

bmpScreenshot.Save("Screenshot.png", ImageFormat.Png);

【讨论】:

  • 不要从另一个帖子复制代码,而是投票关闭作为另一个帖子的副本。
  • @RufusL 以及复制的代码我已经提供了一些解释,这是其他帖子所缺乏的。没有它,OP 可能对这些事情有错误的把握。
  • 是的,但是“剪贴板很复杂”的附加信息真的是一个答案吗?从System.Timers.Timer 切换到System.Windows.Forms.Timer 后,OP 的代码在我的机器上运行良好。
猜你喜欢
  • 2011-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-05
  • 2017-12-23
相关资源
最近更新 更多