Question

Hey all i have this code here:

Dim p As Process = Process.GetProcessesByName("Cal").FirstOrDefault
Dim target_hwnd As Long = FindWindow(vbNullString, "Calculator")

If p IsNot Nothing Then
    SetWindowPos(target_hwnd, 0, winSize(0), winSize(1), winSize(2), winSize(3), 0)
    AppActivate(p.Id)

    Dim img As New Bitmap(145, 145) 'size fo the caption area
    Dim gr As Graphics = Graphics.FromImage(img)

    'sets the offsets and use image size to set region
    gr.CopyFromScreen(New Point(winSize(0) + 44, winSize(1) + 179), Point.Empty, img.Size)
    img.Save("test.jpg", Drawing.Imaging.ImageFormat.Jpeg)
    Process.Start("test.jpg")
End If

As long as i have the window in view it takes the screen shot just fine without any problems. However when i move the form off screen (where i am unable to see it) it only captures a black image.

I've been trying this code out:

Private Declare Function PrintWindow Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal hdcBlt As IntPtr, ByVal nFlags As UInt32) As Boolean
Dim screenCapture As Bitmap
Dim otherForm As New Form

Private Sub CaptureScreen()
    Dim target_hwnd As Long = FindWindow(vbNullString, "Calculator")
    SetWindowPos(target_hwnd, 0, winSize(0), winSize(1), winSize(2), winSize(3), 0)

    screenCapture = New Bitmap(245, 245)
    Dim g As Graphics = Graphics.FromImage(screenCapture)
    Dim hdc As IntPtr = g.GetHdc
    Form1.PrintWindow(target_hwnd, hdc, Nothing)
    g.ReleaseHdc(hdc)
    g.Flush()
    g.Dispose()

    If IO.File.Exists("d:\test.jpg") Then
        IO.File.Delete("d:\test.jpg")
    End If

    screenCapture.Save("d:\test.jpg", Drawing.Imaging.ImageFormat.Jpeg)
End Sub

Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
    CaptureScreen()
End Sub

Now the above code DOES capture an image even when the window is off screen. The problem with the code above is that i can't tell it to only capture an area within that window that i was able to do with the CopyFromScreen i first posted.

Is this possible using the PrintWindow?

Was it helpful?

Solution

I was able to do this:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim fileName = "Calculator.jpg"
    Dim fileNameCrop = "Calculator-crop.jpg"
    '     |--b|---|x|
    '     |   |     |            a|-Form Left to image area
    '     |   V     |             |  b|-Form Top to image area
    '     a-->[c]   |             |   |   c|-Image area Width to capture
    '     |         |             |   |    |  c|-Image area Height to capture
    '     |_________|             V   V    V   V     
    Dim CropRect As New Rectangle(97, 189, 36, 29)
    Dim OrignalImage = Image.FromFile(fileName)
    Dim CropImage = New Bitmap(CropRect.Width, CropRect.Height)

    Using grp = Graphics.FromImage(CropImage)
        grp.InterpolationMode = Drawing2D.InterpolationMode.NearestNeighbor
        grp.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
        grp.DrawImage(OrignalImage, New Rectangle(0, 0, CropRect.Width, CropRect.Height), CropRect, GraphicsUnit.Pixel)
        CropImage.Save(fileNameCrop)
    End Using

    OrignalImage.Dispose()
    CropImage.Dispose()
    'delete org image
    If FileIO.FileSystem.FileExists(fileName) Then FileIO.FileSystem.DeleteFile(fileName)
End Sub

And just crop out the area after i saved the forms image from the first code posted in the OP.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top