views:

155

answers:

2

I am using C# .NET to take a screenshot of the contents of a second monitor and display it in a windows on the primary screen.

The code I have is:

screenShotGraphics.CopyFromScreen(
    Screen.AllScreens[screen].Bounds.X,
    Screen.AllScreens[screen].Bounds.Y,
    0,
    0,
    Screen.AllScreens[screen].Bounds.Size,
    CopyPixelOperation.SourceCopy);

This works quite well when it is triggered by a button click, because the slight delay is not noticeable, however when it is run automatically (say every few seconds) the user can easily notice their mouse 'lock up' for a few seconds.

Obviously that's not ideal. So is there a faster way to perform this operation? (Or a way to perform it without interrupting mouse movements or interactivity?

+2  A: 

You could try performing the screen shot with a BackgroundWorker Control, which is an easy way of running the function on a separate thread. Just call your screen shot function within the DoWork event of the BackgroundWorker and whenever you want to run your function just call:

yourBackgroundWorker.RunWorkerAsync()

Edit: It's probably doing this so anything moving on the screen (like the mouse) won't blur the screenshot. You could try to break the screen down into smaller sections and take screenshots, then stitch them together. This would free the mouse for movements between each partial screenshot since you're on a separate thread, but it runs the risk of something changing on the screen (depending on how long it actually takes)

smoore
I already run the screenshot taking in a seperate thread. This doesn't help though - the operation of taking a screenshot this way, even within a seperate thread, seems to lose cause the cursor to freeze briefly.
Elliot Hughes
After some slight modification to your answer I have found that it solves the problem very well. Cheers!
Elliot Hughes
Just out of curiosity, how many sections do you split it in to and how long does the screenshot take to complete?
smoore
A: 

Try to make the call on the principal thread and if you need to save the image to file, do it in another thread...

I think that there isn't other way, cuz the CopyFromScreen, calls the BitBlt api function, witch is the one you must call if you want to do this by api calls... So that is the only thing that Windows provides.

MF