Abarbeiten von Funktionern in Codeblöcken

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21189
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Manfred »

:lol:
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Sören
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 205
Registriert: Mo, 07. Aug 2006 10:18
Wohnort: Leipzig
Danksagung erhalten: 11 Mal

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Sören »

Hallo Jan,
Jan hat geschrieben:Das ändert dann aber nichts daran, das doch wieder mehr als nur eine Eventschleife im Programm ist. Was aber, wie ich oben schon mehrfach anmerkte, nach meinem Wissensstand eher vermieden werden sollte.
Eine solche Funktion ist m.E. ganz unproblematisch; der aktuelle Eventloop wird kurzzeitige vom Eventloop in der Funktion abgelöst, alle Ereignisse werden abgearbeitet und anschließend wird wieder zum "normalen" Evenloop zurückgekehrt.

Ich benutze das hin und wieder in Fällen ähnlich dem Deinen.
Beste Grüße,
Sören
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von brandelh »

Jan hat geschrieben:Hubert,
worauf genau möchtest Du mit der Aussage hinaus?
Ich habe nie behauptet das nicht eine Funktion nach der anderen abgearbeitet wird. Klar werden die das.
Aber es wird nicht auf das korrekte Ende der vorigen Funktion gewartet. Ich habe das im Debugger gesehen.
Der Code baut den Dialog aus Funktion drei ganz korrekt auf, den kann ich auch auf dem Bildschirm sehen, und dann geht der Code sofort weiter auf das Löschen der XBParts.
So einfach ist das.
Jan
JAN,

ich gebe es auch auf, du widersprichst dir selbst !
Es ist schlicht nicht möglich, dass die 4. Funktion ausgeführt wird, solange die 3. nicht beendet wird :!: :!: :!: :!: :!: :!: :!: :!: :!: :!:
Es mag sein, dass du denkst er sei noch in der anderen Funktion, das kann aber nicht sein.
Erst wenn du das akzeptierst, kannst du den (Gedanken-)Fehler finden.

Ich nutze ein Menüsystem basierend auf dem MDI Beispiel.
Fenster wird gestartet und in die Fensterliste eingetragen.
Nach dem Beenden des Fensters wird es wieder dort ausgetragen.

Deine Funktionen sollen ähnliches machen, gehen aber davon aus, dass der Codeblock in der 3. Funktion wartet bis das Fenster beendet wird.
Und erst dann die 4. und 5. Funktion zum Aufräumen ausführt.
So funktionieren MDI Fenster NICHT !
Nach Aufbau des Fensters wird die aufrufende Funktion beendet und die Kontroll zurück an das Programm - meist die Eventschleife - gegeben.

Ohne Code ist keine Hilfe möglich.
Jan hat geschrieben:worauf genau möchtest Du mit der Aussage hinaus?
Der TITEL des Threads zeigen MIR, dass du daran zweifelst. Das kann ich aber auch falsch verstanden haben ;-)
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von brandelh »

Sören hat geschrieben:Hallo Jan,
Jan hat geschrieben:Das ändert dann aber nichts daran, das doch wieder mehr als nur eine Eventschleife im Programm ist. Was aber, wie ich oben schon mehrfach anmerkte, nach meinem Wissensstand eher vermieden werden sollte.
Eine solche Funktion ist m.E. ganz unproblematisch; der aktuelle Eventloop wird kurzzeitige vom Eventloop in der Funktion abgelöst, alle Ereignisse werden abgearbeitet und anschließend wird wieder zum "normalen" Evenloop zurückgekehrt.
Ich benutze das hin und wieder in Fällen ähnlich dem Deinen.
wenn in der normalen Eventloop nichts besonderes geregelt ist, macht eine zweite gleich aussehende nichts anderes und es ist OK, wenn auch nicht elegant ;-)

ABER wenn in der Main einige Steuerungen enthalten sind, dann wird das problematisch.
Daher lege ich meine EINE Eventschleife in eine Funktion die so heißt wie dein Beispiel und rufe diese Funktion in der MAIN ohne und in langen Schleifen mit timeout auf.
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9361
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Tom »

Ein Codeblock enthält eine Folge von Anweisungen, die nacheinander abgearbeitet werden. Er ist insofern nichts anderes als die Auflistung dieser Anweisungen in Programmzeilen:

Code: Alles auswählen

bBlock := {||Funktion1(),Funktion2()...Funktion6()}
Eval(bBlock)
entspricht:

Code: Alles auswählen

