Die Community zu .NET und Classic VB.
Menü

Steuern von Drittprogrammen mit Hilfe der SendKeys-Methode

 von 

Übersicht 

Nicht alle Programme auf einem Windows-System können von Visual Basic for Application aus erreicht werden. Um Programme die ihre Ressourcen nicht z.B. als COM-Objekte anbieten trotzdem in einem VB/VBA-Projekt einzubinden muss deshalb ein anderer Weg beschritten werden. Ein Möglichkeit dazu bietet die "SendKeys-Methode".

Mit freundlichen Grüßen
Franz-Peter Zantis

Einleitung  

Die meisten Programme sind über Tastaturkürzel steuerbar. So gelangt man z.B. bei MS-Word mit der Taste [Alt] in die Menüleiste und kann dann alle angebotenen Funktionen nutzen indem man die unterstrichenen Buchstaben auf der Tastatur drückt. Die Kombination [Alt] und dann [D] öffnet z.B. das Menü "Datei". Auch einige Steuertasten wie die Pfeiltasten oder die Taste [RETURN] sind nutzbar. Diese Eigenschaft, ein Programm über die Tastatur zu steuern wird bei der "SendKeys-Methode" ausgenutzt. Die Tastenkombinationen werden dann nicht vom Anwender eingegeben, sondern von VB/VBA aus an das geöffnete Programm bzw. an die geöffnete Applikation gesendet. Bei der Angabe der Tastaturcodes ist die Groß-/Kleinschreibung relevant und muss beachtet werden. Vor der eigentlichen Programmierung sollten die einzelnen Schritte unbedingt manuell nachvollzogen bzw. ausprobiert und dokumentiert werden.

Bei dem Verfahren ist es allerdings sehr wichtig sicherzustellen, dass die zu steuernde Applikation geladen und aktiv ist. Sie muss "den Fokus" haben. "Fokus" bedeutet hier, die nächste Tastatureingabe gilt dem betreffenden Programm. Wird dieser Punkt nicht beachtet, landen die abgesandten Tastaturkürzel in dem Programm, dass zufällig den Fokus hat (das kann auch Windows selbst sein) und es werden unvorhersehbare Aktionen ausgelöst.
Die allgemeine Vorgehensweise ist also:

  • Sicherstellen dass das zu steuernde Programm den Fokus hat.
  • Tastaturkürzel senden.
  • Ergebnis(se) sichern.

Der Fokus des Programms  

Um sicherzustellen, dass das gewünschte Programm "den Fokus" hat, gibt es verschiedene Möglichkeiten. Besonders sicher und einfach anzuwenden ist die Benutzung von AppActivate. Die allgemeine Syntax lautet:

AppActivate (Titel, [Wait])

Listing 1

"Titel" ist vom Typ String und enthält den Namen oder die Application-ID der Anwendung. Dieser erscheint im Normalfall in der Titelleiste der Anwendung. Es reicht, wenn man ein Wort oder die ersten paar Buchstaben aus dem Titel angibt. Dies kann aber zu unerwünschten Ergebnissen führen, wenn die Angabe nicht eindeutig ist. Zum Beispiel beginnen die Programme Microsoft Excel und Microsoft Access beide mit "Microsoft" - sofern keine Dokumente geladen sind. Am sichersten ist es deshalb, anstelle des Namens die Application-ID (AppID) zu verwenden.

Beispiel für den "Titel" bei MS-Word mit geladener Datei "SendKeysMethode.doc":


Abbildung 1

"Wait" ist ein Wert vom Typ Boolean, der angibt, ob die aufrufende Anwendung den Fokus haben muss, bevor sie eine andere Anwendung aktiviert. Beim Wert False (Voreinstellung) wird die angegebene Anwendung mit sofortiger Wirkung aktiviert, auch wenn die aufrufende Anwendung nicht den Fokus hat. Beim Wert True wartet die aufrufende Anwendung, bis sie den Fokus erhält, und aktiviert dann die angegebene Anwendung.

Die Anweisung: AppActivate "MeinDokument1.doc - Microsoft Word", Wait:=True würde das bereits gestartete Textverarbeitungsprogramm mit der geladenen Datei MeinDokument1.doc in den Vordergrund bringen.

