Captura de pantalla o ventana activa en VB

Capturar la pantalla o la ventana activa usando la clase SendKeys sin recurrir a librerías externas en Visual Studio 2017 con VB

En este ejercicio se propone una manera relativamente sencilla para capturar tanto la pantalla completa como la ventana activa, copiarla al portapapeles y almacenarla en disco como JPG. Este ejercicio constituye un ejemplo más de que es posible realizar con Visual Basic .NET aplicaciones relativamente complejas y utilizables como ésta aunque el programador no tenga un nivel avanzado. El proceso para hacer la captura es el siguiente:

  • se minimiza la aplicación para que no salga en la captura con el ítem Minimized de la enumeración FormWindowState
  • el proceso queda suspendido durante 500 milisegundos con el método Sleep de la clase Thread
  • la pulsación de teclas es enviada con el método SendWait de la clase SendKeys para obtener la captura en ese intervalo
  • las teclas que se envían son las que se utilizan en Windows para hacer estas capturas
  • desde el portapapeles se obtiene un objeto Bitmap que permite guardar la imagen en disco y mostrarla en el PictureBox

Capturar la pantalla

'Botón que captura al portapapeles la pantalla, guarda la captura'
'junto al ejecutable como Pantalla.jpg y la muestra en el PictureBox'
Private Sub BtGrabScr_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtGrabScr.Click
	'minimizar el formulario para que no aparezca en la captura'
	Me.WindowState = FormWindowState.Minimized
	'tiempo de espera con el formulario minimizado'
	System.Threading.Thread.Sleep(500)
	'enviar la pulsación equivalente a May + ImprPant'
	SendKeys.SendWait("+{PRTSC}")
	'capturar, guardar y mostrar la captura en el PictureBox'
	Dim pantalla As Bitmap
	pantalla = CType(Clipboard.GetDataObject().GetData("Bitmap"), Bitmap)
	pantalla.Save("Pantalla.jpg", ImageFormat.Jpeg)
	ImgPantalla.Image = pantalla
	'restaurar el formulario a su tamaño normal desde minimizado'
	Me.WindowState = FormWindowState.Normal
End Sub

Capturar la ventana

'Botón que captura al portapapeles la ventana activa, guarda la captura junto al ejecutable como Ventana.jpg y la muestra en el PictureBox'
Private Sub BtGrabWin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtGrabWin.Click
	'minimizar el formulario para que no aparezca en la captura'
	Me.WindowState = FormWindowState.Minimized
	'tiempo de espera con el formulario minimizado'
	'el proceso de esperar y enviar Alt + ImprPant se lanza 2 veces '
        'si se lanza sólo una vez no captura bien en algunas ocasiones'
	'tiempo de espera con el formulario minimizado'
	System.Threading.Thread.Sleep(500)
	'enviar la pulsación equivalente a Alt + ImprPant'
	SendKeys.SendWait("%{PRTSC}")
	'tiempo de espera con el formulario minimizado'
	System.Threading.Thread.Sleep(500)
	'enviar la pulsación equivalente a Alt + ImprPant'
	SendKeys.SendWait("%{PRTSC}")
	'capturar, guardar y mostrar la captura en el PictureBox'
	Dim ventana As Bitmap
	ventana = CType(Clipboard.GetDataObject().GetData("Bitmap"), Bitmap)
	ventana.Save("Ventana.jpg", ImageFormat.Jpeg)
	ImgPantalla.Image = ventana
	'restaurar el formulario a su tamaño normal desde minimizado'
	Me.WindowState = FormWindowState.Normal
End Sub

Clase SendKeys

Proporciona métodos para enviar pulsaciones de tecla a la aplicación activa. Como parámetro se pasa una cadena que contiene la tecla pulsada. No se puede crear una instancia de esta clase. Para enviar una pulsación de tecla y continuar inmediatamente con el flujo del programa, utiliza Send. Para esperar a que terminen los procesos iniciados por la pulsación de tecla, utiliza SendWait.

Cada tecla está representada por uno o más caracteres. Para especificar un único carácter del teclado, utiliza dicho carácter. Por ejemplo, para representar la letra A, pasa la cadena «A» al método. Si se desea representar más de un carácter, agrega cada carácter adicional al que lo precede. Para representar las letras A, B y C, especifica el parámetro como «ABC».

El signo más (+), el signo de intercalación (^), el signo de porcentaje (%), la tilde (~) y los paréntesis () tienen significados especiales para SendKeys. Para especificar uno de estos caracteres, ponlo entre llaves ({}). Por ejemplo, para especificar el signo más, utiliza «{+}».

Para especificar caracteres que no se muestran al presionar una tecla, como ENTRAR o TAB, y teclas que representan acciones en lugar de caracteres, utiliza códigos como:

  • RETROCESO – usar {BACKSPACE}, {BS} o {BKSP}
  • ESC – usar {ESC}
  • IMPR PANT – usar {PRTSC}

Para especificar teclas con cualquier combinación de las teclas MAYÚS, CTRL y ALT, escribe delante del código de la tecla: % para ALT, ^ para CTRL y + para MAYÚS. Para especificar una repetición de teclas, utiliza el formato {tecla número}. Hay que separar la tecla y el número de repeticiones con un espacio.

Como ejemplo de todo ello, para enviar 1 pulsación de ALT + IMPR PANT (captura la ventana activa) usaremos %{PRTSC} y para enviar 1 pulsación de MAYÚS + IMPR PANT (captura la pantalla entera) usaremos +{PRTSC}.

NOTA: si se pulsa «Capturar la ventana» cuando no hay ventana alguna visible, lo que se captura es la barra de tareas.

Clase ClipBoard

La clase ClipBoard (derivada de la clase Object) tiene 3 miembros (constructor, GetDataObject y SetDataObject). Esta clase nos permite copiar al o pegar desde el portapapeles, como se ha visto en el código anterior:

ventana = CType(Clipboard.GetDataObject().GetData("Bitmap"), Bitmap)

Puedes descargar el proyecto de Visual Studio 2017 desde aquí.

Nota: el ajuste automático de escala del formulario que muestra la ventana de la aplicación se puede configurar de varias maneras, lo tienes en las propiedades del formulario como AutoScaleMode, la opción con la que obtengo el mejor resultado es con Dpi.