PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C# TuT] Screenshots vom im Vodergrund befindlicher Anwendungen erstellen



C_OnnecTion
18.10.2011, 18:17
Tutorial Capture Screen


In diesen Tutorial möchte ich euch zeigen, wie man von bestimmten Anwendungen (bestimmte Fenster die sich im Vordergrund befinden) einen Screenshot erstellen kann. D.h. immer wenn sich ein bestimmtes Programm im Vordergrund befindet, wird ein Screenshot erstellt. In diesem Fall handelt es sich um ICQ, Outlook und Windows-Live-Mail.



Als erstes mal der komplette Sourcecode:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;

namespace Screenshot_ForegroundWindow
{
class ScreenshotForegroundWindow
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetForegroundWindow();

public void MakeScreenshotForegroundWindow()
{
try
{
IntPtr foregroundwindow = GetForegroundWindow();
int length =1000;
StringBuilder mybuilder = new StringBuilder(length);
GetClassName(foregroundwindow, mybuilder, mybuilder.Capacity);
string classname = mybuilder.ToString();
switch (classname)
{ //Klassenname für alle relevanten ICQ-Fenster
case "__oxFrame.class__":
Screenshot();
break;
//Klassenname für Outlook 2007-Fenster
case "rctrl_renwnd32":
Screenshot();
break;
case "":
Screenshot();
break;
//Klassenname für alle relevangen Windows-Live-Mail-Fenster
case "Outlook Express Browser Class":
Screenshot();
break;
}
}
catch (Exception)
{


}

}
//Methode für den Screenshot
private void Screenshot()
{
try
{
//Zufallszahl für einen eindeutigen Bildnamen
Random rand = new Random();
int zufall = rand.Next(0, 1000000);
//Höhe
int width = 1280;
//Breite
int height = 1024;
//Objekt aus der Klasse Bitmap
Bitmap bitmap = new Bitmap(width, height);
//Objekt aus der Klasse Graphics
Graphics grahpic = Graphics.FromImage(bitmap);
grahpic.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
//Apspeichern des Bitmaps
bitmap.Save("c:\\Test\\bitmap" + zufall + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
//Freigeben der Resourcen
grahpic.Dispose();
}
catch (Exception)
{


}
}


Erklärung der Klasse


Als erstes komme ich mal auf die Dll‘ s zu sprechen, die benötigt werden.
Mit folgender Dll ist es möglich den Klassennamen eines Fensters auszulesen.


[DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

Diese Dll ist dafür zuständig, ein Handle auf das sich im Vordergrund befindliche Fenster zu bekommen. Anhand dieses Handles wird dann später der Klassename abgerufen.


[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern IntPtr GetForegroundWindow();
So nun werde ich mal die relevanten Zeilen erklären.

Als erstes wird das Handle von dem Fenster ermittelt , welches sich im Vordergrund befindet. Dieses Handle wird benötigt, um den Klassenamen des sich im Vordergrund befindlichen Fensters zu ermitteln. Das wird hiermit erreicht :


IntPtr foregroundwindow = GetForegroundWindow();Nun deklarieren wir uns eine Variable, die die Kapazität des StringBuilders Objekts festlegt. Dieses Objekt wird benötigt, um den Namen der Klasse des entsprechenden Fensters aufzunehmen.


int length =1000;Nun wird das StringBuilder-Objekt mit der entsprechenden Kapazität erstellt.


StringBuilder mybuilder = new StringBuilder(length);Jetzt wird der Klassename des sich im Vordergrund befindlichen Fenster in das StringBuilder-Objekt „gepackt“. Dieses geschieht anhand der Funktion GetClassName(……..);


GetClassName(foregroundwindow, mybuilder, mybuilder.Capacity);Der nächste Schritt ist nun den Inhalt des StringBuilders-Objektes einen string zuzuweisen.


string classname = mybuilder.ToString();Darauf folgend wird anhand einer Switch/Case auf den Inhalt des strings reagiert.


switch (classname)
{ //Klassenname für alle relevanten ICQ-Fenster
case "__oxFrame.class__":
Screenshot();
break;
//Klassenname für Outlook 2007-Fenster
case "rctrl_renwnd32":
Screenshot();
break;
case "":
Screenshot();
break;
//Klassenname für alle relevanten Windows-Live-Mail-Fenster
case "Outlook Express Browser Class":
Screenshot();
break;
}
}




Die Methode Screenshot sollte verständlich auskommentiert sein. Wenn man diese Geschichte dann in einen Timer auslagert, sollte das Ergebnis logisch sein.



MFG Conn……

Sawyer
18.10.2011, 18:53
Schön das du hier dein Tutorial zur Verfügung stellt. Allerdings muss ich sagen das der Code selbst so simpel gehalten ist, dass ihn eigentlich jeder mit Grundkenntnissen nachvollziehen können müsste. Deshalb halte ich die separate Erklärung der Codezeilen eher für unnötig. Trotzdem wird es für einige interessant sein ;)

MfG, Sawyer

C_OnnecTion
18.10.2011, 18:58
@ Sawyer. Mit den Codzeilen hast Du natürlich recht. Der Code ist schon recht simpel und einfach zu verstehen. So bevor es Off Topic wird schreibe ich mal.......


MFG Conn...