Die sicherste Methode überhaupt ist es, das Programm von VB/VBA selbst aus zu starten. Die gewünschten Funktionen mit Hilfe der Sendkeys abzurufen und danach das Programm wieder zu schließen. Dies gelingt z.B. mit Hilfe eines Shell-Aufrufes. Dabei kann dann auch die Application-ID aufgefangen werden, mit der später eine eindeutige Zuordnung zum Programm möglich ist. Ein Beispiel dazu:

Dim appID As Integer
appID = Shell("notepad.exe", vbNormalFocus) 
AppActivate appID

Listing 2

Die erste Zeile enthält eine gewöhnliche Deklaration. Die zweite Zeile startet den Windows-Editor Notepad und füllt die Integervariable appID mit der zugehörigen Application-ID. Die Zahl 1 (oder vbNormalFocus) hinter dem String "notepad.exe" ist übrigens optional. Dieser Parameter bestimmt wie das Programm gestartet wird. Dabei bedeuten:

  • 1 (vbNormalFocus) Das Programm wird in Normalgröße gestartet und erhält den Fokus
  • 2 (vbMinimizedFocus) Das Programm wird minimiert gestartet und erhält den Fokus
  • 3 (vbMaximizedFocus) Das Programm wird maximiert gestartet und erhält den Fokus

Die dritte Zeile garantiert, dass die soeben gestartete Applikation (Editor Notepad im Beispiel) den Fokus erhält, den der Wert von appID ist unique. Diese Zeile kann je nach Erfordernis irgendwo - auch mehrfach - im Programmtext stehen. Die Anordnung unmittelbar nach dem Shell-Aufruf wie im Beispiel oben ist eigentlich überflüssig, da das Programm damit bereits den Fokus erhält. Typisch ist es diese Zeile unmittelbar vor dem Absenden der Tastaturcodes anzuordnen.

Im obigen kleinen Beispiel wurde in der zweiten Zeile stillschweigend vorausgesetzt, dass der Pfad zur Datei notepad.exe in Windows bekannt ist. Falls dies nicht garantiert werden kann, ist natürlich die komplette Pfadangabe zu übergeben:

appID = Shell("C:\WINNT\notepad.exe", vbNormalFocus)

Listing 3

Tastaturkürzel senden  

Nachdem das zu steuernde Programm auf diese Weise gestartet wurde und den Fokus erhalten hat, können die Tastaturcodes abgesandt werden. Die allgemeine Syntax dazu lautet wie folgt:

SendKeys String [,Wait]

"String" beinhaltet den zu sendenden Tastaturcode, der als String übergeben wird.

"Wait" ist optional und vom Typ Boolean. Hat "Wait" den Wert True, dann wird gewartet bis die Anweisung komplett ausgeführt wurde. Erst danach erfolgt die Fortsetzung der Programmausführung in der nächsten Zeile. Falls "Wait" den Wert False hat, wird der Tastaturcode abgesandt und unmittelbar danach in der nächsten Zeile weitergemacht. Im Prinzip kann dies ausgenutzt werden um parallele Prozesse anzuwerfen (was aber einige Gefahren in sich birgt).

Beispiel: das Programm, das gerade zufällig den Fokus hat soll geschlossen werden.

SendKeys String:="%{F4}", Wait:=True

Listing 4

oder kürzer:

SendKeys "%{F4}", True

Listing 5

"%{F4}" bedeutet hier [Alt]+[F4].

Einige Tasten haben spezielle Aufgaben. Eine Liste der bei Spezialtasten zu verwendenden Strings ist nachfolgend abgebildet.


Abbildung 2

