Capture Screen with (VB)

Hi all

I need to capture the screen just like the print screen key on the keyboard and save this image, I have been surfing around for this and I found code for it. After a lot search and coding I have the following class. This code works PERFECTLY on a Windows Forms project on visual studio, BUT the same class on a web application returns a huge BLACK image the size of the screen. I finally found that the problem lies on a GDI32 library function called BitBlt, which returns false if there is an error, on the web app this fuctions reurns false, BUT NO reasons why.

Here is the class to Capture Screen:

Imports System
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Drawing.Imaging

Namespace ScreenShot
    '/ <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 -
            ' 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
            Dim functionOK As Boolean

            functionOK = GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY)
            If Not functionOK Then
                Dim errorValue As Integer
                Dim errorString As String
                errorValue = Err.LastDllError
                errorString = Err.Description
            End If
            ' restore selection
            GDI32.SelectObject(hdcDest, hOld)
            ' clean up
            User32.ReleaseDC(handle, hdcSrc)

            ' get a .NET image object for it
            Dim img As Image = Image.FromHbitmap(hBitmap)
            ' free up the Bitmap object

            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 User32
            <StructLayout(LayoutKind.Sequential)> Public Structure RECT
                Public left As Integer
                Public top As Integer
                Public right As Integer
                Public bottom As Integer
            End Structure
            <DllImport("user32.dll")> Public Shared Function GetDesktopWindow() As IntPtr
            End Function
            <DllImport("user32.dll")> Public Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
            End Function
            <DllImport("user32.dll")> Public Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As IntPtr
            End Function
            <DllImport("user32.dll")> Public Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef rect As RECT) As IntPtr
            End Function
        End Class 'User32
    End Class 'ScreenCapture
End Namespace 'ScreenShot
Who is Participating?
devsolnsConnect With a Mentor Commented:
Well you might be able to leverage an existing ActiveX control.  For example microsoft uses one for its remote desktop web.  There might be a free one that exists.  Try google,

If not writing your own ActiveX control is pretty easy,

RamuncikasConnect With a Mentor Commented:
The reason is that windows app works on the user account who has launched the app. But web app works under ASPNET account. It's not the same as ASPNET user account has no so called interaction with desktop. If you want to grab printscreen from your web app user you have to use javascript or activex for that purpose, but if you want to grab server's screen then I'm afraid it's imposible
sguerraAuthor Commented:
Yes I need to grab users screen NOT SERVER's.
So Is there any chance you have a link or something to where I can find the javascript version of this?

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

sguerraAuthor Commented:
Also, if what you say it's true, the problem lies in the "User32.GetDesktopWindow()" function, which is probably trying to get ASPNET's account desktop. Its probably not posible but can I use another function or the same but whith the purpose of obating the web users desktop?


There is no way to do that in jscript.  You are going to have to create an ActiveX control to do this.   Without ActiveX there is no way to execute the native commands needed to capture scree data on the client.
sguerraAuthor Commented:
Yes I was looking arround and I found that too. And even if it were posible to do soo, there is no way I can save that image on a file of the server. So ActiveX its the solution ..... were do I start and How ... can anyone point me on the right direction, I never programmed an activex before.
sguerraAuthor Commented:
I tried your google search but it gave me activex components which I have to buy ... no good. But anyway thanks for your help. The all thing was for a web page in which I must capture an image from a webcam. Finally I did it with flash (webcam part) and sending the captured image to my aspx page with xml. Worked ok.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.