Capturing forms using sendkeys

mcfly

Well-known member
Joined
Jun 15, 2009
Messages
54
Programming Experience
Beginner
Hi,

my program at the moment will capture forms using the sendkeys command, I use the code:

VB.NET:
SendKeys.Send("%" + "{PRTSC}")

Can anyone explain why I can capture the current form sometimes and then other times it wont capture a current form depending on the appllication that is running the form. Is there a way that applications can hide from having a screen capture as it only works with certain applications, for example the visual studio forms, explorer or firefox browser, any windows form etc it works fine. I am able to pick up the thread and title name of any form but can't capture every form, some are dismissed.

The rest of my code looks like this:

VB.NET:
Public Class Form1

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        'clear clipboard
        Windows.Forms.Clipboard.Clear()
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'clear clipboard before we begin
        Windows.Forms.Clipboard.Clear()

        KeyboardSimulator.SimulateKeyDown(Keys.LWin)
        KeyboardSimulator.SimulateKeyDown(Keys.D)
        KeyboardSimulator.SimulateKeyUp(Keys.LWin)
        KeyboardSimulator.SimulateKeyUp(Keys.D)

        'minimze starting window
        'Me.WindowState = FormWindowState.Minimized
        'turn on timer
        Timer1.Enabled = True
    End Sub

    Public Class KeyboardSimulator

        <Runtime.InteropServices.DllImport("user32")> _
        Private Shared Sub keybd_event(ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)
        End Sub

        Private Const KEYEVENTF_EXTENDEDKEY As Integer = &H1
        Private Const KEYEVENTF_KEYUP As Integer = &H2

        Public Shared Sub SimulateKeyDown(ByVal vKey As Keys)
            keybd_event(CByte(vKey), 0, KEYEVENTF_EXTENDEDKEY, 0)
        End Sub

        Public Shared Sub SimulateKeyUp(ByVal vKey As Keys)
            keybd_event(CByte(vKey), 0, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
        End Sub

    End Class

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        SendKeys.Send("%" + "{PRTSC}")

        PasteImage()
        'timer currently at 500 milliseconds
        'every half second
        'capture active form
        If PictureBox1.Image IsNot Nothing Then

            Dim TempBitmap As Bitmap
            TempBitmap = PictureBox1.Image

            Dim MyColor As Color
            MyColor = TempBitmap.GetPixel(10, 10)

            'Dim str As String
            'str = MyColor.ToString
            Dim str2 As String

            str2 = ColorTranslator.ToHtml(MyColor)

            Dim str As String
            str = MyColor.ToString

            txtColour.Text = str2

            If str2 IsNot "#3A6EA5" Then

                SendKeys.Send("%" + "{PRTSC}")

                'SendKeys.Send("{PRTSC}") dosen't work in vista
                'or with certain keyboards
                'pasting copied image to the picturebox
                PasteImage()

            End If

        End If


    End Sub

    Public Sub PasteImage()
        'check the data format in clipboard if its of type bitmap then proceed further 
        If Clipboard.GetDataObject.GetDataPresent(DataFormats.Bitmap) Then
            'setting clipboard data to picturebox
            Me.PictureBox1.Image = Clipboard.GetDataObject.GetData(DataFormats.Bitmap)
        End If
    End Sub


    Private Declare Function GetForegroundWindow Lib "user32.dll" () As IntPtr
    Private Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As IntPtr, ByRef lpdwProcessID As Integer) As Integer
    Private Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hWnd As IntPtr, ByVal WinTitle As String, ByVal MaxLength As Integer) As Integer
    Private Declare Function GetWindowTextLength Lib "user32.dll" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Integer

    Private Sub timerActiveWindowCheck_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        'Get the Handle to the Current Forground Window 
        Dim hWnd As IntPtr = GetForegroundWindow()

        If hWnd = IntPtr.Zero Then Exit Sub

        'Find the Length of the Window's Title
        Dim TitleLength As Integer

        TitleLength = GetWindowTextLength(hWnd)

        'Find the Window's Title
        Dim WindowTitle As String = StrDup(TitleLength + 1, "*")

        GetWindowText(hWnd, WindowTitle, TitleLength + 1)

        'Find the PID of the Application that Owns the Window 
        Dim pid As Integer = 0

        GetWindowThreadProcessId(hWnd, pid)

        If pid = 0 Then Exit Sub

        'Get the actual PROCESS from the process ID
        Dim proc As Process = Process.GetProcessById(pid)

        If proc Is Nothing Then Exit Sub

        txtProcessID.Text = pid.ToString
        txtProcessName.Text = proc.ProcessName
        txtProcessTitle.Text = proc.MainWindowTitle
        txtCurrentWindowTitle.Text = WindowTitle
        txtTitleLength.Text = TitleLength.ToString

    End Sub

End Class


Perhaps there is a way of capturing a form based upon a thread. Any one else experienced anything like this?
 
Is there another way to capture the current form?...rather than using sendkeys or print screen etc
 
Back
Top