Es gibt ein paar Grundregeln bei der Übergabe der Tastaturcodes, deren Kenntnis den Umgang mit der Methode sehr vereinfacht:

  • die Tastaturcodes werden in Anführungsstrichen übergeben (wegen des Variablentyps String)
  • Tasten mit speziellen Funktionen werden in geschwungenen Klammern gesetzt.
  • die Zeichen ~%()+{}[] müssen in runden Klammern übergeben werden
  • Wenn UMSCHALT, STRG und ALT gleichzeitig mit anderen Tasten gedrückt werden müssen, wird der Code für die Tasten in Klammern eingeschlossen. Wenn zum Beispiel die UMSCHALTTASTE (Shift-Taste) gleichzeitig mit den Tasten [E] und [C] gedrückt werden soll, muss "+(EC)" übergeben werden. Wenn die UMSCHALTTASTE zusammen mit [E] gedrückt werden soll und im Anschluß daran [C] ohne UMSCHALTTASTE, lautet der Ausdruck richtig "+EC".
  • Soll eine Taste mehrfach betätigt werden, kann dies hinter dem Kürzel in der geschweiften Klammer angegeben werden. Wenn zum Beispiel die Tabulator-Taste zweimal betätigt werden soll kann geschrieben werden: SendKeys "{TAB 2}", True

Anwendungsbeispiel: Mit Hilfe des Windows-Calculators (calc.exe) soll die Summe aller Zahlen von 1 bis 100 berechnet werden. Anschließend wird der Calculator geschlossen. Das Ergebnis wird nicht weiterverwertet.

Dim Ergebnis, I 

'Starten des Windows-Calculators und Auffangen der Applikation-ID 
appID = Shell("CALC.EXE", 1) 

'Sicherstellen dass der Calculator den Fokus hat 
AppActivate appID 

'berechnen der Summe der Zahlen von 1 bis 100
For I = 1 To 99 
    'send keys to add the values of I 
    SendKeys I & "{+}", True
Next I
SendKeys ("100"), True
SendKeys "=", True 

'Schließen des Calculators mit [Alt]+[F4] 
SendKeys "%{F4}", True

Listing 6

Ergebnis sichern  

Im vorangegangenen Beispiel wurde etwas mit dem Calculator berechnet. Bei der Programmausführung kann man dies am Bildschirm mitverfolgen. Das Ergebnis wurde aber wieder vergessen bzw. nicht verwendet. Normalerweise möchte man aber das Resultat aus der fremden Applikation nutzen. Es stellt sich also die berechtigte Frage, wie kann das Ergebnis einer SendKeys-Aktion in einem VB/VBA-Programm (oder in einem anderen, dritten Programm) benutzt werden. Dazu bieten sich drei Wege mit unterschiedlichen Vor- und Nachteilen an:

  • a) über das Dateisystem (Festplatte)
  • b) über die Windows-Zwischenablage
  • c) über direkten Zugriff auf den Arbeitsspeicher

Punkt c) ist eher umständlich und bietet nur bei wirklich zeitkritischen Routinen einen echten Vorteil. Er wird deshalb im Rahmen dieses Aufsatzes nicht weiter behandelt. Interessanter und einfacher zu handhaben ist der Fall a) oder b).

Fall a): Ergebnisse über das Dateisystem (Festplatte) sichern

Die Möglichkeit a) ergibt sich häufig aus der Aufgabenstellung. Dazu ein Beispiel: Es soll mit Hilfe des Windows-Programms "Paint" (mspaint.exe) eine Grafikdatei vom bmp-Format in das jpg-Format umgewandelt werden. In diesem Fall ist das Ergebnis bereits eine Datei.

Im Beispiel wird der Dateiname der zu konvertierenden bmp-Datei samt Pfad in eine TextBox eingetragen. Die erzeugte jpg-Datei wird im selben Ordner abgelegt in dem sich auch die Originaldatei befindet. Dazu muss das Programm "Paint", dass sich im Windows-Systemordner befindet gestartet werden. Anschließend muss der Fokus auf dieses Programm sichergestellt werden. Dann wird die Originaldatei eingeladen und als jpg-Datei wieder abgespeichert. Zum Schluss wird das Programm Paint beendet.


Abbildung 3: Oberfläche des Grafik-Konvertierungsprogramms

