Community discussion forum
[4630] Capture a Screen Shot
-
This thread is for discussions of Capture a Screen Shot.
-
Advertisement
Simply the fastest line-level profiler for .NET ever
“The low overhead means it has minimal impact on the execution of my program”
Mark Everest, Development Team Leader, Renault F1 Team Ltd.Try out the new ANTS Profiler 4 for yourself. Download your 14-day trial now
-
Is there any VB.NET code available for this ScreenCapture utility ? and can it work on the web ?
thanks -
I appreciate that both VB.NET and C# code was posted, however there are two shortcomings
1) No sample app to run this. It is easy to knock up a app to run the whole screen capture. Locating a window to capture is doable but needs more API calls.
2) No function to do a user-selectable rectangle part of a screen. -
I see the VB code but I cannot get it to compile.
Is something like this even valid in VB.NET:
Public Shared<DllImport("gdi32.dll")> _
Function CreateCompatibleBitmap(hDC As IntPtr, nWidth As Integer, nHeight As Integer) As IntPtr
Public Shared<DllImport("gdi32.dll")> _
Function CreateCompatibleDC(hDC As IntPtr) As IntPtr
Don't you need to end the Functions? Am I missing something important here?
I just created a new windows app and added existing from solution explorer but there are many things keeping it from compiling. Any suggestions? -
Imports System
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Drawing.Imaging
Namespace ScreenShotDemo
_
'/ <summary>
'/ Provides functions to capture the entire screen, or a particular window, and save it to a file.
'/ </summary>
Friend Class ScreenCapture
'/ <summary>
'/ Creates an Image object containing a screen shot of the entire desktop
'/ </summary>
'/ <returns></returns>
Public Function CaptureScreen() As Image
Return CaptureWindow(User32.GetDesktopWindow())
End Function 'CaptureScreen
'/ <summary>
'/ Creates an Image object containing a screen shot of a specific window
'/ </summary>
'/ <param name="handle">The handle to the window. (In windows forms, this is obtained by the Handle property)</param>
'/ <returns></returns>
Public Function CaptureWindow(ByVal handle As IntPtr) As Image
' get te hDC of the target window
Dim hdcSrc As IntPtr = User32.GetWindowDC(handle)
' get the size
Dim windowRect As New User32.RECT
User32.GetWindowRect(handle, windowRect)
Dim width As Integer = windowRect.right - windowRect.left
Dim height As Integer = windowRect.bottom - windowRect.top
' create a device context we can copy to
Dim hdcDest As IntPtr = GDI32.CreateCompatibleDC(hdcSrc)
' create a bitmap we can copy it to,
' using GetDeviceCaps to get the width/height
Dim hBitmap As IntPtr = GDI32.CreateCompatibleBitmap(hdcSrc, width, height)
' select the bitmap object
Dim hOld As IntPtr = 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
Dim img As Image = Image.FromHbitmap(hBitmap)
' free up the Bitmap object
GDI32.DeleteObject(hBitmap)
Return img
End Function 'CaptureWindow
'/ <summary>
'/ Captures a screen shot of a specific window, and saves it to a file
'/ </summary>
'/ <param name="handle"></param>
'/ <param name="filename"></param>
'/ <param name="format"></param>
Public Sub CaptureWindowToFile(ByVal handle As IntPtr, ByVal filename As String, ByVal format As ImageFormat)
Dim img As Image = CaptureWindow(handle)
img.Save(filename, format)
End Sub 'CaptureWindowToFile
'/ <summary>
'/ Captures a screen shot of the entire desktop, and saves it to a file
'/ </summary>
'/ <param name="filename"></param>
'/ <param name="format"></param>
Public Sub CaptureScreenToFile(ByVal filename As String, ByVal format As ImageFormat)
Dim img As Image = CaptureScreen()
img.Save(filename, format)
End Sub 'CaptureScreenToFile
_
'/ <summary>
'/ Helper class containing Gdi32 API functions
'/ </summary>
Friend Class GDI32
Public Shared SRCCOPY As Integer = &HCC0020
' BitBlt dwRop parameter
<DllImport("gdi32.dll")> _
Public Shared Function BitBlt(ByVal hObject As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hObjectSource As IntPtr, ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As Integer) As Boolean
End Function
<DllImport("gdi32.dll")> _
Public Shared Function CreateCompatibleBitmap(ByVal hDC As IntPtr, ByVal nWidth As Integer, ByVal nHeight As Integer) As IntPtr
End Function
<DllImport("gdi32.dll")> _
Public Shared Function CreateCompatibleDC(ByVal hDC As IntPtr) As IntPtr
End Function
<DllImport("gdi32.dll")> _
Public Shared Function DeleteDC(ByVal hDC As IntPtr) As Boolean
End Function
<DllImport("gdi32.dll")> _
Public Shared Function DeleteObject(ByVal hObject As IntPtr) As Boolean
End Function
<DllImport("gdi32.dll")> _
Public Shared Function SelectObject(ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr
End Function
End Class 'GDI32
_
'/ <summary>
'/ Helper class containing User32 API functions
'/ </summary>
Private Class User3 -
Hi:
I created a full example of how to use this code...
SOme changes...
* You can email the captured screen to any address
* I added a app.config file so you can specify SMTP server and email address to send image to...
Have some fun with it!
Its at
http://www.webdataserver.com/downloads/screencapture.zip
Just update the config.app file with your email and smtp values. When the project is built, it will be copied with the EXE created and renamed "winscreensnapshot.exe.config"
You can use WIndows Scheduler to run it at any time interval too... just a thought...
Thanks
Dotnetguy -
Is the zip available atm?
-
ATM? I am sorry, not sure what this is an abbrevation for...
-
this code is for c#... there is no conversion for c# to vb directly....
if you know both languages its not to hard, but my guess is you don't...
just make sure if you do a search you include VB in it..
-N14 -
The code I posted was cut and pasted from ScreenCapture.vb
-
I've been working with this code and I have the capture working ok. However, it does not seem possible to capture things that are off the viewable screen - is this true?
Does anyone know of a way to do a screen capture, but retrieve, say, the contents of a browser window stretched beyond the screen?
Thanks. -
I compile the code in VB.net and runs fine...
(using vbnet 2003).
no modifs required. Maybe something wrong with your references?
I simply put the code in a class... (and the other code in a form
)
If you want capture only the desktop --> make invisible the application before capture (obvious). -
I tried using this code for a web application and it doesn't seem to work. The image that gets saved to disk is simply JUST BLACK.
Does anyone know how to get around this?
Thanks -
Hi,
I've got a problem similar to the previous one. I'm trying to capture a frame from a DVD player ( realized using the MSWEBDVD.DLL ), but the image is black!
Has anyone got any suggestion?
Thanks,
Cla -
I think you'll probably find you get a black screen if you try and capture the image yourself using printscreen too. This is a problem capturing videos to do with layers or something - beyond my understanding

-
Can anyone please tell me how I would include the mouse image with my screen capture? I've done google after google and havent came up with anything.
Thanks
Steve -
I'm having a problem with capturing only a black image if I try to run this in the code behind of an asp.net web page (or from a script directly on the page, for that matter). It also doesn't matter if I run it directly on the server or from a remote machine. Either way it creates the designated image format in the proper directory...but plain black.
From what I've found in other locations on the net, this seems to be a common problem. Has anyone seen/developed a good workaround for this? -
I do have VisualStudio.net 7.0. I do simple VB program. I am having some problem compiling this code. I think if I get some hints, I can do it. First of all, say I do open an empty vb project. Just a window with one 'Exit' button.
Q1. What name I should put for my project? Any restrictions?
Now, in the code page, at the top, I add the "using xxxx" lines.
In this vb code, I see Namespace, no idea what that means or how to use that.
Q2. Which portion of codes from example do I copy?
Q3. Where in my project's code I paste it? In side "Class Form1" which was created automatically? Or outside that scope?
Q4. Or I copy the whole example code and put "Class form1" section inside it?
My questions might seem stupid, but I am not sure how to work with multiple classes in VB. Specially, .NET is totally new to me. Please, be elaborate when you reply. Thanks in advance. -
Hi,
When I want to open the project using my VisualStudio.Net it says, "Project c:..\..\screencapture was created with newer version of VisualStudio which is incompatible with your version. You can olny open this project in newer VisualStudio."
All the info about my VisualStudio .NET (From Help->About... .. .)
Microsoft Development Environment 2002 : Version 7.0.9466
Microsoft .NET Framework 1.0 : Version 1.0.3705
Microsoft Visual Basic .NET 55603-652-0000007-18318
I am using HomeXp SP1 (I haven't installed SP2)
Is there a newer VisualStudio.NET software? What I need to do to complie this code? Thanks. -
It looks like that project was created in Visual Studio 2003. However, you should simply be able to create your own new project in VS2002, and add the files back.
-
Thanks a lot for the suggestions. It worked. I thought I had MSVisualStudio_2003 (ver 7.0). Now I have two new questions.
1. Is there any parameter that will allow me to control the Quality of the Jpeg file? My screen resulotion is 1280x1024, resulting file size is (+/-)162Kb. I want to get a slight better quality.
2. I use multiple monitors, this program only captures the Default (Monitor_1) screen. It is not a big deal, cause who will use the program he has only one monitor. But, still I want to know.
I didn't thought I'll get response so quickly. Now I am hoping for a quick reply
-
You might want to take a look at http://www.codeproject.com/cs/media/bitmapmanip.asp, and scroll down to "ConvertBitmapToJpeg"

-
Everything is told in detail i nthat page. Thanks once again.
-
I 've tried this code. It works, but every time I took screenshot the amount of used memory increased by appr. 1600 KBytes (My screen is 1024x768, 32 bit). I need to take screenshot every second, so very soon my work almost stops...
The statement (in On Timer_Tick Sub)
Me.PictureBox1.Image = sc.CaptureScreen
causes this increment
Any comments?
Andrej Otroshenko -
Hi, i have had the same problem in previous projects.
for some reaosn in .net when using images in subs, they do not dispose properly, even when you call the dispose method!
to overcome this problem, you must write a loop instead of using a timer
eg.
dim running as boolean
running = True
Do While Running = True
Me.PictureBox1.Image = sc.CaptureScreen
Application.DoEvents <-- allows screen to refresh and prevents crash
Loop
and to add a delay in (to simulate your timer)
dim running as boolean
dim t as threading.thread
dim interval as integer
interval = 1000
running = True
Do While Running = True
Me.PictureBox1.Image = sc.CaptureScreen
Application.DoEvents <-- allows screen to refresh and prevents crash
t.sleep(interval)
Loop
also, if you havnt tried this before you might not be aware that you cant put that i nthe form load or activate events otherwise you will get problems, as load is called before the form is displayed and activate is called everytime the form is given focus
therefore, use your timer to call the sub you make for your loop, and have the timer then turn itself off.
regards,
-Phill -
Thanks!
I solved this problem in another way. I used the code of CaptureScreen not as class, but as the part of the Form1 class (the class of the main form of the application). And I changed this code a little.
In the class Form1 I declared:
Dim bmpResult As Bitmap
and in the Sub CaptureWindow(handle) I wrote:
If Not (bmpResult Is Nothing) Then
bmpResult.Dispose()
End If
bmpResult = Bitmap.FromHbitmap(hBitmap)
where bmpResult is declared in class Form1
Now all is working OK! The timer ticks and every tick gets the screen image...
-
Ah Good,
Great to hear you have already found a solution
-
This is not for a web application - it's for client code...

-
Hey James -
Might I suggest you add the following code to your class:
Code: if (HTTPContext.Current!=null) { Developer.Current.Smack(Developer.BodyPart.Head); }
Seriously, thanks for the class... -
While compiling this screen capture class in VS2003.net (using web form), I am getting following error message:
C:\Inetpub\wwwroot\IssueTracking\ScreenCapture.aspx.cs(33): 'Image' is an ambiguous reference
Anyone has any clue...
-
Hi
I have an application which lists all the active applications in a combo box and lets the user select an application. I am trying to get the handle to this selected application and calling the CaptureWindowToFile function and trying to save it as a bmp. Unfortunately I am unable to get the screen shot of my selected application.
Any help in this regard will be greatly appreciated.
Thanks in Advance,
Shyam
-
How are you getting the active applications? Usually you would enumerate all the windows that are open by getting their handles, then getting the window title from that to be put into the combobox, with the handle saved as well. This will use a lot of API calls, and you might want to use Google quite a bit. Then all you have to do is pass the handle to the function.
-
Hi
Thanks so much for your reply.
I am exactly doing the way you have said it. To explain briefly what I am doing ...
I have a VB.NET application where I need to capture the screenshot of the applications that are currently running. So I am enumerating all the process and populating a combo box with only those which has a main window title (the other processes do not have a main window title so that I am filtering out only the applications in the task bar). Then I am allowing the user to select an application and passing the main window handle to get the screenshot. But this unable to do it. Everytime I pass the main window handle I am only getting the screenshot of the current active application and NOT the screenshot of the application the user chooses. I would really appreciate if you have any sample code to do this.
I am using Microsoft Dev Environment 2003, ver 7.1.3088 and .NET framework 1.1
Thanks in Advance,
Shyam
-
I would make sure that all of the window handles are different - by the sounds of it you are only retrieving the active window's handle, which is not what you want.
Unfortunately I can't help you with code, as I know nothing of VB .NET (I gave you a general explanation), but I can give you these tips:
- Debug and put breakpoints at the point where you get the handles. This way you can check and make sure that they are all unique
- Make sure that the method you are using is the right one
- Check your code!
I hope this helps you in some way... sorry I can't post code, if I could, I would!
-
Hi
Thanks for your reply.
Even if I hardcode the windows handle I want the screenshot of I am getting a bitmap with a black rectangle. I just want to make sure that if I pass a windows handle will I be able to get the screen shot or not using this Screenshot class. Because if I give the current windows handle it is giving the bitmap correctly.
Shyam
-
I'm not sure what the problem is. I'll be able to be progamming again next week so I'll look into it.
-
i had the same problem too,but i just tried aca and solved thr problem, here is the details. i hope it helps.
http://screen-capture.spaces.live.com/blog/cns!543BF253C6896A68!133.entry -
Make sure that you are using SRCCOPY! Also make sure that all the code is exactly the same as it appears here. I tried this code out in C++ and it DID NOT WORK at first. A little investigation showed that I had cut corners and written SRCPAINT instead of SRCCOPY...
If that doesn't solve your problem, I'lm not sure what the problem is
... -
I've got a problem with screenshots of direct3d windows. After taking a first shot everything is fine. The second and all following shots are not updated correctly. Instead they always show the first done screenshot. Normal windows are updated normally. So is there anything I can do? I wonder if there's a command missing for flushing direct3d input or something else.
Has anybody an idea?
Thanks, Maik
-
I have not tried it yet..but lets see..it
-
Can i know the same concept for asp.net
-
Great article. I used in my application.
Post a reply
Quick links
Recent activity
- mac clark replied to Complete portal of VOIP pro...
- Vijay Kumar Tripathi replied to I have to print the content...
- Rajasekhar Reddy replied to increase maxRequestLength i...
- Cason Lopez replied to Need suggestions......
- Subhadip Roy replied to help me in file handling in...
- Maneesh Jain replied to Complete portal of VOIP pro...
Enter your message below
Sign in or Join us (it's free).