Unabhängig von der Geschwindigkeit wären Callbackfunktion aber cool. Da steckt noch viel Potenzial in XProfan.
Callback Funktionen
-
-
-
Da gebe ich Dir Recht.
Gruß Volkmar
-
Es geht ja nicht nur alleine um die Funktion. Das Langsame bei XProfan
sind ja auch die WhileLoop - Schleifen. Das hast du ja selber mit dem
neuen ASM-Feature von XProfan bewiesen.
Du kannst ja mal eine Schleife mit 10000 Durchläufen mit einem
Interpreter und einem nativen Compiler messen. Je mehr Iterationen,
um so größer wird der Unterschied.Aber, wie ich bereits sagte, spreche ich von Hausgebrauch. Das sind
für mich etwa 1...1000 Einträge.Was die Funktion anbetrifft, könnte man der sogar noch mit ASM
mehr Speed geben. Steht ja nirgendwo, daß die Proc's unbedingt
mit XProfan - Befehlen geschrieben sein müssen.Eine Funktion mit ASM...ENDASM müßte da natürlich genau
so gut als Callback passen.Von daher habe ich also keine Bedenken.
-
Eigentlich wollte ich antworten, dass das Thema interessant ist, aber es nicht mehr für X4 reicht, ... aber dann hat es mich doch in den Fingern gejuckt. Folgendes wird gehen:
Code
Alles anzeigenMoveListProc Parameters string s, int i if get("MoveListMode") = 1 AddString str$(i) + " " + s elseif get("MoveListMode") = 2 AddString left$(s, 2) endif EndProc cls var string tage[] = "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag" set("MoveListMode", 1) move("ArrToList", tage[]) set("MoveListMode", 2) move("ArrToList", tage[]) set("MoveListMode", 0) move("ArrToList", tage[]) listbox$("Liste", 1) WaitInput End
Wenn der MoveListMode 0 ist (Voreinstellung), läuft alles wie bisher. Die Einträge landen blitzschnell und unverfälscht in der ListboxListe. Ist der Modus größer als 0, muss die Prozedur "MoveListProc" existieren. Dieser wird für jeden Eintrag der Quelle (Array, String, File, Mem oder Handle) der String und der Index als Parameter übergeben. Was dann damit angestellt wird, bleibt dem Programmierer überlassen. Man kann den String z.B. bearbeiten und dann mit AddString der ListboxListe hinzufügen. Man könnte ihn aber auch nur anzeigen, oder in ein Grid schreiben oder ...
Abhängig vom Modus kann die Bearbeitung unterschiedlich sein.Der MoveListMode gilt für alle Move("..ToList"-Funktionen.
Gruß
RolandIch werde eine neue Subscriptionsversion mit dieser Fähigkeit heute oder in den nächsten Tagen hochladen.
-
Na, das klingt doch gut. Ich will nicht rumningeln, aber da ich es gerade gebrauchen könnte: Ist auch ein Move("FileToHandle",...) geplant? Das fehlt irgendwie noch in der Sammlung. So muss ich die Datei in die Listboxliste einlesen und die dann ins Handle kopieren. Das könnte man vereinfachen.
Nachtrag: Geht bestimmt nicht. Die Move-Funktion baut immer mit der Listboxliste in einer Seite auf, das ist für Roland bestimmt zu viel Aufwand.
-
Wenn der MoveListMode 0 ist (Voreinstellung), läuft alles wie bisher. Die Einträge landen blitzschnell und unverfälscht in der ListboxListe. Ist der Modus größer als 0, muss die Prozedur "MoveListProc" existieren. Dieser wird für jeden Eintrag der Quelle (Array, String, File, Mem oder Handle) der String und der Index als Parameter übergeben. Was dann damit angestellt wird, bleibt dem Programmierer überlassen. Man kann den String z.B. bearbeiten und dann mit AddString der ListboxListe hinzufügen. Man könnte ihn aber auch nur anzeigen, oder in ein Grid schreiben oder ...
Abhängig vom Modus kann die Bearbeitung unterschiedlich sein.Der MoveListMode gilt für alle Move("..ToList"-Funktionen.
Roland, Genial
Damit braucht man nur eine Callback-Proc (MoveListProc) für alle.
Worüber ich jetzt aber grübele :
In deinem obigen Code hast du den MoveListMode für Move("ArrToList",...) verwendet.
Wenn ich aber nun mehrere Move("..ToList",...) mit der MoveListProc bedienen
möchte, dann stimmt zwar der Code für ein Array, aber nicht für eine andere Quelle,
z.B. eine Gridbox (...|....|). Da bekommst du mit Left$() nicht das Gewünschte raus
sondern eher mit SubStr$() + Delimitter.
Man könnte höchstens den MoveListMode als Protokoll verwenden (1 = Array, 2 = String, 3 = Handle, usw.).Das ist das Problem : Der MoveListMode gilt für alle Move("..ToList"-Funktionen
Oder bin ich da mal wieder auf dem Holzweg ?
-
Nachtrag :
Die MoveListProc weiß ja bei ihrem Aufruf nicht, von welcher Art Liste
der String und der index kommt. Und ich als Programmierer auch nicht.Vielleicht wäre da eine Systemvariable, die nur in der MoveListProc
gültig ist, hilfreich. Die könnte dann sowas ähnliches, wie pType$()
([] für Array {} für Gridbox o.ä.) enthalten. Durch Abfragen dieser
Systemvariablen hätte man die Art der Liste und könnte den Code
für die Bearbeitung des Strings entsprechend schreiben.Vielleicht auch so was ähnliches wie bei SUBCLASSPROC das
SubClassMessage(&hWnd, MsgNr%)
wo man das Handle der gerade aktuellen zu bearbeitenden Liste bekommt :CodeIf ListProcHandle(HandleDerListe&) If MoveListMode = 1 ..... ElseIf MoveListMode = 2 ...... EndIf EndIf
Den MoveListMode könnte man dann, wie oben gehabt, verwenden.
Wäre noch ein Vorschlag von mir.
-
Du gibst ja vor Aufruf der "...ToList"-Funktion den MoveList-Modus an, den Du für diese Funktion verwenden willst. Diesen kannst Du ja, wie im Beispiel gezeigt, in der MOVELISTPROC abfragen. Und somit weißt Du, woher der String und der Index kommen.
Und in allen Fällen handelt es sich um einen einfachen String.
Gruß
Roland -
Wird das eigentlich irgendwann mal nicht zu langsam, wenn z.B.
50 x oder mehr ?drin sind. Ich kann ja den Modus beliebig erhöhen und neuen Code schreiben,
wenn sich die Anforderungen ändern. Wäre z.B. der Fall, wenn eine Gridbox
viele Spalten hat und bei jeder Spalte ändert sich die Aufgabe. Und so eine
Callback kann man ja vielseitig nutzen. Es spräche ja auch nichts dagegen,
die Move(...ToList) - Funktionen zum Aufaddieren, MWST ausrechnen usw.
für jede Spalte zu mißbrauchen. Die Listboxliste kann man ja dann außen
vor lassen.Da es aber nur eine feste MoveListProc gibt, wird es auch schwierig, bewährte
selbstgeschriebene Codes darin zu verwalten. Man erfindet das Rad ja nicht
jedesmal neu, sondern nutzt Altbewährtes. Wenn man sich dann noch den
gebrauchten Code von älteren Quellcodes zusammen suchen muß ?
Man will ja schließlich keine riesengroße MoveListProc, sondern eine solche,
die für den momentanen Einsatzzweck die Anforderungen erfüllt.Von daher wäre mir eine selbstgeschriebene Callbackproc lieber gewesen.
Natürlich mit fester Vorgabe mit :
Parameters string s, int i
Dann könnte man die Callbackproc, die man gerade braucht an alle
Move-Funktionen binden (Set("MoveListCallback", "Proc-Name")) und
MoveListMode könnte entfallen. Und auch die vielen
If MoveListMode = x
-------
Endif
bräuchte man dann nicht.
Vielleicht könntest du auch einen extra Container machen, in der die
Callback-Procs mit SubProc gesammelt werden. Bei
Set("MoveListCallback", "Proc-Name"))
im Container nachschauen und die Proc anbinden.
Das wäre dann ganz XProfan-konform.Wie gesagt: So, wie es jetzt ist, ist es für einige wenige Codes
sehr gut durchdacht. Aber bei sehr vielen Codes wird das sehr
unübersichtlich.Sind jetzt nur so ein paar Gedanken von mir.
Ob überhaupt machbar, mußt du entscheiden. -
Du kannst ja problemlos aus der MOVELISTPROC andere Prozeduren in deinem Programm aufrufen. Dann bleibt die eigentliche MOVELISTPROC übersichtlich. Und es wird ja immer nur exakt ein String bearbeitet, der allerdings bei Gridboxen aus mehreren Teilstrings bestehen kann.
Gruß
Roland -
Wenn die Tage die neue Subscription kommt, versuche ich es
erst einmal. Werde mir mal in eine .inc erstellen,
die dann alle Callbackprocs aufnimmt. Evtl. später auch
noch einen Container. -
Die neue (und hoffentlich letzte) Subscriptionsversion ist da!
Gruß
Roland -
Hab schon etwas rum gespielt :
Code
Alles anzeigenDeclare String z, Handle gb, lv, Long summe z = "Was|ist|das|für|ein|Tag|gewesen !" Window 600, 400 gb = Create("Grid", 3, 0) ' unsichtbares Grid mit 2 Spalten lv = Create("Gridbox", %HWnd, "Spalte 1;0;80;Spalte 2;0; 120;Wert;0;60", 0, 50, 200, 280, 100) WhileLoop 1, 100 AddString(gb, Str$(&LOOP) + "|" + "Zeile" + "|" + Str$(Rnd(100 - 1)+ 1)) EndWhile MoveListProc Parameters String s, int i If Get("MoveListMode") = 1 s = Upper$(s) Print i, s ElseIf Get("MoveListMode") = 2 If (i > 48) And (i < 70) ' die Zeilen zwischen 50 und 70 kommen in die Gridbox AddString(0, s) EndIf ElseIf Get("MoveListMode") = 3 summe = summe + Val(SubStr$(s, 3, "|")) ' Spalte 3 zusammenzählen EndIf EndProc Set("MoveListMode", 1) Print Move("StrToList", z, "|") Print "Taste für weiter...." waitkey Set("MoveListMode", 2) Move("HandleToList", gb) Set("MoveListMode", 0) ClearList lv Move("ListToHandle", lv) Print "weiter für Taste..." waitkey ClearList lv ClearList summe = 0 Move("HandleToList", gb) Move("ListToHandle", lv) Set("MoveListMode", 3) Move("HandleToList", gb) AddString(lv, "---|SUMME :|" + Str$(summe)) SetCurSel lv, GetCount(lv) - 1 Print "Taste für Ende...." Waitkey
Damit kann man schon einiges anstellen.
-
Und da Roland uns ja die Freiheit gibt, selber zu entscheiden, was mit dem Eintrag
geschieht, ist auch ein begrenztes Move("HandleToHandle",...) möglich.
Man muß nur dazu Move("HandleToList",...) benutzen, da ja die SubProcs
von der neuen Funktionalität nicht profitieren können.
Man hat auf jeden Fall den Umweg über die Listboxliste gespart.Code
Alles anzeigenDeclare Handle gb, lv, btn1, Long ende ende = 0 Window 600, 400 gb = Create("GridBox", %HWnd, "Spalte 1;0;80;Spalte 2;0; 120;Wert;0;60", 0, 50, 50, 280, 100) lv = Create("Gridbox", %HWnd, "Spalte 1;0;80;Spalte 2;0; 120;Wert;0;60", 0, 50, 220, 280, 100) btn1 = Create("Button", %HWnd, "Copy", 50, 180, 60 ,25) WhileLoop 1, 10 AddString(gb, Str$(&LOOP) + "|" + "Zeile" + "|" + Str$(Rnd(100 - 1)+ 1)) EndWhile WhileNot ende WaitInput If Clicked(btn1) ClearList lv Sleep 300 Set("MoveListMode", 1) Move("HandleToList", gb) EndIf Case %Key = 2 : ende = 1 EndWhile MoveListProc Parameters String s, int i If Get("MoveListMode") = 1 AddString(lv, s) EndIf EndProc
-
Das bedeutet dann, das sich auch alle Move("ListTo...",...) nachbilden lassen.
Auch Listen gleich in HTML einbauen geht dann einfach; genauer gesagt kann mit diesen Strings alles aufgebaut werden.
Aus Array,Datei,Speicher,String und allen Handle-Listen/-Grids können die Daten kommen. Der Generator sorgt für zeilenweises bereitstellen der Daten.
Code
Alles anzeigenDeclare string html_start, html_end, line_start, line_mid, line_end Declare string Quelle[2] Cls Print "gelistet wird\n" html_start = "<!DOCTYPE html><html><head><meta name=\qviewport\q content=\qwidth=device-width, initial-scale=1\q>" + \ "<style>table {border-collapse: collapse; border-spacing: 0; width: 100%; border: 1px solid #ddd;}" + \ "th, td { text-align: left; padding: 16px;} tr:nth-child(even) {background-color: #f2f2f2}" + \ "</style></head><body><h2>Zebra Striped Table</h2>" + \ "<p>Entliehen aus: https://www.w3schools.com/howto/howto_css_table_zebra.asp</p>" + \ "<p>For zebra-striped tables, use the nth-child() selector and add a background-color to all even (or odd) table rows:</p><table>" + \ "<tr><th>First Name</th><th>Last Name</th><th>Points</th></tr>" html_end = "</table></body></html>" line_start = "<tr><td>" line_mid = "</td><td>" line_end = "</td></tr>" Quelle[0] = "Jill|Smith|50" Quelle[1] = "Eve|Jackson|94" Quelle[2] = "Adam|Johnson|67" MoveListProc Parameters String s, int i Declare string s2 If Get("MoveListMode") = 1 Print SubStr$(s,1,"|"), SubStr$(s,2,"|"), SubStr$(s,3,"|") s2 = line_start $ SubStr$(s,1,"|") $ line_mid $ SubStr$(s,2,"|") $ line_mid $ SubStr$(s,3,"|") $ line_end Print #1, s2 : err = %IOResult EndIf EndProc Declare int err, string Testdatei MkDir "C:\\TEMP" err = %IOResult Testdatei = "C:\\TEMP\\TEMP_HTML_TEMP.html" Assign #1,Testdatei : err = %IOResult Rewrite #1 : err = %IOResult Print #1, html_start : err = %IOResult Set("MoveListMode",1) Move("ArrToList",Quelle[]) Print #1, html_end : err = %IOResult Close #1 : err = %IOResult Print "\nENTER für Ende (es wird mit ShellExec aber noch die HTML-Datei angezeigt)" ShellExec( Testdatei, "open", 5) WaitInput End
und nochmal mit mehr als 3 Datenzeilen, damit es klarer wird
Code
Alles anzeigenDeclare string html_start, html_end, line_start, line_mid, line_end, temp, temp2 Declare string Quelle[52] Cls Print "gelistet wird\n" html_start = "<!DOCTYPE html><html><head><meta name=\qviewport\q content=\qwidth=device-width, initial-scale=1\q>" + \ "<style>table {border-collapse: collapse; border-spacing: 0; width: 100%; border: 1px solid #ddd;}" + \ "th, td { text-align: left; padding: 16px;} tr:nth-child(even) {background-color: #f2f2f2}" + \ "</style></head><body><h2>Zebra Striped Table</h2>" + \ "<p>Entliehen aus: https://www.w3schools.com/howto/howto_css_table_zebra.asp</p>" + \ "<p>For zebra-striped tables, use the nth-child() selector and add a background-color to all even (or odd) table rows:</p><table>" + \ "<tr><th>First Name</th><th>Last Name</th><th>Points</th></tr>" html_end = "</table></body></html>" line_start = "<tr><td>" line_mid = "</td><td>" line_end = "</td></tr>" 'Zu faul zum selbst befüllen, und die Namen wurden im Netz **generiert**. Gesucht durch "list of names". temp = "Jill|Smith,Eve|Jackson,Adam|Johnson,Erick|Grinnell,Elizbeth|Silver,Jordon|Sarkisian,Herma|Beene,Gilberto|Mullenix,Neal|Speed,Jaimee|Mccarthy," + \ "Cherrie|Mcmurry,Rozanne|Eversole,Linh|Schwartzberg,Maxima|Wein,Yuki|Putney,Billie|Claycomb,Lavina|Ungar,Mammie|Bator,Anna|Monteiro,Breann|Traynor," + \ "Lenita|Kula,Ligia|Sherburne,Tijuana|Whitlock,Claretta|Brockwell,Billye|Glymph,Troy|Keown,Ezra|Voll,Inger|Mccraw,Lesha|Eichhorn,Evita|Waybright," + \ "Zack|Taillon,Anjanette|Brien,Paulette|Begum,Elaine|Hartwig,Nick|Briley,Reiko|Martin,Marquis|Knobel,Hal|Mance,Lamonica|Michels,Caroll|Hinson," + \ "Chara|Madrid,Cecile|Beecroft,Robbyn|Velazco,Arvilla|Houlihan,Stacie|Farish,Rosaura|Copper,Quyen|Quinlan,Tomeka|Wilcoxon,Clementina|Cather," + \ "Marth|Brim,Izetta|Goold,Suzanne|Harber,Noella|Passman" Randomize Set("Decimals",0) WhileLoop 0,52 temp2 = SubStr$(temp, &loop + 1, ",") $ "|" $ Str$(Range(rnd(99) + 1,1,100)) Quelle[&loop] = temp2 EndWhile MoveListProc Parameters String s, int i Declare string s2 If Get("MoveListMode") = 1 Print i, SubStr$(s,1,"|"), SubStr$(s,2,"|"), SubStr$(s,3,"|") s2 = line_start $ SubStr$(s,1,"|") $ line_mid $ SubStr$(s,2,"|") $ line_mid $ SubStr$(s,3,"|") $ line_end Print #1, s2 : err = %IOResult EndIf EndProc Declare int err, string Testdatei MkDir "C:\\TEMP" : err = %IOResult Testdatei = "C:\\TEMP\\TEMP_HTML_TEMP.html" Assign #1,Testdatei : err = %IOResult Rewrite #1 : err = %IOResult Print #1, html_start : err = %IOResult Set("MoveListMode",1) Move("ArrToList",Quelle[]) Print #1, html_end : err = %IOResult Close #1 : err = %IOResult Print "\nENTER für Ende (es wird mit ShellExec aber noch die HTML-Datei angezeigt)" ShellExec( Testdatei, "open", 5) WaitInput End
-
Jetzt mitmachen!
Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!