Private Sub grafikkonverter_Click()
    Dim appident As Integer
    Dim Eingang As String
    
    'Pfad zu den zu konvertierenden bmp-Dateien
    Eingang = TextBox1.Value
    
    'Starten des Programms MS-Paint und den Fokus darauf setzen
    appident = Shell("C:\WINNT\system32\mspaint.exe", 1)
    AppActivate appident
    
    'Einladen der Datei in MS-Paint
    SendKeys "%Df", True
    SendKeys Eingang, True
    SendKeys "{ENTER}", True
    
    'Abspeichern der eingeladenen Datei als jpg-Typ im selben Verzeichnis
    SendKeys "%Du", True
    SendKeys "{TAB}j", True
    SendKeys "{ENTER}", True
    
    'MS-Paint beenden
    SendKeys "%({F4})"
End Sub

Listing 7

Nachfolgend die Bedeutung der im obigen Beispiel verwendeten Tastenkürzel:

Das Einladen der Datei erfolgt mit

  • % Alt, um in die Menüleiste zu gelangen
  • D zum Öffnen des Pulldown-Menüs "Datei"
  • f den Dialog zum Einladen einer Datei öffnen

Beim Abspeichern sieht es wie folgt aus:

  • % Alt, um in die Menüleiste zu gelangen
  • D zum Öffnen des Pulldown-Menüs "Datei"
  • u zum Öffnen des Dialogs "Speichern unter"

In diesem Zustand ist der Fokus auf die Eingabe des Dateinamens gesetzt. Mit {TAB} gelangt man in das nächste Feld, mit dem der Dateityp vorgegeben wird. Man kann nun durch Eintippen des Anfangsbuchstabens eine Auswahl treffen. Mit "j" wird das jpg-Format ausgewählt.

Dieses kleine Programm ist natürlich noch nicht alltagstauglich, denn wenn z.B. die Zieldatei bereits im Ordner vorhanden ist gelingt das Abspeichern (und in diesem Falle das Überschreiben) und Beenden des Programmes nicht. MS-Paint würde anhalten und fragen ob die vorhandene Datei überschrieben werden darf. Da es bei der SendKeys-Methode keine Rückmeldungen gibt, müsste also vorher mit herkömmlichen VB/VBA-Methoden überprüft werden, ob der Zielordner leer ist bzw. ob sich vielleicht eine gleichnamige Datei darin befindet.

Außerdem wäre es sinnvoll wenn alle bmp-Dateien die sich in einem Ordner befinden automatisch in das jpg-Format konvertiert würden, ohne dass man einen Dateinamen auswählen muss. Aber auch dafür gibt es Lösungen.

Ein etwas umfangreicheres Beispiel: Alle Bilder (jpg-Dateien) in einem Verzeichnis sollen verkleinert werden, wobei das Höhe-Breiten-Verhältnis und auch der Inhalt nicht verändert werden darf. Die Resultate sollen eine einheitliche Höhe von 400 Pixel aufweisen und im gleichen Verzeichnis unter einem neuen Namen abgelegt werden. Auch hier wird VB nur für die Steuerung eines Fremdprogrammes, das dann die eigentliche Arbeit erledigt, eingesetzt. Das Windows-Programm mspaint.exe ist mit dieser Aufgabe überfordert. Man kann sich ein über die Tastatur steuerbares Free- oder Sharewareprogramm beschaffen und die Aufgabe mit dessen Hilfe lösen. Im hier gezeigten Beispiel wird das Programm PaintShopPro (Shareware) in der Version 7.06 (engl.) verwendet. Dieses Programm ist im Internet verfügbar. Es kann zu Testzwecken kostenlos heruntergeladen und installiert werden. Um das Beispiel nachzuvollziehen muss PSP 7.06 auf dem Windows-System installiert sein. Eine andere Version dieses Programms würde eventuell eine Anpassung der Tastaturcodes erfordern.

