Captura de pantalla
[Usando el método SendKeystrokes y la clase ClipBoard que deriva de la clase Object
]

Fecha: 13/Ago/2003 (13/Ago/2003)
Autor: Miliuco (
Emilio Pérez Egido) - emi@miliuco.com

 
 

En este artículo se propone una manera relativamente sencilla para capturar tanto la pantalla completa como la ventana activa, copiarlas al portapapeles para su uso en otro programa, y almacenarlas en disco como BMP, mediante el uso de:

- el método SendKeystrokes, al que se le pasa un parámetro String que contiene el código de la tecla pulsada, en nuestro caso nos interesa que la tecla pulsada sea ImprPant o la combinación Alt + ImprPant, y se envía a la ventana activa la pulsación de la tecla referida en esa cadena.
  Hay que hacer notar que "%{PRTSC}" es el código de la combinación Alt + ImprPant pulsada una sola vez, lo que equivale a capturar la ventana, y "{PRTSC 2}" es el código de la tecla ImprPant pulsada 2 veces, lo que equivale a capturar la pantalla completa.
 Durante la captura de la pantalla completa se minimiza la ventana de la aplicación, para que no aparezca en la captura.
 Después de la captura de la ventana activa, la ventana de la aplicación coge automáticamente el foco para que sea más cómodo trabajar con ella.

- la clase ClipBoard, derivada de la clase Object, que tiene 3 miembros (constructor, GetDataObject y SetDataObject). Esta clase nos permite copiar al o pegar desde el portapapeles.

A continuación sigue código en Visual Basic:


  ' Botón que activa el temporizador (intervalo: 2,5 segundos)
    Private Sub btGrab_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btGrab.Click
        Me.WindowState = FormWindowState.Minimized ' formulario minimizado
        Timer2.Enabled = True
        Timer2.Start()
    End Sub

    ' Botón que activa el temporizador (intervalo: 2,5 segundos)
    Private Sub btGrab2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btGrab2.Click
        Timer1.Enabled = True
        Timer1.Start()
    End Sub

    ' Temporizador que llama a la función GetWindowCapture:
    ' - guarda la ventana en C:\ como EmiWin.bmp
    ' - coloca la ventana en el PictureBox1 del formulario
    Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        GetWindowCapture().Save("c:\EmiWin.bmp") ' guardar la captura como BMP
        imgPantalla.Image = GetWindowCapture() ' poner la imagen en el control imgPantalla
        ' Me.TopMost = True ' formulario al primer plano obligatoriamente
        Me.Activate() ' formulario al primer plano con el foco
        ' Me.TopMost = False ' formulario puede no estar en primer plano
        Timer1.Stop() ' detener el temporizador
        Timer1.Enabled = False
    End Sub

    ' Temporizador que llama a la función GetScreenCapture:
    ' - guarda la pantalla en C:\ como EmiScreen.bmp
    ' - coloca la pantalla en el PictureBox1 del formulario
    Private Sub Timer2_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer2.Tick
        GetScreenCapture().Save("c:\EmiScreen.bmp") ' guardar la captura como BMP
        imgPantalla.Image = GetScreenCapture()
        Timer2.Stop() ' detener el temporizador
        Timer2.Enabled = False
        Me.WindowState = FormWindowState.Normal ' formulario normal
    End Sub

    ' Función que captura la pantalla mediante el envío de la pulsación de la
    ' tecla "Impr Pant". La función devuelve un objeto Image y coloca la captura en el portapapeles
    Public Function GetScreenCapture() As Image
        Dim objTecla As SendKeys ' variable que guarda la pulsación de la tecla
        ' envía la pulsación de la tecla especificada (Impr Pant)
        objTecla.SendWait("{PRTSC 2}") ' 2 pulsaciones de Impr Pant para capturar la pantalla entera
        ' variable de tipo IDataObject que contiene el portapapeles
        Dim objClipboard As IDataObject = Clipboard.GetDataObject() ' método de IDataObject
        ' devolver el portapapeles como mapa de bits
        Return objClipboard.GetData(DataFormats.Bitmap)
    End Function

    ' Función que captura la ventana mediante el envío de la pulsación de la
    ' tecla "Impr Pant". La función devuelve un objeto Image y coloca la captura en el portapapeles
    Public Function GetWindowCapture() As Image
        Dim objTecla As SendKeys ' variable que guarda la pulsación de la tecla
        ' envía la pulsación de la tecla especificada (Impr Pant)
        objTecla.SendWait("%{PRTSC}") ' 1 pulsación de Alt + Impr Pant para capturar la ventana activa
        Dim objClipboard As IDataObject = Clipboard.GetDataObject() ' portapapeles
        ' devolver el portapapeles como mapa de bits
        Return objClipboard.GetData(DataFormats.Bitmap)
    End Function

    Private Sub btSalir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btSalir.Click
        'End ' salir
	Close()
    End Sub

    ' Información sobre el programa
    Private Sub btHelp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btHelp.Click
        MessageBox.Show("Este programa realiza capturas de la pantalla o de la ventana activa" & vbCrLf & _
        "usando el método SendKeystrokes, al que se le pasa un parámetro String" & vbCrLf & _
        "y envía a la ventana activa  la pulsación de la tecla referida en esa cadena." & vbCrLf & _
        "La pantalla se captura cuando han transcurrido 1,5 segundos." & vbCrLf & _
        "La ventana se captura cuando han transcurrido 2,5 segundos." & vbCrLf & _
        "Las capturas se copian al portapapeles y también se guardan en el disco duro como mapa de bits", _
        "Información de Miliuco", MessageBoxButtons.OK)
    End Sub

    ' Abrir el formulario con el código
    Private Sub lbCode_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles lbCode.Click
        Dim formCode As New Form2
        formCode.ShowDialog()
    End Sub

Como podéis ver, no es un código largo ni complicado, y se obtiene un programa funcional y útil, de hecho es con el que yo hago las capturas desde hace 3 meses.

Para completarlo haría falta incluir la función de capturar solamente un área de la pantalla o de la ventana, pero para ello habría que recurrir al GDI+ y yo por ahora no me veo capaz de ello.

Imagen del programa en funcionamiento:

 

Fichero con el código de ejemplo usando Visual Studio .NET 2003 (miliuco_captura.zip - Tamaño 173 KB)


ir al índice