Funktion1()
Funktion2()
...
Funktion6()
Wenn nun scheinbar Funktion2 etwas tut, obwohl noch etwas getan wird, das Funktion1 zugeordnet werden muss, kann man das beispielsweise so erreichen:

Code: Alles auswählen

FUNCTION Funktion1()
LOCAL oThread := Thread()New()
oThread:Start({||Funktion7()})
RETURN nil
Jetzt wird das, was in Funktion7 geschieht, u.U. noch weiter abgearbeitet, obwohl sich Funktion1 längst beendet hat und bereits Funktion2 läuft. Dieses Szenario kann man auch auf anderen Wegen indirekt gestalten. Tatsächlich laufen beispielsweise sämtliche Ownerdrawing-Funktionalitäten im GUI-Thread, und es gibt noch weitere Beispiele für diese immanente Asynchronität.
Herzlich,
Tom
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14653
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Jan »

Da Hubert nicht zu verstehen scheint das ich ihm zur Zeit keinen Code geben kann, und da von mehreren Seiten an dem gezweifelt wird was ich schreibe, möchte ich das Thema ersteinmal beenden. Es nützt nichts, das wir uns hier fast die Köpfe einschlagen, Das ist nicht der Sinn der Sache.

Aber zwei Anmerkungen:
  • Gerade rief mich ein befreundeter Entwickler an, der die Diskussion verfolgt hat. Er erklärte mir, das er genau das gleich Problem auch schon hatte. Und auch hier im Forum gepostet hat. Das aber auf die Schnelle nicht wieder findet. Ich bin also nicht der Einzige mit diesem Problem.
  • Ich habe eine entsprechende Anfrage an Alaska gesendet. Mal sehen was die zu dem Problem sagen.
Eine Bemerkung aber noch zu Tom: Leider ist es eben nicht so. In einer früheren Version wurden die Funktionen nacheinander abgearbeitet. Ich mußte die aber jetzt in Codeblöcke zusammen ziehen. In der vorigen Version hat es funktioniert, in den Codeblöcken nicht. Es hat sich am gesamten Code sonst nichts geändert! Nur das Überführen der Funktionen in den Codeblock.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von brandelh »

Hallo Jan,
Ich hatte deine zwischenzeitliche Mitteilung übersehen, dass du aktuell nicht an den Quellcode kommst, sorry.
Aber ohne geht es halt nicht zu erklären.

Mal ein Beispiel von meinem Code ... ich nutze Classcode, ist aber im Prinzip das Gleiche !

Code: Alles auswählen

im MENÜ
oMenu:addItem( { "~Testfenster" , {|| TestFenster() } } )
im eigenen PRG, Classcode meldet sich in CREATE() selbst bei der Fensterliste an,
das könnte man aber auch in dieser Funktion vor CREATE tun.

Code: Alles auswählen

function TestFenster()
   local oWin
   oWin := _TestFenster():New(RootWindow():drawingArea,RootWindow():drawingArea)
   oWin:Create()
return NIL
Das Austragen darf hier natürlich nicht aufgerufen werden, sonst wäre der Eintrag SOFORT wieder weg !
Das wird hier erledigt:
*---------------------------------------------------------------------------
das ist meine erweiterte Basisklasse, man kann das aber auch als Funktion in den codeblock close legen.

Code: Alles auswählen

METHOD HB_Dialog:close()  // sehr einfache Version, bei spezielleren Anforderungen
   ::destroy()            // sollte diese einfach in den abgeleiteten Klassen
RETURN SELF               // implementiert werden.
*---------------------------------------------------------------------------
METHOD HB_Dialog:destroy()   // wenn die Fensterverweise noch aktiv sind, löschen !
   ...
   IF ! Empty( ::windowMenu )
      ::windowMenu:delItem( self )
      ::windowMenu := NIL
   ENDIF
   ...
   ::XbpDialog:destroy()
return self
DEIN code könnte also so aussehen:

Code: Alles auswählen

im MENÜ
oMenu:addItem( { "~Testfenster" , {|| Vorab1(),Vorab2(),TestFenster() } } )
beim Fenstercode:

Code: Alles auswählen

...
oFenster:close := {|u1,u2,oXbp| NachEnde1(oXbp), NachEnde2(oXbp), oXbp:destroy() }
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von brandelh »

