Screenshots mit Visual Basic einfach erstellen

Veröffentlicht: 04. Apr 2005

Von Mathias Schiffer

Die Microsoft Newsgroups sind eine Quelle schier unerschöpflichen Wissens, das nahezu auf Knopfdruck abrufbar ist: Hunderte deutschsprachige Entwickler vom Einsteiger bis zum Profi treffen sich hier täglich virtuell, um Fragen zu stellen oder zu beantworten. Auch themennahe Probleme, Ansichten und Konzepte werden miteinander diskutiert. Sie kennen die Microsoft Newsgroups noch nicht? Detaillierte Information für Ihre Teilnahme finden Sie auf der Homepage der Microsoft Support Newsgroups.

Diese Kolumne greift regelmäßig ein besonders interessantes oder häufig nachgefragtes Thema aus einer der Entwickler-Newsgroups auf und arbeitet es aus.

Aus der Visual Basic Newsgroup microsoft.public.de.vb:

Ich möchte mit Visual Basic 6 ohne großen Aufwand einen Screenshot des aktiven Anwendungsfensters erstellen und in die Zwischenablage übertragen. Wie geht’s am einfachsten?

Screenshots, neudeutsch für Bildschirmfotos, lassen sich auf unterschiedlichste Weise anfertigen. Vorrangig geht es dabei darum, eine angezeigte Grafik (nichts anderes ist ein Fenster auf dem Bildschirm) in einen anderen Grafikspeicher zu kopieren.

Visual Basic selbst bietet von Haus aus keinerlei Möglichkeiten an, um Screenshots zu erstellen. Anders sieht es schon beim Windows API aus: Ihr Teilbereich GDI („Graphics Device Interface“) zeichnet verantwortlich für alles, was unter Windows mit oberflächenbezogener Grafik zu tun hat. So finden sich dort auch API-Funktionen wie BitBlt (1:1-Kopie eines vorab definierten Rechtecks) und StretchBlt (1:x-Kopie eines vorab definierten Rechtecks) und diverse verwandte Funktionen. Diese eigenen sich hervorragend, um angezeigte Grafiken in reservierte Speicherbereiche zu kopieren und diesen auch noch in die Windows-Zwischenablage zu transferieren. Die Verwendung der Funktionen ist zwar nicht vollkommen trivial, aber doch beherrschbar. Sie erfüllen jedoch eindeutig nicht die Anforderung, den einfachsten Weg zur Verfügung zu stellen.

Wie so oft im Leben zeigt sich ein deutlich einfacherer Weg in der Nutzung bereits bestehender Funktionalität. Schließlich bietet Windows dem Endanwender die angefragte Funktionalität bereits selber an: Betätigt der Anwender die „Druck“-Taste (meist beschriftet mit „PrtScrn“ für „Print Screen“) auf seiner Tastatur, so wird ein grafisches Abbild der aktuellen Bildschirmanzeige in der Windows Zwischenablage abgelegt. Wird vor der Betätigung die Alt-Taste niedergehalten, so bezieht sich das angefertigte Bildschirmfoto lediglich auf das aktive Anwendungsfenster.

Statt also reihenweise komplexe API-Funktionen für Grafik- und Zwischenablageoperationen aufzurufen, lässt sich der zu erzielende Effekt viel einfacher über die programmatische Simulation von Tastaturbetätigungen erreichen!

Zu diesem Zweck wiederum bietet das Win32-API die sehr einfache Methode keybd_event an. Hier die notwendige API-Prototypendeklaration (inklusive der von uns ebenfalls benötigten Konstantendefinitionen):

' API-Deklarationen:
Private Declare Sub keybd_event _
  Lib "user32" ( _
  ByVal byteVirtualKeycode As Byte, _
  ByVal byteScan As Byte, _
  ByVal lFlags As Long, _
  ByVal lExtraInfo As Long)
  
Private Const KEYEVENTF_KEYUP As Long = &H2  ' Taste lösen
Private Const VK_MENU         As Byte = &H12 ' Alt-Taste
Private Const VK_SNAPSHOT     As Byte = &H2C ' Druck/PrtScrn-Taste

Die Konstante VK_MENU bezeichnet die Alt-Taste, deren zusätzliche Funktionalität für die Eingrenzung auf das aktive Anwendungsfenster bereits besprochen wurde. VK_SNAPSHOT repräsentiert als Konstantenwert die ebenfalls besprochene „Druck“-Taste. Zusätzlich interessant ist noch die Konstante KEYEVENTF_KEYUP: Sie steht in einem Folgeaufruf der Methode dafür, dass eine betätigte Taste auch wieder gelöst wird (andernfalls würde sie als dauerhaft betätigt betrachtet werden).

Der folgende Beispielcode stellt die sofort einsetzbare Methode ScreenCopy zur Verfügung. Ein einfacher Aufruf reicht, um das Abbild des Desktops oder des aktiven Anwendungsfensters in die Zwischenablage zu transferieren.

Public Sub ScreenCopy(Optional ByVal ActiveWindow As Boolean = False)
' Überträgt eine Bildschirmkopie des Desktops (ActiveWindow = False)
' oder des aktiven Fensters (ActiveWindow = True) in die Zwischenablage.
  
  If ActiveWindow Then
  
    ' Nur das aktive Fenster abfotografieren
    ' => Alt-Taste einbeziehen
    keybd_event VK_MENU, 0, 0, 0                    ' Alt 'runter
    keybd_event VK_SNAPSHOT, 0, 0, 0                ' Druck ' runter
    keybd_event VK_SNAPSHOT, 0, KEYEVENTF_KEYUP, 0  ' Druck hoch
    keybd_event VK_MENU, 0, KEYEVENTF_KEYUP, 0      ' Alt hoch
  
  Else
  
    ' Den gesamten Desktop abfotografieren
    keybd_event VK_SNAPSHOT, 0, 0, 0                ' Druck ' runter
    keybd_event VK_SNAPSHOT, 0, KEYEVENTF_KEYUP, 0  ' Druck hoch
  
  End If
  
End Sub

Mathias Schiffer widmet sich als freier Softwareentwickler und Technologievermittler größeren Projekten ebenso wie arbeitserleichternden Alltagslösungen. Seit Jahren gibt er sein Wissen in unzähligen Publikationen auch an andere Entwickler und Entscheider weiter. Sie erreichen ihn per E-Mail an die Adresse Schiffer@mvps.org.