2009-05-19 6 views
15

Desidero fornire all'utente una schermata ridotta del desktop nella mia applicazione.C'è un modo per fare uno screenshot del desktop di Windows dell'utente?

C'è un modo per fare uno screenshot del desktop di Windows dell'utente corrente?

Sto scrivendo in C#, ma se c'è una soluzione migliore in un'altra lingua, sono aperto a questo.

Per chiarire, ho bisogno di uno screenshot del desktop di Windows - che è solo lo sfondo e le icone; nessuna applicazione o nulla che abbia attenzione.

risposta

16

Stai cercando Graphics.CopyFromScreen. Crea una nuova bitmap della giusta dimensione e passa le coordinate dello schermo dell'oggetto grafico della bitmap della regione da copiare.

C'è anche an article che descrive come eseguire scatti a livello di codice.

Risposta a modifica: ho frainteso cosa intendevi per "desktop". Se si vuole scattare una foto del desktop, dovrete:

  1. Minimize all windows using the Win32API (inviare un messaggio MIN_ALL) prima
  2. scattare l'istantanea
  3. quindi annullare le minimizzare tutto (inviare un messaggio MIN_ALL_UNDO).

Un modo migliore per fare questo sarebbe non disturbare le altre finestre, ma per copiare l'immagine direttamente dalla finestra del desktop. GetDesktopWindow in User32 restituirà un handle al desktop. Una volta che hai l'handle della finestra, ottieni il suo contesto di dispositivo e copia l'immagine in una nuova Bitmap.

C'è an excellent example on CodeProject di come copiare l'immagine da esso. Cerca il codice di esempio su come ottenere e creare il contesto del dispositivo nella sezione "Catturare il contenuto della finestra".

+1

Posso farlo se la mia domanda è a fuoco? Non catturerà la mia finestra dell'applicazione (e altri) se sono di fronte al desktop? – Damovisa

+1

Ho provato 'GetDesktopWindow' ma cattura le finestre che si trovano di fronte al desktop –

+0

qualsiasi soluzione finale con l'esempio di codice sorgente completo a lavorare su di esso? – Kiquenet

10

Ho l'impressione che stiate scattando per scattare una foto del desktop reale (con sfondo e icone) e nient'altro.

1) chiamata ToggleDesktop() in Shell32 utilizzando COM
2) Utilizzare Graphics.CopyFromScreen per copiare l'area del desktop corrente
3) Chiamare ToggleDesktop() per ripristinare lo stato precedente del desktop

Edit: Sì, chiamando MinimizeAll() è belligerante.

Ecco una versione aggiornata che ho sbattuto insieme:

/// <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; 

    } 

Regolare a piacere per molteplici scenari di monitoraggio (anche se suona come questo dovrebbe funzionare bene per la vostra applicazione).

+0

ottima risposta! Spiega ciò che è necessario senza essere tagliati e incollati. Vorrei più risposte SO fossero così. –

+0

Grazie, è esattamente quello che cercavo. Presumo che ci sia un metodo simile in Shell32 che posso chiamare per ripristinare la mia applicazione per mettere a fuoco in seguito. – Damovisa

+0

@Damovisa: non è solo la tua applicazione che deve essere ripristinata. Ridurre a caso tutte le applicazioni per un utente non è una buona pratica ... –

2

È possibile utilizzare GetDesktopWindow tramite p/invoke, quindi ottenere il contesto del dispositivo e acquisire lo snapshot. C'è un tutorial molto dettagliato here. Potrebbe essere meglio di perturbare le finestre esistenti.

+0

+1 Questo è un eccellente tutorial. –

0

Tutti ex risposte sono completamente sbagliate (applicazioni minimizzando è assurdo)
Basta usare SHW api: una riga del codice (bitmap del desktop viene memorizzata nella cache, l'API semplicemente Blits al tuo HDC ...)

+2

Hai un link o maggiori informazioni su "SHW api"? Non sono sicuro di cosa intendi... – Damovisa

0

È sempre possibile catturare screenshot all'avvio di Windows prima che le applicazioni eseguano o utilizzare altro desktop utilizzando la commutazione desktop. Date un'occhiata qui: http://www.codeproject.com/Articles/7666/Desktop-Switching passare ad altri desktop, prende l'immagine e ricordate che non avete bisogno di mostrarlo solo crearlo "desktop"