2009-05-19 18 views
15

Quiero proporcionar al usuario una captura de pantalla reducida de su escritorio en mi aplicación.¿Hay alguna manera de tomar una captura de pantalla del escritorio de Windows del usuario?

¿Hay alguna manera de tomar una captura de pantalla del escritorio de Windows del usuario actual?

Escribo en C#, pero si hay una solución mejor en otro idioma, estoy abierto a ello.

Para aclarar, necesito una captura de pantalla del escritorio de Windows: solo el fondo de pantalla y los iconos; no hay aplicaciones ni nada que tenga foco.

Respuesta

16

Está buscando Graphics.CopyFromScreen. Cree un nuevo mapa de bits del tamaño correcto y pase las coordenadas de la pantalla del objeto de gráficos de mapa de bits de la región para copiar.

También hay an article que describen cómo tomar instantáneas mediante programación.

Respuesta a la modificación: He entendido mal lo que quiere decir con "escritorio". Si usted quiere tomar una imagen del escritorio, tendrá que:

  1. Minimize all windows using the Win32API (enviar un mensaje MIN_ALL) primero
  2. tomar la instantánea
  3. Luego deshacer el Minimizar todo (enviar un mensaje MIN_ALL_UNDO)

Una mejor manera de hacer esto sería no molestar a los demás ventanas, pero para copiar la imagen directamente desde la ventana del escritorio. GetDesktopWindow in User32 devolverá un identificador al escritorio. Una vez que tenga el identificador de ventana, obtenga su contexto de dispositivo y copie la imagen en un nuevo mapa de bits.

Hay an excellent example on CodeProject de cómo copiar la imagen de la misma. Busque el código de ejemplo sobre cómo obtener y crear el contexto del dispositivo en la sección "Capturar el contenido de la ventana".

+1

¿Puedo hacer que si mi solicitud está en el foco? ¿No capturará la ventana de mi aplicación (y otras) si están frente al escritorio? – Damovisa

+1

Intenté 'GetDesktopWindow' pero captura las ventanas que están en frente del escritorio –

+0

¿Alguna solución final con el código fuente completo de muestra trabajando al respecto? – Kiquenet

10

Me da la impresión de que está fotografiando para tomar una foto del escritorio real (con fondo de pantalla e íconos), y nada más.

1) Llamar ToggleDesktop() en Shell32 mediante COM
2) Uso Graphics.CopyFromScreen para copiar el área de escritorio actual
3) Llame a ToggleDesktop() para restaurar el estado anterior de escritorio

Editar: Sí, llamando MinimizeAll() es beligerante.

Aquí es una versión actualizada que Azoté juntos:

/// <summary> 
    /// Minimizes all running applications and captures desktop as image 
    /// Note: Requires reference to "Microsoft Shell Controls and Automation" 
    /// </summary> 
    /// <returns>Image of desktop</returns> 
    private Image CaptureDesktopImage() { 

     //May want to play around with the delay. 
     TimeSpan ToggleDesktopDelay = new TimeSpan(0, 0, 0, 0, 150); 

     Shell32.ShellClass ShellReference = null; 

     Bitmap WorkingImage = null; 
     Graphics WorkingGraphics = null; 
     Rectangle TargetArea = Screen.PrimaryScreen.WorkingArea; 
     Image ReturnImage = null; 

     try 
     { 

      ShellReference = new Shell32.ShellClass(); 
      ShellReference.ToggleDesktop(); 

      System.Threading.Thread.Sleep(ToggleDesktopDelay); 

      WorkingImage = new Bitmap(TargetArea.Width, 
       TargetArea.Height); 

      WorkingGraphics = Graphics.FromImage(WorkingImage); 
      WorkingGraphics.CopyFromScreen(TargetArea.X, TargetArea.X, 0, 0, TargetArea.Size); 

      System.Threading.Thread.Sleep(ToggleDesktopDelay); 
      ShellReference.ToggleDesktop(); 

      ReturnImage = (Image)WorkingImage.Clone(); 

     } 
     catch 
     { 
      System.Diagnostics.Debugger.Break(); 
      //... 
     } 
     finally 
     { 
      WorkingGraphics.Dispose(); 
      WorkingImage.Dispose(); 
     } 

     return ReturnImage; 

    } 

Ajuste al gusto para múltiples escenarios de monitor (aunque suene como esto debería funcionar bien para su aplicación).

+0

¡excelente respuesta! Explica lo que se necesita sin cortar -n- pegar. Desearía más respuestas de SO así. –

+0

Gracias, eso es exactamente lo que buscaba. Supongo que hay un método similar en Shell32 al que puedo llamar para restablecer mi aplicación y centrarme luego. – Damovisa

+0

@Damovisa: no es solo su aplicación la que necesita ser restaurada. Minimizar aleatoriamente todas las aplicaciones para un usuario no es una buena práctica ... –

2

Puede consultar el uso de GetDesktopWindow a través de p/invoke, luego obtener el contexto del dispositivo y tomar su instantánea. Hay un tutorial muy detallado here. Podría ser mejor que perturbar las ventanas existentes.

+0

+1 Ese es un excelente tutorial. –

0

Todas las anteriores respuestas son completamente equivocado (aplicaciones minimizando es absurdo)
Utilice simplemente SHW api: una línea de código (el mapa de bits de escritorio se almacena en caché, la API simplemente Blits a su HDC ...)

+2

¿Tiene un enlace o más información sobre "SHW api"? No estoy seguro de lo que quieres decir... – Damovisa

0

Siempre puede capturar la captura de pantalla en el inicio de Windows antes de que las aplicaciones se ejecuten en o usar otro escritorio usando el cambio de escritorio. Echar un vistazo aquí: http://www.codeproject.com/Articles/7666/Desktop-Switching Cambiar a otro escritorio, tomar la foto y recuerda que no tienes que mostrar sólo la crea "escritorio"

Cuestiones relacionadas