为什么我在给带有图像的pictureBox后几秒钟内获取参数无效?

时间:2016-04-25 22:57:03

标签: c# .net winforms

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
                try
                {
                    for (int i = 0; i < 1000; i++)
                    {
                        System.Threading.Thread.Sleep(500);
                        if (pictureBox1.Image != null)
                            pictureBox1.Image.Dispose();
                        pictureBox1.Image = sc.CaptureWindowToMemory(windowHandle);
                    }
                }
                catch(Exception err)
                {
                    string error = err.ToString();
                }
        }

public Bitmap CaptureWindowToMemory(IntPtr handle)
        {
            Image img = CaptureWindow(handle);
            Bitmap bmp = new Bitmap(img);
            bmp.Save("foo.png", System.Drawing.Imaging.ImageFormat.Png);
            return bmp;
        }

public Image CaptureWindow(IntPtr handle)
        {
            // get te hDC of the target window
            IntPtr hdcSrc = User32.GetWindowDC(handle);
            // get the size
            User32.RECT windowRect = new User32.RECT();
            User32.GetWindowRect(handle, ref windowRect);
            int width = windowRect.right - windowRect.left;
            int height = windowRect.bottom - windowRect.top;
            // create a device context we can copy to
            IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
            // create a bitmap we can copy it to,
            // using GetDeviceCaps to get the width/height
            IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
            // select the bitmap object
            IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
            // bitblt over
            GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
            // restore selection
            GDI32.SelectObject(hdcDest, hOld);
            // clean up 
            GDI32.DeleteDC(hdcDest);
            User32.ReleaseDC(handle, hdcSrc);
            // get a .NET image object for it
            Image img = Image.FromHbitmap(hBitmap);
            // free up the Bitmap object
            GDI32.DeleteObject(hBitmap);
            return img;
        }

如果我将线程设置为休眠5000毫秒,它将起作用,但显示图像的速度太慢。当它设置为500ms或更低,如50ms,然后在20-25秒后我得到异常参数在Program.cs上无效

Application.Run(new Form1());

1 个答案:

答案 0 :(得分:1)

当您访问由其创建的控件时,您需要调度到UI线程。

pictureBox1.Invoke(new Action(() => {
    if (pictureBox1.Image != null)
        pictureBox1.Image.Dispose();
    pictureBox1.Image = sc.CaptureWindowToMemory(windowHandle);
}));

似乎你可以简单地使用System.Windows.Forms.Timer代替你的后台工作人员,如果这就是它正在做的那样。