Betrachtet man den Programmcode, so zeigt sich, dass bei der SendKeys-Methode noch eine weitere Schwierigkeit auftaucht: Es gibt keine Rückmeldung, ob eine Anweisung fertig ausgeführt wurde. Bei den meisten Vorgängen hängt die Ausführungsdauer von der verwendeten Hardware ab. Sendet man aber einen Folgecode zu früh, also wenn z.B. ein Speichervorgang noch nicht abgeschlossen ist, so kann dies zu unvorhersehbaren Aktionen führen. Aus diesem Grund wurden im Programmcode an kritischen Stellen Pausen eingearbeitet. Eine schnelle Programmausführung läßt die Methode also nicht zu. Außerdem ist die Ausführungsdauer von der Anzahl der umzuarbeitenden Dateien abhängig. Das heißt, dass Programm PaintShopPro ist eine geraume Zeit maximiert auf dem Bildschirm zu sehen und hat den Fokus. Wegen der eingefügten, notwendigen Pausen steht das Programm zeitweise still. Klickt ein Anwender in dieser Phase auf einen Menüpunkt oder gewährt einem anderen Programm den Fokus, so werden die Voraussetzung für das Weiterarbeiten verändert und die nächsten gesendeten Steuercodes laufen ins Leere oder führen in einem Programm das zufällig den Fokus hat, unvorhersehbare Aktionen aus. Es ist also sowohl bei der Programmierung, als auch bei der Anwendung Vorsicht geboten!

'Dieses Programm verwendet PSP 7.06 (engl.)
'um eine Anzahl von max. 100 Bildern
'auf eine einheitliche Höhe von 400 Pixel zu bringen.
'Das Seitenverhältnis Breite/Höhe bleibt erhalten.

Option Explicit
Option Base 1

'die Bildhöhe fest vorgeben
Const einheitlichehoehe As Integer = 400

'den Pfad mit den zu bearbeitenden Dateien fest vorgeben
Const quellpfad As String = "E:\Fotos\"

'Array mit den Namen der zu ändernden Dateien (maximal 100)
Dim dateinamen(100) As String


Sub verkleinern()
    Dim l_anzahlreturn As Integer
    Dim l_zaehler As Integer
    Dim l_appid As Integer
    Dim l_pfadundname As String
    Dim l_returnpause As String
    
    'ermitteln wieviele Bilddateien verkleinert 
    'werden sollen (Funktionsaufruf)
    l_anzahlreturn = wievieledateien(quellpfad)
    
    'nur arbeiten, wenn wenigstens eine Bilddatei im Verzeichnis liegt
    If l_anzahlreturn > 0 Then
    'PaintShopPro öffnen und die Application-ID auffangen
    l_appid = Shell(C:\Programme\Jasc Software Inc\ _
    Paint Shop Pro 7\psp.exe, 3)
    '3 bedeutet: Maximiert, mit Fokus
    
    'PaintShopPro erscheint im vorliegenden Fall mit einem Start-
    'Fenster und einem Dialogfenster; beides muss quittiert werden. 
    'Des Start-Fenster verschwindet nach ein paar Sekunden von alleine.
    'Das Dialogfeld muss quittiert werden.
    'Pauschal 10 s warten bis dass das Start-Fenster verschwunden ist.
    l_returnpause = pause(10)
    
    'Das Dialogfenster schließen mit [RETURN]
    AppActivate l_appid, False
    SendKeys "{ENTER}", True
        
        For l_zaehler = 1 To l_anzahlreturn
        
        'den Öffnen-Dialog starten
        SendKeys "^o", True 'entspricht File Open
        
        'ein Bild einladen
        l_pfadundname = quellpfad & dateinamen(l_zaehler)
        SendKeys l_pfadundname, True
        SendKeys "{ENTER}", True
          
        'Pauschal 5s warten bis die Datei eingelesen ist
        l_returnpause = pause(5)
        
        'Bildgröße anpassen (die eigentliche Umrechnung)
        SendKeys "+S", True    'entspricht Image Resize
        SendKeys "400", True    'entspricht Eingabe der Breite 400
        SendKeys "{ENTER}", True  'Übernahme der Einstellung
        
        'Zielpfad- und name festlegen           
        l_pfadundname = quellpfad & "klein_" & dateinamen(l_zaehler)
        
        'Pauschal 1s warten bis die Umrechnung abgeschlossen ist
        l_returnpause = pause(1)
        
        'Speicherdialog aufrufen, neuen Dateinamen eingeben und 
        'in das selbe Verzeichnis abspeichern
        SendKeys "{F12}", True 'File SaveAs-Dialog öffnen
        SendKeys l_pfadundname, True
        SendKeys "{ENTER}", True
        
        'falls die Datei schon da ist: Dialog quittieren und Datei 
        'überschreiben; falls die Datei noch nicht existiert stört das 
        '"J" auch nicht
        SendKeys "J", True  
        
        'Pauschal 3s warten bis abgespeichert ist (da die Bilder jetzt 
        'sehr klein sind nur 3 Sekunden pro Bild)
        l_returnpause = pause(3)
        
        'Bild schließen
        SendKeys "%", True   'entspricht [Alt]
        SendKeys "FC", True  'entspricht File Close
        SendKeys "N", True   'entspricht Nein, das Original nicht
        'überschreiben
        
        Next l_zaehler
        
    'PaintShopPro beenden
    SendKeys "%{F4}", True
    
    Else
        MsgBox "Keine Dateien im Verzeichnis vorhanden."
    End If

