Reputation: 111
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();
}
}
And
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;
}
And
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;
}
If I set the thread to sleep for 5000ms it will work but will be too slow to display the images. When set it to 500ms or lower like 50ms then after 20-25 seconds i'm getting exception parameter is not valid in Program.cs on
Application.Run(new Form1());
Upvotes: 0
Views: 159
Reputation: 103447
You need to dispatch to the UI thread when you access a control that was created by it.
pictureBox1.Invoke(new Action(() => {
if (pictureBox1.Image != null)
pictureBox1.Image.Dispose();
pictureBox1.Image = sc.CaptureWindowToMemory(windowHandle);
}));
It seems like you could simply be using a System.Windows.Forms.Timer
in place of your background worker, if this is all it's doing.
Upvotes: 1