el Guille, la Web del Visual Basic, C#, .NET y más...

Capturar la pantalla o ventana activa

Con previsualizador de las imágenes que permite guardarlas

 
Publicado el 29/Dic/2007
Actualizado el 31/Dic/2007
Autor: Guillermo 'guille' Som

Revisión (1.0.2.8) del 31/Dic/2007


Esta utilidad te permite capturar la pantalla completa o solo la ventana activa. Además permite ver las capturas realizadas y guardarla en uno de los formatos soportados por el tipo Image de .NET.



 

La batallita del agüelo

Pues eso... que por "necesidad" me he tenido que fabricar una utilidad que capture la pantalla completa o la ventana que tenga el foco.

Y esa necesidad viene de la mano del sistema operativo que estoy usando ahora, que es el Windows Server 2008 RC1 de 64 bits, y en el Windows Server 2008 no existe la utilidad Snipping Tool que es la que podemos usar en Windows Vista para realizar capturas de la pantalla. (Recuerda que Windows Server 2008 es como el hermano "serio" de Windows Vista.)

Por supuesto, ni esa utilidad está en mi sistema, ni tampoco ningún otro programa que me permita hacer capturas, ya que en el otro equipo que tengo con el Windows Vista Ultimate, la herramienta que uso para hacer las capturas es el Corel Paint Shop Pro Photo X2 (o el PSP 12), que también uso para editar las fotos.

Así que... me dije... pues hagamos una utilidad para capturar la pantalla... y en vez de ponerme a hacer pruebas, busqué en mi sitio, cosa que tenías que hacer cada vez que necesites algún código, ya que, casi seguro, que lo que busques está en el sitio del Guille, ya sea porque lo he publicado yo o porque algún colaborador lo haya hecho, y esa búsqueda me mostró un artículo del colega Miliuco: Captura de pantalla.

Así que, me fijé en cómo capturaba él las pantallas y use ese código.

Por supuesto lo he adaptado a "mis gustos", pero la "base" de todo es la llamada al método SendWait de la clase SendKeys, y particularmente el parámetro que indica que queremos capturar la pantalla, que no es otro que el envío de la tecla Print Screen o Impr Pant, que se indica con la cadena {PRTSC}.

Inicialmente lo hice para que capturara la imagen y la guardara en el portapapeles, con idea de posteriormente usar un programa (el Paint, por ejemplo) y pegar esa imagen para después guardarla.

Pero hace un rato me dije (sí, es que hablo yo conmigo mismo y me digo cosas, je, je), pues... ¿por qué no guardar directamente lo capturado? o mejor aún,  ¿por qué no poder ver lo capturado y después decidir si lo quiero guardar o no?

Y eso es lo que he hecho, crear un formulario de "previsualización", muy simple, pero totalmente funcional. Ahora te muestro cómo es ese formulario.

 

La utilidad para capturar la pantalla o ventana activa

No me voy a enrollar demasiado, así que iré al grano.

La pantalla principal es muy simple (ver la figura 1), ya que solo tiene tres botones y un NumericUpDown.
El control NumericUpDown sirve para indicar el retardo que queremos dar para realizar la captura (ya que si la captura la hiciéramos directamente, pues la ventana activa siempre sería nuestra aplicación). Las capturas se guardan en el portapapeles, con idea de poder pegarlo en cualquier aplicación que "entienda" de gráficos.
Dos de los botones sirven para indicar qué es lo que queremos capturar, y el tercero servirá para mostrar lo que hay capturado. Este botón se habilitará solo si se ha podido capturar, es decir, si hay alguna imagen en el portapapeles, esa comprobación también se hace al iniciarse la aplicación, por tanto, si en el portapapeles hay una imagen, la podremos ver con esta utilidad.

Figura 1. La ventana principal (en ejecución)
Figura 1. La ventana principal (en ejecución)

Debido a que la utilidad esta la podemos usar en un Windows Vista, el icono ese que hay en la parte inferior derecha nos avisa si estamos ejecutando la aplicación como administrador (icono verde, tal como se muestra en la figura 1) o un icono naranja (de advertencia). Esto lo he hecho porque en ocasiones, si quieres capturar una ventana que está ejecutándose como administrador solamente podrás hacerlo si el programa se ejecuta también como administrador. En el caso de la captura de la pantalla completa, si hay una aplicación que se está ejecutando como administrador tampoco se capturará... salvo que la utilidad también se ejecute como administrador. Por supuesto esto es solo aplicable en Windows Vista.
Si la utilidad se ejecuta como administrador, siempre podrá capturar todo lo que haya, se esté ejecutando como se esté ejecutando. El único caso curioso es al intentar capturar una imagen (máquina virtual) de Smartphone, que no la copiaba ni en modo ventana ni en modo pantalla completa... en fin...

Una vez que hemos hecho una captura, podemos mostrarla en una ventana aparte, por ejemplo en la figura 2 tenemos una captura de esa ventana mostrando algo capturado.

Figura 2. La ventana de mostrar las capturas
Figura 2. La ventana de mostrar las capturas

Esta ventana tiene tres botones, dos de ellos sirven para la forma de mostrar la imagen, el primero es para el tamaño normal, en ese caso se muestran las barras de desplazamiento con idea de que puedas ver el resto de la imagen. El otro botón es para hacer un Stretch, es decir, para mostrar la captura completa, pero encajándola en el picture (o la ventana).