Jan hat geschrieben:Eine Bemerkung aber noch zu Tom: Leider ist es eben nicht so. In einer früheren Version wurden die Funktionen nacheinander abgearbeitet.
Ich mußte die aber jetzt in Codeblöcke zusammen ziehen.
In der vorigen Version hat es funktioniert, in den Codeblöcken nicht.
Es hat sich am gesamten Code sonst nichts geändert! Nur das Überführen der Funktionen in den Codeblock.
Jan
ich kann kein Beispiel erzeugen, bei dem der CodeBlock sich anders verhält als die entsprechnde Funktion.
Falls du dieses Fehlverhalten in einem kleinen Beispiel zeigen könntest, wäre es eine Untersuchung wert ;-)
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9361
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Tom »

Hallo, Jan.

Der Unterschied besteht im Zeitpunkt der Abarbeitung. Code in Slots wird eben dann abgearbeitet, wenn der Slot evaluiert wird, während Code im Code in der Reihenfolge abgearbeitet wird, in der er programmiert ist. Es kann also nur daran liegen, wann und wo und von wem der Codeblock im Slot evaluiert wird.
Herzlich,
Tom
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Herbert »

Tom hat geschrieben: Wenn nun scheinbar Funktion2 etwas tut, obwohl noch etwas getan wird, das Funktion1 zugeordnet werden muss, kann man das beispielsweise so erreichen:

Code: Alles auswählen

FUNCTION Funktion1()
LOCAL oThread := Thread()New()
oThread:Start({||Funktion7()})
RETURN nil
Tom, du nimmst dieses wirre Wort auf :book: Thread angry9:

um auf Jan's Problem zurückzukommen; was macht aMenu[7]? da wird der Code dahinter gestartet.
Grüsse Herbert
Immer in Bewegung...
DelUser01

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von DelUser01 »

Hallo Jan

aus dem gesamte Thema werde ich auch nicht schlau,
aber es könnte sich so anhören wie ein Problem welches ich vor einiger Zeit mal hatte:
Verschiedene Threads welche eigentlich "geordnet" und in gewissem Maße synchronisiert ablaufen sollten taten das einfach nicht. Durch Programmierfehler liefen die unkontrolliert, blieben nie stehen und starteten sich gegenseitig (und mehrfach). CTI/Telefonsystem.
Vielleicht tun Deine Threads einfach auch nicht das was Du von ihnen erwartest?

Wenn das so wäre dann hättest Du genau den Effekt, dass eine Funktion/CodeBlock bereits etwas tut obwohl der vorherige noch nicht voll durchgelaufen ist.
Das liegt aber nicht daran dass die CodeBlöcke tun was sie wollen sondern die laufen in verschiedenen Threads ab und dadurch entsteht der Eindruck des "Durcheinanders".

So etwas in den Griff zu bekommen wenn man nicht selbst "verbrochen" hat stelle ich mir sehr schwierig vor.

Viel Erfolg!

Gruß
Roland
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von AUGE_OHR »

Sören hat geschrieben:

Code: Alles auswählen

  while NextAppEvent() != xbe_None
    nEvent := AppEvent( @mp1, @mp2, @oXbp )
ein xbe_None wird NUR bei einem Timeout gesendet !
gruss by OHR
Jimmy
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von AUGE_OHR »

Jan hat geschrieben:Und wie Herbert ganz richtig schrieb: In meinen eigenen Projekten arbeite ich mit Threads für jede Funktion, habe also auch stapelweise Event-Schleifen. In diesem Kundenprojekt gibt es aber nur den einen Thread, in dem alles passiert. Also nach meinem (theoretischen) Kenntnisstand sollte es auch nur eine Event-Schleife geben. Aber leider funktionieren die Codeblöcke nicht, wenn es nur die eine gibt ...
ein eigener Thread muss nicht unbedingt eine Event-Schleife haben, nur wenn du einen Event abfangen willst.

es muss aber auch keine "Schleife" sein, es reicht evtl. schon ein AppEvent().

wie es mit einer einzigen Event Schleife geht zeigt doch das Demo c:\ALASKA\XPPW32\Source\samples\apps\MdiDemo\MdiDemo.prg
gruss by OHR
Jimmy
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14653
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Jan »

Hallo Roland und Jimmy,

das Programm hat keine Threads! Threads benutze ich in meinen eigenen Programmen, aber dieses Kundenprogramm hat keine (außer die üblichen natürlich).

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14653
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Jan »

So, bevor ich gleich zum ersten Kunden raus muß habe ich mal schnell die Eventschleife von Sören ausprobiert. Leider Null Änderung.