End Sub


Function wievieledateien(pfadangabe As String) As Integer
'hier wird festgestellt wieviele Dateien im Quellverzeichnis vorhanden 
'sind und welche Namen diese haben
    
    Dim l_zaehler As Integer
    Dim l_dname As String
    
    l_zaehler = 0
    
    'erste Datei in pfadangabe lesen und dir initialisieren
    l_dname = Dir(pfadangabe)
    
    'falls mindestens eine Datei vorhanden ist versuchen alle weiteren
    'festzustellen; die Dateiendung wird nicht geprüft. Es werden jpg- 
    'Dateien vorausgesetzt.
    If l_dname <> "" Then
        l_zaehler = 1
        dateinamen(l_zaehler) = l_dname
        Do
            l_dname = Dir()
            If l_dname <> "" Then
            l_zaehler = l_zaehler + 1
            dateinamen(l_zaehler) = l_dname
            
            'Sicherstellen das nur maximal 100 Dateien bearbeitet
            'werden
            If l_zaehler = 100 Then
                Exit Do
            End If
            Else
            'falls weniger als 100 Dateien vorhanden sind, weitermachen
            Exit Do
            End If
        Loop
    
        'Anzahl der Dateien zurückgeben
        wievieledateien = l_zaehler
    Else
        wievieledateien = 0
    End If
End Function


Function pause(wartesekunden As Integer) As String
'Dieser Funktion wird eine Wartezeit in Sekunden (Ganzzahl)
'angegeben.
    Dim l_zeit As Double
    Dim l_wartezeit As Double
    Dim l_deltazeit As Double
    l_zeit = CDbl(Time)
    l_wartezeit = (1 / 86400) * wartesekunden '86400 = 24*3600
    Do
        l_deltazeit = Time - l_zeit
        If l_deltazeit > l_wartezeit Then
            Exit Do
        End If
    Loop
    pause = "Pause beendet!"
End Function

Listing 8

Wenn nicht Dateien, sondern einzelne Daten (z.B. Zahlenwerte) übergeben werden müssen, können diese in eine Datei auf die Festplatte abgelegt und dann mit VB/VBA-Mitteln geöffnet und übernommen werden. Das Ablegen der Werte geschied z.B. mit der SendKeys-Methode indem man üblicherweise den Dialog "Datei/Speichern" unter bzw. "File/Save as" ansteuert. Die angelegte Datei wird dann unter zuhilfenahme üblicher VB/VBA-Mittel (Open....) eingelesen und die Daten können ausgewertet werden. Wie dies gemacht wird ist nicht Thema dieses Aufsatzen und vermutlich bekannt. Ein Beispiel erübrigt sich deshalb hier.

Fall b) Ergebnisse über die Windows-Zwischenablage sichern

Diese Methode ist besonders einfach und schnell anzuwenden. Nehmen wir das gezeigte Beispiel mit dem Windows-Calculator. Das Ergebnis der Berechnung wurde dort nicht verwendet - es wurde einfach wieder vergessen. Soll es in die Zwischenablage übernommen werden, ist vor dem Schließen des Calculators die folgende Zeile einzufügen:

SendKeys "^c", True

Listing 9

Beim String "^c" handelt es sich um die übliche Bedienung der Zwischenablage über die Tastatur:

  • Strg + C : das markierte Elemente bzw. die markierten Elemente als Kopie in die Zwischenablage legen
  • Strg + X : das markierte Element ausschneiden und in die Zwischenablage legen
  • Strg + V : den Inhalt der Zwischenablage an die bezeichnete Stelle ablegen (kopieren)