El tercer botón nos permite guardar la imagen en uno de los formatos soportados por la clase Image, esos tipos de imágenes son los formatos que define la clase ImageFormat (definida en System.Drawing.Imaging).

 

El formulario que muestra las capturas se muestra por medio de Show (en vez de ShowDialog) y sin usar la instancia predeterminada que crea Visual Basic a la que podemos acceder por medio del nombre del formulario o usando My.Forms.
Esto es para que se puedan abrir varios formularios con varias capturas, de forma que no tengamos que guardarla antes de tomar la siguiente, sino que podemos capturar, mostrar la captura realizada y seguir capturando más cosas.

 

Algunas cosas interesantes del código de esta utilidad

Si miras la documentación de Visual Studio buscando una propiedad para mostrar las barras de desplazamiento (scroll) en un control PictureBox, no busques, porque no tiene esa propiedad (al menos en el .NET 2.0).

Para mostrar las barras de scroll en el caso de que la imagen sea más grande que la ventana, lo que he hecho es poner el control PictureBox (picClipB) dentro de un panel (panelPic). Ese panel tiene un valor True en la propiedad AutoScroll y la propiedad Dock con un valor Fill, con idea de que ocupe toda la pantalla... y eso es lo que hacía... ¡ocupar toda la ventana! Tanto ocupaba, que se ponía detrás del ToolStrip de la botonera, impidiendo ver la parte superior de la imagen.

¿Solución? Poner el ToolStrip dentro de otro panel, acoplado a la parte de arriba, y así se ajusta el panel de la imagen al resto de la ventana... cosas que pasan con esto del "docking", en fin...

En la figura 3 puedes ver la ventana del "Document Outline" en el que se aprecia que el ToolStrip está dentro de un panel, lo mismo que el PictureBox está dentro de otro.

Figura 3. Con el Document Outline podemos ver qué controles están dentro de otros
Figura 3. Con el Document Outline podemos ver qué controles están dentro de otros

 

El problema es que ese scroll no se mostraba... ¡jooorrrr! ¿y ahora qué? Pues... si el scroll aparece cuando lo que tiene dentro es más grande que lo que se muestra... la solución es hacer crecer la imagen, es decir, no dejarla con el tamaño que tuviera.

Para que la imagen crezca al tamaño que tiene la imagen lo podemos hacer de dos formas:

1- Dejando el valor de la propiedad SizeMode del PictureBox en Normal y asignando al PictureBox el tamaño de la imagen:

    picClipB.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Normal
    ' Cambiar el tamaño del pictureBox
    ' para que se muestre el scroll del contenedor si fuera necesario
    picClipB.Size = picClipB.Image.Size

2- Asignando el valor AutoSize a la propiedad SizeMode, ya que de esta forma el PictureBox se redimensiona automáticamente al tamaño de la imagen que está mostrando:

    picClipB.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize

En cualquiera de los dos casos, tenemos que indicarle al panel que sea del mismo tamaño que la imagen, con idea de que muestre las barras de desplazamiento:

    panelPic.Size = picClipB.Size

 

Para comprobar si hay imagen en el portapapeles y para copiar la imagen, he usado el objeto My.Computer.Clipboard.
Para saber si hay una imagen, lo compruebo por medio del método ContainsImage, y para recuperar la imagen del portapapeles, he usado el método GetImage.

Nota:
Decir que el objeto My.Computer.Keyboard define un método SendKeys similar al de la clase SendKeys, pero en este ejemplo he usado la clase del .NET Framework en vez del objeto definido en My.

 

Más abajo tienes el código de los dos formularios, así como el ZIP con el proyecto completo para Visual Basic 2008, pero aunque esté creado con el Visual Basic 2008, no utiliza nada de lo incluido en el .NET Framework 3.5, además de que le he indicado que use el .NET Framework 2.0, por tanto, podrás usar directamente el ejecutable si ya tienes el runtime del .NET Framework 2.0 instalado.

Nota si quieres usar el proyecto desde Visual Basic 2005:
El código en sí te servirá también para Visual Basic 2005, pero no el fichero del proyecto. Si quieres usarlo con Visual Basic 2005, tendrás que quitar algunas líneas del fichero de proyecto (.vbpoj) o bien crear un nuevo proyecto con Visual Basic 2005, añadir las imágenes como recursos y añadir los dos formularios al proyecto que acabas de crear (te dirá si quieres sobrescribir el Form1, le dices que sí).

 

Espero que te sea de utilidad.

Nos vemos.
Guillermo


 


Código de ejemplo (comprimido):

Fichero con el código para Visual Basic 2008: CapturarPantalla_vb2008.zip - 65.0 KB

Este ZIP contiene la última versión publicada: v1.0.2.8 del 31/Dic/07

(MD5 checksum: 7290BF6604E7EC5D3FB6B67DB2AE25EB)

Nota:
Este ZIP incluye también el ejecutable.
Y si quieres usarlo con Visual Basic 2005, lee lo que digo más arriba, en la nota final.

 


 


La fecha/hora en el servidor es: 23/11/2024 8:59:45

La fecha actual GMT (UTC) es: 

©Guillermo 'guille' Som, 1996-2024