首页 > 解决方案 > 如何从 System.Timers.Timer 访问剪贴板

问题描述

我正在尝试从我的应用程序中捕获屏幕截图并将其设置为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# 很陌生,所以对某个解决方案如何工作的一些描述将非常有帮助。

标签: c#

解决方案


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

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

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

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

推荐阅读