![]() |
ScriptingEngine?
Hi,
ich suche derzeit nach einer Art ScriptingEngine... Ich habe Scripte, die ungefähr so aussehen:
Code:
($x sind Variablen; alles andere Strings bzw. Anweisungen; ist eines der komplizierteren... ;))
findwindow "wndname" $1 // findet das Fenster
findchild $1 "pagecontrol" $2 // findet das pagecontrol findchild $2 "label" $3 // findet das Label getnumber $3 "Nr. " " um" $4 // findet die Nummer x heraus, x steht in $4 findchild $2 "btn".$4 $5 sendmessage bm_click $5 END Nun frage ich mich, wie man sowas machen kann, dass man das ganze sozusagen interpretiert. Muss ich das ganze etwa per copy, delete, ... machen??? Dann würde ich glatt durchdrehen! :freak: Naja... das Problem sind da eher Knackpunkte wie die zusammensetzung eines Strings und einer Variable (z.B. "btn".$4). Gibt es irgendwo so eine Art "Vorlage"? Oder habt ihr eine Idee, wie man sowas machen kann? Chris |
Moin Chris,
mit einer Idee kann ich dienen ;-) Da es sich offensichtlich um ein sequentiell abzuarbeitendes Script handelt, könntest Du es so machen: Voraussetzungen:
Jetzt kannst Du die Liste in einer Schleife durchgehen, und die einzelnen Zeilen in ihre Bestandteile zerlegen, wobei als erstes wohl immer ein Schlüsselwort steht (hoffentlich ;-) ), gefolgt von Parametern, in Abhängigkeit des Schlüsselwortes. Als Beispiel mal Deine erste Zeile: Schlüsselwort findwindow. Jetzt weisst Du, dass als nächstes der Name es Fensters erscheinen muss, und dann der Name einer Variablen, in der das Ergebnis gespeichert werden soll. Dann kannst Du die Funktion ausführen, und das Ergebnis in der Variablenliste speichern. Soll der Wert einer Variablen verwendet werden, muss dieser dann aus der Liste ausgelesen werden. Ggf. kann die Liste auch eine einfache Stringliste in der Form Variablenname=Wert sein. Für eventuelle vordefinierte Konstanten (bm_click) wäre eine entsprechende weitere Liste ganz sinnvoll. |
|
Hi,
@Christian: also so, oder so ähnlich, hatte ich mir das auch schon gemacht, allerdings überlegte ich nach einer Möglichkeit das ohne es so kompliziert zu machen (wobei man sagen muss, dass deine Möglichkeit viel einfacher ist, als ich sie mir ausgedacht hab). [EDIT] Da fällt mir: das Problem ist, dass für jeden Befehl ich eine if-Abfrage machen muss, weil ja jeder Befehl eine andere Struktur hat und andere Befehle verwendet. Also zum Beispiel sendmessage verlangt andere Parameter, als findwindow. Auch die Anzahl ist unterschiedlich. Das Problem ist z.B. auch, dass Zusammensetzen (wie gesagt: ein String.eine Variable). Wie bitte soll ich das anstellen? :| [/EDIT] Deswegen... ...@chris: werde mir das mal ansehen. Allerdings scheint mir das schon wieder ein wenig zu aufwendig. Aber ich habe jetzt nur mal einen Blick drauf geworfen! Chris |
Moin Chris,
je komplizierter/flexibler die zu verarbeitende Sprache ist, umso komplizierter wird halt auch die Verarbeitung. Solange sich das ganze sequentiell abarbeiten lässt und dabei die einzelnen Funktionen und Paramter leicht zu trennen sind, ist die Umsetzung nicht ganz so schwierig. Sobald Du mit bedingtem Programmablauf (womöglich verschachtelt) und Schleifen anfängst wird's merklich komplexer. |
Moin Chris,
Du kannst doch den Wert einer Variablen aus der vorgeschlagenen Tabelle auslesen (Eigenschaft z.B. sWert := slVariablen.Values['$4'];). Diesen verbindest Du dann mittels + mit der Konstanten. |
Mit Schleifen usw. will ich gar nichts anfangen...
Denn eigentlich bringen mir Schleifen nichts. Ich habe gerade dieses Innerfuse-Teil heruntergeladen. Also wirklich begeistert bin ich nicht. Nicht einmal eine install.txt. :evil: Naja... werde das ganze mal versuchen. Chris |
Stimmt... Warum mach ich die Sache eigentlich selber so scher??? :wall:
Chris |
Hi,
ich hab gerade bei der ganzen Sache ein Problem (die Klasse an sich funktioniert wunderbar): Ich bräuchte eine Funktion, die mir den n. Parameter liefert. Also z.B.:
Code:
dann ist findwindow der 0., test window der 1. und $1 der 2.
findwindow "test window" $1
Hat jemand dafür eine Funktion parat? Ich habe im Moment nämlich keine Idee, wie ich das machen soll, dass Problem ist halt die Sache mit den Strings... :( Chris |
Na ja, im Prinzip werden die Parameter durch Leerzeichen getrennt. Nur wenn vor dem Leerzeichen eine ungerade Anzahl an Gänsefüßchen steht, dann ist das Leerzeichen kein Trennoperator. Also Zeichen für Zeichen durchgehen, zusätzlich boolsche Variable für String oder nicht und falls kein String, trennen am Leerzeichen.
Alternativ dazu die Anzahl der Gänsefüßchen vor dem Leerzeichen ermitteln: Falls ungerade -> Leerzeichen ignorieren, ansonsten trennen. |
Moin Chris,
ich würd's leicht anders machen: Die Zeile zeichenweise durchgehen, dabei in Schlüsselwort und Parameter trennen, indem bei auftreten eines " alle Zeichen ab der Position von " +1 bis zum nächsten " (-1) als String übernommen werden, und ab $ bis zum Auftreten von #32 als Variablenname. |
Hi Chris, hi Chewie,
danke für eure Hilfe! Ich werde versuchen Christians Idee umzusetzen (muss erstmal Onkel Fisch anhören :mrgreen:). Chris |
Hi,
ich habe gerade das ganze mal versucht. Erstmal meine Funktion:
Delphi-Quellcode:
Bei lineStr =
function GetParam(index: integer; lineStr: string): string;
var Params: array[0..5] of string; counter: integer; paramCounter: integer; temp: string; oldEnd: integer; openString: boolean; i: integer; begin counter := 0; paramCounter := -1; oldEnd := 1; repeat inc(counter); if lineStr[counter] = '"' then begin openString := true; i := counter; while openString do begin inc(i); if lineStr[i] = '"' then openString := false; end; temp := copy(lineStr, counter, counter + 1 - i); inc(paramCounter); Params[paramCounter] := temp; oldEnd := i; counter := i; end; if lineStr[counter] = ' ' then begin temp := copy(lineStr, oldEnd, counter - oldEnd); inc(paramCounter); Params[paramCounter] := temp; oldEnd := counter; end; until counter = length(lineStr); end;
Code:
wird so ist Paramcount so:
findwindow "test" "test test" $1
Code:
Das erste ist ja richtig... :mrgreen:
0: findwindow
1: 2: " 3: 4: " 5: Woran kann das liegen? Wo liegt der Hund begraben? Chris |
Habe gerade noch mal drüber geschaut. Jetzt sieht das ganze so aus:
Delphi-Quellcode:
Das Array geht von 0 bis 10 und die Ausgabe ist:
counter := 0;
paramCounter := -1; oldEnd := 1; repeat inc(counter); if lineStr[counter] = '"' then begin openString := true; i := counter; while openString do begin inc(i); if lineStr[i] = '"' then openString := false; end; temp := copy(lineStr, counter, i - counter + 1); inc(paramCounter); Params[paramCounter] := temp; oldEnd := i; inc(counter); end; if (lineStr[counter] = ' ') or (length(lineStr) = counter) then begin temp := copy(lineStr, oldEnd, counter - oldEnd); inc(paramCounter); Params[paramCounter] := temp; oldEnd := counter - 1; end; until counter = length(lineStr);
Code:
Habt ihr eine Idee, wie man das ganze noch verbessern (lauffähig bekommen) könnte?
0: findwindow
1: "test" 2: " " 3: 4: "test test" 5: 6: " $1 7: 8: " $ 9: 10: Chris |
Moin Chris,
hier mal ein erweiterbares Muster. Es wäre u.U. sinnvoller mit einer speziellen Liste für das Ergebnis zu arbeiten (Einträge als Record mit den Feldern Token für die Kennung was es denn nun ist, und Attribute für den Wert). Der Einfachheit halber mal als StringListe, und die Typen als Konstanten, statt Aufzählungstyp. Das Muster entspricht im Wesentlichen dem, was ich Dir schon mal vorgeschlagen hatte. Die Leerzeichen entfallen, da Du sie nach der Aufspaltung der Zeile eh' nicht mehr brauchst.
Delphi-Quellcode:
procedure SplitCommandLine(const AsCommandLine : string;const AslResult : TStrings);
const _iIsKeyword = 1; _iIsVariable = 2; _iIsStringConst = 3; var iIndex : integer; iCount : integer; begin AslResult.Clear; iIndex := 1; while iIndex <= length(AsCommandLine) do begin case AsCommandLine[iIndex] of 'a'..'z','A'..'Z' : begin // Keyword filtern iCount := 1; while (iIndex < length(AsCommandLine)) and (AsCommandLine[iIndex+iCount] in ['a'..'z','A'..'Z']) do inc(iCount); AslResult.AddObject(copy(AsCommandLine,iIndex,iCount),Pointer(_iIsKeyword)); inc(iIndex,iCount); end; '"' : begin // StringKonstante iCount := 1; while (iIndex < length(AsCommandLine)) and (AsCommandLine[iIndex+iCount] <> '"') do inc(iCount); AslResult.AddObject(copy(AsCommandLine,iIndex+1,iCount-1),Pointer(_iIsStringConst)); inc(iIndex,iCount+1); end; '$' : begin // Variable iCount := 1; while (iIndex < length(AsCommandLine)) and (AsCommandLine[iIndex+iCount] in ['0'..'9']) do inc(iCount); AslResult.AddObject(copy(AsCommandLine,iIndex,iCount),Pointer(_iIsVariable)); inc(iIndex,iCount); end; else begin inc(iIndex); end; end; end; end; procedure TfrmMAIN.Button1Click(Sender: TObject); begin SplitCommandLine('findwindow "test" "test test" $1',Memo1.Lines); end; |
Öhm... ok... eigentlich wollte ich nur einen Vorschlag für meine Funktion, allerdings ist da deine doch wesentlich komfortabler.
Danke! Werde das ganze jetzt mal ausprobieren... Chris |
Moin Chris,
sorry, aber da ich mich seit geraumer Zeit, und auch gerade jetzt, intensiv mit der Thematik beschäftigt habe, war's für mich einfacher das neu zu machen, als mich in Deine Funktion einzulesen ;-) |
Zitat:
Chris |
So... Funktioniert jetzt alles wunderbar, aber wie mache ich das mit "string string string".$4???
[EDIT] Muss nicht unbedingt "string".$4 sein! Kann z.B. auch "string$4" sein... [/EDIT] Chris |
Moin Chris,
wenn Du mich mal aufklären könntest, wie Du Dir, so ganz im allgemeinen, die Syntax gedacht hattest, könnte ich Dir vielleicht darauf antworten. |
Hm... also gut ich will es versuchen.
Es gibt verschiedene Funktionen (z.B. findwindow) diese Funktionen haben verschiedene Parameter (z.B. Strings, Variablen [$x, ...], Konstanten). Nun ist es halt auch so, dass man als Parameter auch zusammengesetzte Sachen benutzen kann. Also z.B. "Ein String mit einer Variable: ".$x Das ganze ist eine einfache Skriptsprache, also soll nix wirklich Großes werden (also Abfragen, Schleifen, ...)! Hoffe, dass es das war, was du wolltest... ;) Chris |
Moin Chris,
das mit dem Zusammensetzen hatten wir doch schon mal weiter oben im Thread? Wenn es "string".$4 und "string$4" geben soll (was soll eigentlich der Punkt? Ersatz für +?), müssest Du noch eine Möglichkeit finden, eine Variable in einem String als solche zu erkennen. Das liesse sich dann z.B. so machen wie in C, mit Hilfe eines Escape Characters. In C dient dazu der \. Soll dieser dargestellt werden muss man ihn doppelt schreiben. (siehe z.B. auch Dateipfade in REG Dateien, da hat MS es auch so übernommen (warum eigentlich?)). Statt beide Möglichkeiten ins Auge zu fassen, halte ich es für sinnvoll, wenn Du Dich für eine entscheidest. Leichter umsetzen lassen dürfte sich die erste. Ich empfinde sie auch als übersichtlicher. Um so eine Zeile zu ermöglichen, musst Du Dir Regeln einfallen lassen, was alles auf was folgen darf, und was für eine Bedeutung das dann hat. Deshalb halte ich es für empfehlenswert beim Aufspalten einer Kommandozeile den einzelnen Teilen eine Kennung mitzugeben, soll heissen: Beim Aufspalten werden die Bestandteile in, sogenannten, Token gespeichert. Dazu kannst Du einfach einen Record erstellen, der zwei Felder enthält. Eines für die Kennung um was es sich handelt (Schlüsselwort, Variable, Stringkonstante, Operator ...), und eines das das zugehörige Attribut enthält (findwindow, $1...) wobei natürlich bei festliegenden Attributwerten (z.B. Schlüsselworten) das Eintragen des Attributes entfallen kann. Da Du Variablen verwenden willst wirst Du auch noch eine Variablenliste brauchen, in der Du dann die aktuellen Wert merken kannst. Was nun die Regeln angeht: Du musst prüfen, was auf (z.B.) FindWindow folgt, und ob es folgen darf (ggf. Fehler). Stösst Du auf eine Stringkonstante, so kann der Parameter damit komplett sein, oder aber ein . (+) folgen. Ist letzteres der Fall, so muss entweder ein Weiterer String folgen, oder eine Variable usw. Ich hoffe, dass alles war einigermassen verständlich. |
Verständlich!
Ich wollte sowieso nur eine Möglichkeit nutzen. Jenachdem, was einfacherer ist. Ich versuch das ganze mal weiter zuführen (deine Funktion ein wenig modifizieren :roll:). Chris |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz