Ist dies erledigt, können wir mit der eigentlichen Aufnahme beginnen. Hierzu dient die Message GS_WRITE:
msg[0] GS_WRITE msg[1] Applikations-ID msg[2] 0 msg[3] + Pointer auf Kommandozeile (wie bei GS_COMMAND) msg[4] msg[5] ID aus GS_MACRO msg[6] 0 msg[7] 0
Wie wir sehen, wird hier eine Kommandozeile übergeben, die exakt dasselbe Format hat wie die bei GS_COMMAND vom Interpreter an die Applikation geschickte. Demnach ist die Aufnahme auch programmiertechnisch der umgekehrte Fall des Abspielens eines Skriptes, hier werden eben nicht Kommandos des Interpreters von der Applikation in Aktionen umgesetzt, sondern genau umgekehrt.
Dazu empfiehlt es sich, vielleicht über eine Semaphore, den Aufnahmestatus im eigenen Programm zu markieren. Dann kann beim Sprung in jede Programmfunktion, die bei einer Useraktion aufgerufen wird, eine entsprechende Kommandozeile an den Interpreter geschickt werden.
Ich verwende hierzu eine globale Funktion
gemscriptRecord(int command, char *param)
die zu Beginn jeder Funktion, die eine "aufzeichenbare" Useraktion behandelt, aufgerufen wird.
command ist hier das Kommando in Form einer symbolischen Konstanten, param die entsprechenden Parameter. Aus der Applikationsroutine, die das Anklicken von "Datei/Öffnen" behandelt, wird diese Funktion folgendermaßen aufgerufen:
gemscriptRecord(GS_OPEN, filename);
Filename wäre hierbei der Dateiname der vom User gewählten Datei.
Hier die record-Funktion (der Einfachheit halber nur für ein Kommando):
int gemscriptRecord(int command, char *param) { char *cmdline = malloc(strlen(param)+32); char *parameters; /* eine Prüfung, ob der allozierte Speicher auch tatsächlich vorhanden ist, muß hier natürlich auch rein */ /* Kommando schreiben und *parameters dahinter ausrichten */ strcpy(cmdline, gsCommands[command]); parameters = cmdline+strlen(cmdline)+1; strcpy(parameters, param); sendAESMessage(ScripterID, GS_WRITE, cmdline); }
Es entscheidet sich hier also erst in dieser Funktion, wie die Kommandozeile zusammengesetzt wird. Dadurch muß sie nicht komplett in der aufrufenden Funktion zusammengebaut werden und das Kommando kann einfach als Nummer anhand von symbolischen Konstanten übergeben werden. Das Array char *gsCommands[] enthält Zeiger auf die referenzierenden Strings der intern verwendeten GEMScript-Kommandonummern, also z.B. bei
#define GS_OPEN 0 #define GS_CLOSE 1 gsCommands[0] = "Open" gsCommands[1] = "Close"
Schließlich wird die Kommandozeile mittels der Message GS_WRITE an den Interpreter übertragen.
Als Antwort auf diese Message erhalten wir vom Interpreter wie gewohnt GS_ACK, allerdings ohne ein Ergebnis in msg[4]/[5]. Die GEMScript-Entwickler empfehlen, die Aufnahme abzubrechen, wenn bei diesem GS_ACK ein Fehler signalisiert wird.