Das "markierte Element" ist im vorliegenden Fall der im Calculator errechnete Wert. Möglich wäre auch die Steuerung über die spezifischen Tastaturkürzel des jeweiligen Programms. Dies sähe beim Windows-Calculator wie folgt aus:

SendKeys "%BK", True

Listing 10

Dies entspricht der Tastaturbedienung [Alt] [Bearbeiten] [Kopieren]. Das Ergebnis befindet sich dann in der Zwischenablage. Um es von dort ohne Umweg abzuholen und z.B. in einer Textbox auszugeben kann die "GetFromClipboard"-Methode benutzt werden.

Beispiel: Mit Hilfe des Windows-Calculators soll eine Dezimalzahl in eine Binärzahl umgewandelt werden. Der Wert wird in einem Eingabe-Textfeld entgegengenommen, dann über die Zwischenablage dem Windows-Calculator übergeben und dort binär dargestellt. Anschließend wird der im Calculator dargestellte Wert - also das Ergebnis - in die Zwischenablage gebracht und in einem Ausgabe-Textfeld aus der Zwischenablage übernommen.


Abbildung 4

Option Explicit

'Umrechnung einer Dezimalzahl in eine Binärzahl.
Private Sub uebernehmen_Click()

    Dim l_appid As Integer
    Dim l_inputvalue As String
 
    'Eingabewert in der TextBox markieren und in die Zwischenablage bringen
    TextBox1.SelStart = 0
    TextBox1.SelLength = TextBox1.TextLength
    TextBox1.Copy
    
    'Windows-Calculator maximiert starten und Fokus geben
    l_appid = Shell("C:\WINNT\system32\calc.exe", 3)
    
    'auf wissenschaftliche Darstellung schalten
    SendKeys String:="%AW", Wait:=True
    
    'Inhalt der Zwischenablage einfügen
    SendKeys String:="^v", Wait:=True
    
    'Umschalten auf Binärdarstellung
    SendKeys String:="%ab", Wait:=True
    
    'Binärzahl in die Zwischenablage bringen
    'und den Calculator schließen
    SendKeys String:="^c", Wait:=True
    AppActivate l_appid 'Sicherstellen dass der Calculator den Fokus hat
    SendKeys String:="%{F4}", Wait:=True
    
    'Ergebnis anzeigen
    TextBox2.Paste
    
End Sub

Listing 11

Schlusswort  

Die Beispiele haben sicherlich die Einfachheit der Anwendung der SendKeys-Methode aufgezeigt. Allerdings birgt sie auch Gefahren: Wenn der Fokus nicht sorgfältig auf das zu steuernde Programm gesetzt wird, können unvorhersehbare Aktionen ausgelöst werden. Dies trifft auch zu, wenn die zu sendenden Tastaturcodes einen Fehler enthalten. Es ist deshalb dringend anzuraten, die auszuführenden Aktionen vor dem eigentlichen Programmieren zunächst einmal per Handarbeit auszuführen und die verwendeten Tastaturkürzel sorgfältig zu notieren.

In jedem Fall sollte, wie in den Beispielen zu sehen, immer der Parameter Wait auf True gesetzt sein. Unterläßt man dies und ein Befehl wird nicht ausgeführt, weil sich vielleicht die Umstände geändert haben (z.B. eine abzuspeichernde Datei ist bereits auf der Festplatte, etc.) können die übrigen Anweisungen unter Umständen unvorhersehbare Aktionen auslösen. Ist der Parameter Wait jedoch auf True gesetzt, werden die nach einem nicht ausführbaren Kommando folgenden Anweisungen ignoriert.

Zusätzlich sind ausreichend Pausen einzubauen die sicherstellen, dass ein Tastaturcode erst dann abgesandt wird, wenn das zu steuernde Programm bereit dafür ist - d.h. nicht mit irgendwelchen Aktionen oder Berechnungen beschäftigt ist.

Ihre Meinung  

Falls Sie Fragen zu diesem Tutorial haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Zum Calculator-Makro - Chris Gast 11.06.13 10:04 3 Antworten