getting a form's image every so often



Hey all,

I have a problem and I can't find anything on the net to really address
it. We have a program at work that has lots of numbers on the front of
the form because it is a control program for a hydro plant. My boss
would like me to create a web page so our control center can see all of
the numbers but not have access to the actual form. Some of these
numbers are gathered every second, others every five seconds and still
others every minute or ten minutes.

I was thinking the easiest thing to do would be to capture the form's
image every five seconds or so and write the image to disk and then use
an image control on a web page to display it. I have found code
samples to capture a form's image but I'm having a problem with the
function to get the form's image. The code below is called from a
timer that goes off every 5 seconds:

Dim bm As Bitmap


' Get this form's Graphics object.
Dim myGraphics As Graphics = Me.CreateGraphics

' Make a Bitmap to hold the image.
bm = New Bitmap(Me.Width, Me.Height, myGraphics)
Dim bitmapGraphics As Graphics = Graphics.FromImage(bm)
Dim bitmapHandle As IntPtr = bitmapGraphics.GetHdc

' Get the form's hDC. We must do this after
' creating the new Bitmap, which uses myGraphics.
Dim myHandle As IntPtr = Me.CreateGraphics.GetHdc()

' BitBlt the form's image onto the Bitmap.
BitBlt(bitmapHandle, 0, 0, Me.ClientSize.Width,
Me.ClientSize.Height, _
myHandle, 0, 0, SRCCOPY)

Catch ex As Exception
GiveError(ex.ToString, "Error Getting Form Image")
End Try

' Return the result.
Return bm

The message I get is:
"An unhandled exception of type 'System.InvalidOperationException'
occurred in your System.Drawing.dll. Additional information: The
object is currently in use elsewhere."

I know this is occurring on the second call of the function because I
have disabled the timer after the first call and I don't get the error.
I have also tried increasing the timer's Interval to 10 seconds but I
still get the same error.

Has anyone run across this before? All of the posts I have seen on the
web have talked about multiple threads. I know the timer is supposed
to be on its own thread but I don't know how to get around that.

Another workaround I have thought about, instead of capturing the
form's image, is to publish my own performance counters. However,
there are about 30 values to keep track of and that doesn't seem to be
a good solution.

If anyone has suggestions, I'm all ears.



This is just a guess, but I think you need to do a ReleaseHdc on myHandle. I
have a similar function, it also returns a bitmap, and I have two win32 api
calls to ReleaseDC, one for the source and one for the destination.



Thanks for the tip but that didn't help. At first it ran for almost a
full minute and then errored out with the same error. After I
restarted the program it gave me the error almost immediately each time
I tried the program.



I have two suggestions.

1. If you don't already know, find out which statement generated the
exception. Run the code without the try block, let it fail, and let the
debugger tell you where the failure occurs.

2. Sometimes the inner exception gives additional info. Try reporting
ExceptionString(ex) instead of ex.ToString -

Public Function ExceptionString(ByVal MyException As Exception) As String
' return a multiline exception description
Dim t as String = ""
Dim s As String = "Exception"
Dim e As Exception = MyException
While (Not e Is Nothing) And (Len(t) < 10000)
t &= s & ": " & e.ToString
s = "From"
e = e.InnerException
End While
Catch ex As Exception
End Try
Return t
End Function

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question