Im Moment hilft also wirklich nur eine Eventlscheife in den aufgerufenen Funktionen ...

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von brandelh »

die Funktion von Sören kann dir nicht helfen, da diese eben nicht blockiert sondern nur die bis dahin aufgelaufenen Events abarbeitet.

Wenn du eine blockierene Event-Loop brauchst und das Programm so aufgebaut ist, dann mach das so.

In MDI Programmen werden normalerweise mehrere Fenster gleichzeitig aufgerufen und dann wird es schwierig.
Dein Programm scheint das nicht zu machen "Fenster, welche Fenster ..." ;-)

Wenn jedes dieser Fenster eine eigene Eventverarbeitung (also die Reaktionen darauf) benötigt,
dann kannst du auch tatsächlich jeweils eine Schleife einbauen, ansonsten ist es besser die EINE Eventloop
in eine Funktion zu packen und dort aufzurufen wo man es nötig hat.

Wenn man dann die Funktion je nach Parameter blockierend oder zeitlich begrenzt durchläuft, reicht eine Funktion für alle Zwecke.
SO BLEIBT MAN BEI EINER SCHLEIFE JE THREAD !

So sieht meine aus:

Code: Alles auswählen

PROC MAIN()
    ... Einstellungen etc. ...
    DoEventLoop()    // kein Paramter => Endlosschleife == Blockierend !
RETURN

*-----------------------------------------------------------------------------
FUNCTION DoEventLoop(nSeconds)               // For Next Schleifen unterbrechen und Events verarbeiten !
   local nBisSeconds, nEvent, mp1:=nil, mp2:=nil, oXbp:=nil, dBis

   DEFAULT nSeconds to 0

   dBis := date()
   nBisSeconds := seconds() + nSeconds

   if nBisSeconds >= 86400                   // Endlosschleife um Mitternacht verhindern
      dBis++
      nBisSeconds := nBisSeconds % 86400
   endif

   DO WHILE .T.
      nEvent := AppEvent( @mp1, @mp2, @oXbp, nSeconds)
      do case
         case nEvent = xbe_None
            * nichts tun ist hier Standard
         case nEvent = xbeP_Keyboard .and. mp1 == xbeK_F1
            * xbeP_HelpRequest erscheinen für jede Xbp Instanz, also zu oft !
            ShowNoHelp()  // in ANW_MENU.PRG
         otherwise
              oXbp:handleEvent( nEvent, mp1, mp2 )
      endcase
      if nSeconds > 0
         if date() = dBis .and. nBisSeconds < seconds()
            exit
         endif
      endif
   ENDDO
return nil
Ich rufe diese in MAIN einmalig auf und ab und zu in langen Verarbeitungsschleifen:

Code: Alles auswählen

nCount := 100
do while Bedingung
   ...
   DoEventLoop(0.01)  // 1/100 Sekunden eventuelle Events verarbeiten.
   ...
enddo

Das braucht man aber nur wenn man nicht sowieso in Threads ausgelagert hat.

PS: damit erkennst du natürlich an, dass die 3. Funktion beendet wird bevor die 4. gestartet wurde ;-)
genau das wollte ich aber immer klarstellen !
Gruß
Hubert
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14653
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Jan »

brandelh hat geschrieben:PS: damit erkennst du natürlich an, dass die 3. Funktion beendet wird bevor die 4. gestartet wurde ;-)
genau das wollte ich aber immer klarstellen !
Hubert,

ich zähl jetzt nicht nach wie oft ich dazu was geschrieben habe. Ich habe sogar noch eine Klarstellung zu dem Thema "Durchgelaufen oder Abgearbeitet" geschrieben. Einfach mal nachlesen, was dort steht.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von brandelh »

Ich gebe gerne zu, dass mir die eine oder andere Antwort nicht mehr aufgefallen ist, weil viele gleichzeitig geantwortet haben (z.B. dass du nicht an den Quellcode kommst),
Als "Klarstellung" finde ich nur das:

das alle fünf Funktionen nacheinander einfach abgearbeitet werden, ohne auf den Abschluß der vorigen zu warten.

und dazu habe ich schon geantwortet, dass sich die Aussagen widersprechen, entweder eine Funktion wird NACH der anderen abgearbeitet (so ist es !)
oder aber eine fängt schon an, bevor die andere fertig ist, das ginge aber nur bei mehreren Threads. Genau dieser Aussage habe ich die ganze Zeit widersprochen.
Wenn es so wäre würde auch ein Wartezustand in der 3. Funktion nichts bewirken.
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9361
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Tom »

Die Frage ist doch, ob wirklich das RETURN der zuerst aufgerufenen Funktion(en) erfolgt ist oder ob diese tatsächlich noch läuft. Tatsächlich nehme ich an, dass es ein RETURN gab, sonst kann die nächste Funktion im Codeblock nicht aufgerufen werden. Das ist eine immanente und verlässliche Struktur, ohne die vieles nicht funktionieren würde. Also muss es daran liegen, dass die Funktion etwas auslöst, das noch läuft, obwohl sich die Funktion geändert hat.
Herzlich,
Tom
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14653
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Jan »

Ich wiederhole also mal, in der Hoffnung, das ich das irgendwie irgendwann mal allgemeinverständlich ausdrücken kann:

Alle fünf Funktionen werden nacheinander abgearbeitet. Punkt. Soweit sind wir uns noch einig. Im Debugger sehe ich, das der Dialog aus der dritten Funktion sauber aufgebaut wird. Aber sobald der aufgebaut wird wird sofort Funktion vier aufgerufen, danach Funktion 5. Der Bildschirm ist also leer, das Menü enabled. Ab die Funktion 3 irgendwo im Hintergrund noch schlummert kann ich nicht sagen. Auf jeden Fall sind alle XBParts des Dialoges destroyed worden.

Jetzt verständlicher?

Und auf jeden Fall ist es so daß wenn ich Funktionen vier und fünf weglasse, alles sauber läuft. Es wird einfach nur nicht aufgeräumt und das Menü enabled. Was auch doof ist. Es funktioniert auch, wenn ich alle fünf Funktionen drin habe, aber in der dritten eine Eventschleife einbaue. Es hat auch funktioniert als die Menüpunkte noch per ID aufgerufen wurden und in der DO CASE-Schleife nach der ID gesucht wurde, und dort alle fünf Funktionen einzeln untereinander standen. Es hakt erst seitdem das alles in den Codeblock überführt wurde. An den Dialogfunktionen hat sich nichts geändert.

Vielleicht ist das Problem wie ich den Codeblock zusammenbaue. Immerhin setze ich den aus Einzelteilen zusammen und werte den per & aus (bevor es Nachfragen gibt: Auf Seite 1 habe ich ein Beispiel gepostet). Ich habe keine Ahnung, wo das Problem liegt. Ansonsten würde ich ja diese ganze Diskussion hier nicht führen.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9361
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Tom »

Hallo, Jan.

So baust Du den Action-Codeblock für das Menü:

Code: Alles auswählen

oMenu:addtextItem(aMenu[i][5], , , &("{|| DisableAlle(), DelChildList(), " + aMenu[i][7] + ", DelChildList(), EnableAlle()}"))
Was geschieht in "AddTextItem" genau? In "AddItem" ist die Action der zweite Parameter, bei Dir aber der vierte. Ist das richtig?

Mach's doch mal so:

Code: Alles auswählen

xBlock := &("{|| DisableAlle(), DelChildList(), " + aMenu[i][7] + ", DelChildList(), EnableAlle()}")
oMenu:addtextItem(aMenu[i][5], , ,xBlock)
Eigentlich aber ist Dein Code richtig - vorausgesetzt, "AddTextItem" macht alles richtig.
Herzlich,
Tom
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14653
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Jan »

Hallo Tom,

das Menü ist von Alaska. Das haben die mal als XbpOfficeMenu auf der DevCon in den USA verteilt. Ich arbeite da regelmäßig mit, ohne Probleme. Allerdings baue ich das Menü normalerweise auch nicht aus einer dbf zusammen.

Ich werde heute Abend mal zwei Vorschläge testen:
  • Deine Idee, den Codeblock erst zusammen zu bauen, und dann in die AddTextItem einzusetzen
  • In den Codeblock nur eine Funktion einzubauen, in der die fünf aufzurufenden Funktionen dann ausgeführt werden. Funktionen 1, 2, 4, 5 sind ja immer gleich, die kann ich hart codieren.
Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von brandelh »

ich denke schon, dass wir der Sache näher kommen.
Die 3. Funktion baut das Fenster zusammen und zeigt es an, dann wird diese beendet, DAS FENSTER aber natürlich nicht !
So wird immer vorgegangen bei GUI Programmen, eine Funktion erzeugt das Fenster und gibt die Kontrolle zurück.

Das Problem fängt nun an, weil JAN mit dem gleichen Codeblock auch wieder aufräumt, aber das dürfte erst nach dem Ende des Fensters ausgeführt werden !

Darum versuche ich ja verzweifelt klarzumachen, dass die Aufräumarbeit NORMALERWEISE in den CLOSE / DESTROY des Fensters muss.

Wenn das warum auch immer nicht geht, muss in der 3. Funktion die Eventloop aufgerufen werden !
Gruß
Hubert
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14653
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von Jan »

Hubert,

ich habe mehrfach wiederholt, was da passiert. Du hast mir aber nicht geglaubt. Ich kann mich auch nicht erinnern das Du geschrieben hast, das die Aufräumarbeiten in die Dialogfunktionen rein müssen (was ich aber auch im Brass überlesen haben könnte, auch ich bin bei Weitem nicht Vollkommen).

Du (und die meisten anderen) hast auch nie geschrieben, das dieses Problem durch den Codeblock kommt. Es hieß immer (auch von Dir): Codeblock und funktionale Aneinanderreihung müssen exakt gleich laufen. Du hast sogar 2x betont, das Du das getestet hattest. Und es immer so ist. Was ja aber nun mal nicht stimmt in dem Konstrukt, das ich gepostet und mehrfach erklärt habe.

Das Problem ist: Ob ich jetzt in jeden Dialog eine Eventschleife einbaue oder das Aufräumen, ist vollkommen egal. Ich muß jede Funktion einzeln anfassen und umschrieben. Das ist natürlich nicht wirklich gewollt.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15696
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Abarbeiten von Funktionern in Codeblöcken

Beitrag von brandelh »

Jan hat geschrieben:Hubert,
ich habe mehrfach wiederholt, was da passiert. Du hast mir aber nicht geglaubt. Ich kann mich auch nicht erinnern das Du geschrieben hast, das die Aufräumarbeiten in die Dialogfunktionen rein müssen
:arrow: http://www.xbaseforum.de/viewtopic.php? ... ead#p89018 (eventuell auch noch weiter vorne).
Ich habe auch immer das Problem mit den zwischenzeitlichen Beiträgen, die werden leider schnell übersehen wenn man auf einen Beitrag antwortet.
Jan hat geschrieben: Du (und die meisten anderen) hast auch nie geschrieben, das dieses Problem durch den Codeblock kommt.
Es hieß immer (auch von Dir): Codeblock und funktionale Aneinanderreihung müssen exakt gleich laufen.
Du hast sogar 2x betont, das Du das getestet hattest.
und dazu stehe ich, mit der Ausnahme, dass nur zur compilerzeit erzeugte Codeblöcke 100% identisch zu funktionnen sind (außer dass sie keinen Namen haben).
Eventuell hängt dein Problem mit &() zur Laufzeit zusammen.

Die Aussage "ich habe dir nicht geglaubt" möchte ich dahingehend ausgelegt wissen, dass ich dir nicht unterstelle die Unwahrheit zu sagen, sondern mir sicher bin,
dass entweder ein Irrtum in der Sache (die Funktion läuft noch...) oder eine unklare Ausdrucksweise dahinter stecken ;-)
Jan hat geschrieben:Du hast sogar 2x betont, das Du das getestet hattest. Und es immer so ist.
Ich habe getestet, das Beispiel mit den MSGBOX()en ... und dir angeraten am Ende deiner funktion jeweils eine einzubauen, damit du siehst, dass sie beendet wird ;-)
Ich habe noch nie einen Unterschied feststellen können !
Jan hat geschrieben:Das Problem ist: Ob ich jetzt in jeden Dialog eine Eventschleife einbaue oder das Aufräumen, ist vollkommen egal.
Ich muß jede Funktion einzeln anfassen und umschrieben. Das ist natürlich nicht wirklich gewollt.
Das kann ich verstehen, aber es macht das Leben nicht leichter ;-)
Hast du nicht selbst geschrieben, dass es vorher mit Funktionen funktioniert hat ?

Was ich dir klar machen wollte ist, dass du an der falschen Stelle nach dem Problem suchst, wenn du davon ausgehst,
dass in einem Codeblock eine Funktion aufgerufen wird, ohne dass die vorhergehende beendet wurde !

Und ohne gegenteiliges Beispiel das ich sehen und prüfen kann, wirst du mich nicht davon überzeugen können dass es so ist ;-)
Gruß
Hubert
Antworten