codeblöcke

Konzeptionelles, Technisches, Termine, Fragen zum Hersteller usw.

Moderator: Moderatoren

Antworten
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

codeblöcke

Beitrag von saul »

Hallo,
in der xbase Hilfe finde ich zu :itemselect
Slot: :itemSelected := {| nItemIndex, uNIL, self | ... }
Im Beispielprogramm SDIDemo

Code: Alles auswählen

oMenu:itemSelected := {|nItem,mp2,obj| MenuSelect(obj, 200+nItem) }
Meine Frage wäre wo und wie die Variablen obj definiert wird. Im gesamten Programmcode habe ich keine Zuweisung gefunden. Setze ich statt obj self ein, so bekomme ich eine Fehlermeldung.
Hat einer eine einfache Erklärung?
Danke

mfg
Wolfgang
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14641
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 87 Mal
Kontaktdaten:

Re: codeblöcke

Beitrag von Jan »

Moin Wolfgang,

Du wirst obj auch nirgends finden. Die Variablen in den Codeblöcken werden automatisch übergeben von der Methode. Die werden Dir also ohne Dein zutun zur Auswertung und Weiterverarbeitung angeboten. Und self kannst Du nur über ::self ansprechen. Ich muß allerdings gestehen, das ich selber das aus purer Gewohnheit nie mache, sondern obj nehme. Oder wie auch immer. Denn Du mußt die nicht obj nennen! Wenn Du da schreibst |x, y, z|, dann kannst Du die im Auswertungsteil mit x, y, und z ansprechen statt wie in dem Beispiel mit nItemIndex, mp2, obj. Will sagen: Die drei Variablen werden so oder so angeboten, egal wie Du die nennst.

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: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: codeblöcke

Beitrag von brandelh »

Jan hat geschrieben:Und self kannst Du nur über ::self ansprechen. ... Will sagen: Die drei Variablen werden so oder so angeboten, egal wie Du die nennst.
sorry, aber so stimmt das nicht, auch wenn JAN es richtig MEINT !

Richtig ist, dass alles was zwischen die | Zeichen eines Codeblocks geschrieben wird innerhalb des Codeblocks als LOCAL Variable zur Verfügung steht:
{| x, y, z, a, b, n1 ... | hier sind das LOCAL-VARs: x, y, z, a, b, n1 ...
Richtig ist auch, dass man grundsätzlich jeden Namen verwenden kann, aber er sollte doch sprechend sein.
Grundsätzlich bedeuted es gibt Ausnahmen und Wechselwirkungen :!:

Schlüsselwörter wie z.B. INPUT etc. sind nicht erlaubt.
SELF / SUPER etc. sind zwar als Variable durchaus erlaubt, aber sie blockieren dann im CodeBlock den Zugriff auf die Basisklasse des Fensters (o.a.):

::IchBinEinControl wird intern so übersetzt: SELF:IchBinEinControl()
Ähnlich wie eine LOCAL bei einer Funktion die darüberliegende PRIVATE ausblendet, würde in diesem Beispiel ein CodeBlock mit SELF im Parameter den Zugriff auf das Fenster blockieren.
Leider sieht man dieses Beispiel öfters in der Doku:
::IchBinEinControl:EinCallbackSlot := {|p1,p2,self| machwas(SELF,p1,p2) }
Von der Syntax korrekt, soll es ausdrücken, dass bei einem Callbackslot dem hinterlegten CodeBlock 3 Parameter übergeben werden. Zwei Variablen mit den eigentlichen Parametern (P1 und P2) und einer Variablen mit der Referenz auf das Objekt selbst (hier steht dann SELF für IchBinEinControl). Solange man nur eine Funktion aufruft und die Werte übergibt, passiert auch nichts weiter.
Sobald man aber nun in dem Codeblock zusätzlich noch auf das Fenster oder andere Controls zugreifen will und :: verwendet wird eben auf die VARIABLE SELF des Codeblocks zugegriffen, also auf das aufrufende Control und nicht auf das Fenster.
::IchBinEinControl:EinCallbackSlot := {|p1,p2,self| machwas(SELF,p1,p2), ::EinAnderesControl:setCaption("...") } // gibt Fehlermeldung unbekannte Variable / Methode
Darum verwende ich immer:
::IchBinEinControl:EinCallbackSlot := {|p1,p2,oXbp| machwas(oXbp,p1,p2) }
aber auch so ist das klar (man sollte es sich aber einfach machen und immer die gleichen Variablen wählen):
::IchBinEinControl:EinCallbackSlot := {|p1,p2,oObj| machwas(oObj,p1,p2) }
Gruß
Hubert
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: codeblöcke

Beitrag von georg »

Guten Morgen, Wolfgang -


eine Codeblock ist ein Stück Code, der zur Laufzeit ausgeführt werden kann. Meist verwendet man ihn, um eine Funktion aufzurufen, man kann aber auch verschiedene Anweisungen darin abarbeiten.

Xbase-Parts führen beim Auftreten bestimmter Ereignisse Codeblöcke aus, und zwar nach dem Schema, das Du zitiert hast:

Code: Alles auswählen

oMenu:itemSelected := {|nItem,mp2,self| MenuSelect(nItem, mp2, self) }
Wenn ein Menüeintrag selektiert wird, führt die Laufzeitumgebung folgenden Code aus:

Eval(self:itemSelected, nItem, mp2, self)

Die Bereitstellung der drei Parameter, die zwischen den beiden |-Zeichen definiert sind, übernimmt also die Laufzeitumgebung. Du brauchst sie daher nicht selbst bereitzustellen.

Jetzt habe ich ein wenig gepfuscht, als ich Dich sinnentstellend zitiert habe, denn der Aufruf lautet anders:

Code: Alles auswählen

oMenu:itemSelected := {|nItem,mp2,obj| MenuSelect(obj, 200+nItem) }
Auffällig ist, dass z.B. mp2 nicht als Parameter an MenuSelect() übergeben wird. Und, dass obj als erster Parameter von MenuSelect() erwartet wird.

Die Codeblock-Definition sagt aus:
  • nehme den dritter Parameter, den Eval() erhält, und übergebe ihn als ersten Parameter an die Funktion MenuSelect();
  • nehme den ersten Parameter, den Eval() erhält, und addiere 200 auf diesen Wert und übergebe ihn als zweiten Parameter an die Funktion MenuSelect()
Denkbar ist auch, dass Du zusätzlich eigenen Parameter an die Funktion übergeben kannst:

Code: Alles auswählen

oMenu:itemSelected := {|nItem,mp2,obj| MenuSelect(obj, 200+nItem, dHeute, nAntwortzeit) }
In diesem Fall müssen die beiden Felder dHeute und nAntwortzeit in Deinem Programmcode definiert sein, sonst erhältst Du zur Laufzeit eine entsprechende Fehlermeldung.


Und dann möchte ich den beiden Vorredner noch was sagen:

Der Versuch, in MenuSelect() über ::self zu arbeiten: das wird nicht funktionieren. Ganz gewiss nicht. Und die Parameter, die zwischen | aufgelistet sind, sind nur dann in der aufgerufenen Funktion verfügbar, wenn sie auch in den () aufgeführt werden. mp2 wirst Du in MenuSelect() nicht ansprechen können, da es in der Codeblock-Definition nicht an MenuSelect() übergeben wird.
Zuletzt geändert von georg am Fr, 07. Mär 2014 7:54, insgesamt 1-mal geändert.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: codeblöcke

Beitrag von brandelh »

georg hat geschrieben: Und dann möchte ich den beiden Vorredner noch was sagen:

Der Versuch, in MenuSelect() über ::self zu arbeiten: das wird nicht funktionieren. Ganz gewiss nicht. Und die Parameter, die zwischen | aufgelistet sind, sind nur dann in der aufgerufenen Funktion verfügbar, wenn sie auch in den () aufgeführt werden. mp2 wirst Du in MenuSelect() nicht ansprechen können, da es in der Codeblock-Definition nicht an MenuSelect() übergeben wird.
Hallo Georg,

da der Titel oben CODEBlÖCKE lautet, habe ich die grundsätzliche Bedeutung der Parameter und die Gefahr des Ausblendens von SELF erklärt.
Selbstverständlich wird eine aufgerufene Funktion nur auf die Parameter zugreifen können die man dieser auch übergeben hat, aber der Codeblock kann mehr Parameter aufnehmen als z.B. nur die Drei.
So kann man sich selbst - wenn es nötig ist - lokale Parameter im Codeblock zur Verfügung stellen.
Gruß
Hubert
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: codeblöcke

Beitrag von georg »

Hallo, Hubert -


der Titel mag zwar Codeblöcke sein, es ging aber um eine ganz spezielle Frage, nämlich, was mit den Prototypen ist, die zwischen den |-Zeichen definiert sind.

Und wenn MenuSelect() wie hier definiert ist, dann sind die im Codeblock definierte Werte auch keine LOCALs:

Code: Alles auswählen

FUNCTION MenuSelect
   PARAMETER oMenu, nValue
Ich halte es für gefährlich, aus dem eigenen Programmierstil Rückschlüsse auf den anderer zu ziehen (ich gebe Dir recht, ich definiere meine Parameter auch als LOCALs durch die () hinter dem Funktionsnamen). Aber es geht auch anders.

Aber die Frage bezog sich eindeutig auf die Prototypen im Codeblock, und wo sie herkommen.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: codeblöcke

Beitrag von brandelh »

Hallo Georg,

ich schließe nicht von meinem Programmierstil auf falsche Aussagen über ...
Deine Ausführungen zu PRIVATE und CODEBLOCK sind schlicht falsch :!:

Richtig ist, dass wenn man eine eigene Funktion wie du es beschrieben hast deklariert, dann wird diese die Parameter als PRIVATE Variablen weiter verwalten:

Code: Alles auswählen

FUNCTION MenuSelect
   PARAMETER oMenu, nValue // diese Parameter sind AB HIER PRIVATE !
Die Parameter eines CODEBLOCKS in | | definiert sind immer LOCAL im CodeBlock.
Die Parameter einer Funktion zwischen den ( ) definiert sind immer LOCAL in der Funktion.

Wenn man die beiden Beispiele kombiniert, werden die Variablen im Codeblock immer LOCAL bleiben, erst in der Funktion werden sie dort zu PRIVATES :!:
Wobei die Verwendung von PRIVATES hier schon eine blöde Idee wäre :!:

PS: MenuSelect() hielt ich zuerst für eine Xbase++ Funktion ... man wird älter ;-)
Gruß
Hubert
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: codeblöcke

Beitrag von georg »

Hallo, Hubert -


kannst Du mir mal zeigen, wo ich nachlesen kann, dass die Werte in der Codeblock-Deklaration LOCALs sind?
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: codeblöcke

Beitrag von brandelh »

saul hat geschrieben:Hallo,
in der xbase Hilfe finde ich zu :itemselect
Slot: :itemSelected := {| nItemIndex, uNIL, self | ... }
Im Beispielprogramm SDIDemo

Code: Alles auswählen

oMenu:itemSelected := {|nItem,mp2,obj| MenuSelect(obj, 200+nItem) }
Meine Frage wäre wo und wie die Variablen obj definiert wird. Im gesamten Programmcode habe ich keine Zuweisung gefunden. Setze ich statt obj self ein, so bekomme ich eine Fehlermeldung.
Hat einer eine einfache Erklärung?
Danke

mfg
Wolfgang
aber gehen wir genauer auf die Frage ein ...
in der xbase Hilfe finde ich zu :itemselect
Slot: :itemSelected := {| nItemIndex, uNIL, self | ... }
leider ist das so, aber SELF als Variablennamen zu verwenden ist schlicht DÄMLICH :!: - auch wenn es Alaska getan hat :!: :badgrin:
Meine Frage wäre wo und wie die Variablen obj definiert wird.
DEFINIERT, also dem Codeblock als LOCAL Variable zur Verfügung gestellt wird es genau in dieser Zeile:

Code: Alles auswählen

oMenu:itemSelected := {|nItem,mp2,obj| MenuSelect(obj, 200+nItem) }
Ein Callback Codeblock wartet bis er aufgerufen wird :arrow: Grundlagen der Programmierung :arrow: Dialogkonzepte etc.
Zur Laufzeit klickt nun jemand auf das Menü, was in Windows einen Event erzeugt, der in der Eventloop landet:

Code: Alles auswählen

   nEvent := xbe_None
   DO WHILE nEvent <> xbeP_Close
      nEvent := AppEvent( @mp1, @mp2, @oXbp )   // hier wird Windows AppEvent() aufrufen und dieses füllt die Parameter aus: oXbp enthält das Objekt, das den Event ausgelöst hat.
      oXbp:handleEvent( nEvent, mp1, mp2 )  // das Objekt selbst bekommt hier mitgeteilt, dass ein Event aufgetreten ist und übergibt die Parameter.
   ENDDO
Die Methode :handleEvent() wird im obigen Beispiel also den Event itemSelect erhalten haben und prüft ob in der Instanzvariablen mit gleichem Namen ein Codeblock hinterlegt ist.
Wenn JA, wird dieser ausgeführt, intern vermutlich mit EVAL( ::itemSelected , mp1, mp2, SELF ) hier ist dann auch SELF wieder korrekt, da es das Objekt selbst übergibt.
Zuletzt geändert von brandelh am Fr, 07. Mär 2014 8:43, insgesamt 3-mal geändert.
Grund: Ich war mit den CODE und QUOTE Tags durcheinander geraten, nun ist es besser lesbar
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: codeblöcke

Beitrag von brandelh »

georg hat geschrieben:Hallo, Hubert -
kannst Du mir mal zeigen, wo ich nachlesen kann, dass die Werte in der Codeblock-Deklaration LOCALs sind?
gerne, ich muss es aber auch suchen ... es ist schon so lange her ;-)

In der Hilfe suchen nach CODEBLOCK, dann ... kann man viele Seiten durchsuchen, besser so :

:arrow: Sprachelemente und Sprachreferenz
:arrow: :arrow: Operationen und Operatoren für komplexe Datentypen
:arrow: :arrow: :arrow: Operationen mit Codeblöcken

gut versteckt also, bei der allgemeinen Definition steht es nicht.
Codeblock-Parameter und Rückgabewert
...
Innerhalb der beiden Zeichen | | können bei der Definition eines Codeblocks Parameter definiert werden, in denen ein Codeblock Argumente von der Funktion Eval() erhalten kann.
Das ist analog zu der Definition formaler Parameter bei einer benutzerdefinierten Funktion oder Prozedur.
Bei den Codeblock-Parametern handelt es sich um LOCAL-Variablen, die erst zur Zeit der Ausführung eines Codeblocks existieren und nur innerhalb des Codeblocks sichtbar sind.
Gruß
Hubert
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: codeblöcke

Beitrag von georg »

Hallo, Hubert -


ja, das macht Sinn - aber in einem anderen Zusammenhang.

Wenn wir von Codeblöcken reden, wie wir sie in dem Beispiel von Wolfgang haben, macht die Aussage mit LOCAL gar keinen Sinn ... Denn wir haben nur einen Prototypen, wie welche Parameter an eine Funktion zu übergeben sind.

Sinn macht es dann, wenn wir Codeblöcke haben, die Programmcode abbilden, der nicht nur aus dem Aufruf einer Funktion besteht:

Code: Alles auswählen

FUNCTION Main()
   Local bBlock
   Local nEins, nZwei, nDrei

   bBlock := {|nEins, nZwei| nDrei := Max(nEins, nZwei), nDrei *= 5}
   nEins := 10
   nZwei := 20
   nDrei := Eval(bBlock, nEins, nZwei)
   ?nDrei
   nDrei := Eval(bBlock, 5, 7)
   ?nDrei
   WAIT
RETURN (.T.)
Hier macht die von Dir zitierte Stelle Sinn, da die Codeblock-Parameter in entsprechenden Aufgaben verwendet werden. Dass sie bei der Übergabe an eine Funktion ebenfalls LOCAL sind, ist höchstens von akademischen Interesse, bzw. hat keine Auswirkung im Programm.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: codeblöcke

Beitrag von brandelh »

Hallo Georg,

dass ich so auf LOCAL / CODEBLOCK rumreite liegt daran, dass für die meisten zwar die Bedeutung klar ist - und auch ich drücke mich nicht immer sauber aus ;-) - aber gerade Anfänger unheimlich Probleme damit haben.

In diesem Beispiel fragt er genau danach um es zu verstehen, daher finde ich es hier wichtig exakt zu schreiben was wichtig ist.

Natürlich spielt es bei einem einfachen Codeblock nicht die wichtige Rolle, aber die Regel bleibt immer die Gleiche.
Wenn ich z.B. keine Parameter angebe, kann ich im Codeblock nicht darauf zugreifen.
Nur weil die Callback Codeblöcke von Xbase++ so aufgerufen werden ... { | p1, p2, oObj | ... } bedeutet das nicht, dass man nicht noch mehr Parameter angeben darf wenn man im Codeblock noch mehr LOCALs braucht:

o:einCallbackSlot := { | p1, p2, oObj, meinP | ... } ... Xbase beschreibt p1, p2 und oObj, aber im Codeblock gibt es meinP, das am Anfang NIL ist aber z.B. für Zwischenergebnisse genutzt werden kann.
Dass sie bei der Übergabe an eine Funktion ebenfalls LOCAL sind, ist höchstens von akademischen Interesse, bzw. hat keine Auswirkung im Programm.
Ich finde schon dass man das Verhalten und die Sichtweise der verschiedenen Typen verstanden haben muss !
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: codeblöcke

Beitrag von brandelh »

Ich suche gerade krampfhaft nach einem Beispiel mit den zusätzlichen Parametern, das auch Sinn macht ... ;-)

hier z.B. braucht Xbase++ beim Aktionscodeblock (2. Parameter) selbst keine Pameterangabe, da diesem nichts übergeben wird.

Ich möchte aber eine Auswahlliste dazwischen bauen und das Ergebnis anzeigen:

Code: Alles auswählen

oMenu:addItem( { "~Auswahlliste-Fenster" ,;
          {|aTmp| ;  // aTmp ist im Codeblock LOCAL und noch NIL !
             aTmp := Auswahlliste({"Zeile 1","Zeile 2","Zeile 3 - äöü ÄÖÜ ß @ €"},"Test Auswahlliste"),; // eigene Funktion zeigt Auswahlliste in Fenster an und gibt Auswahl zurück. 
             msgbox(var2char(aTmp),"Rückgabe") } } )  // mit der MsgBox() zeige ich die Rückgabe an, var2char() wandelt alles in Text um.
Wenn es komplexer wird, ist es aber sinnvoller das Ganze in eine Funktion auszulagern.

oder dieses Monster aus meinem Beispielprogramm für meine Programmumgebung:

Code: Alles auswählen

oMenu:addItem( { "JaNeinBox()"  , {|| msgbox("Auswahl: "+JaNein(JaNeinBox("Ja oder Nein wählen", "Ja oder Nein")),"Ja oder Nein (.t./.f.)" ) } } )
ist nicht unbedingt leicht lesbar - dient ja auch nur mir für die Tests, das könnte man in eine Funktion legen oder aber Zwischenergebnisse generieren.

Code: Alles auswählen

oMenu:addItem( { "JaNeinBox()"  , {|wahl| wahl := JaNeinBox("Ja oder Nein wählen", "Ja oder Nein") ,;
                                                                   msgbox("Auswahl: "+JaNein(wahl),"Ja oder Nein (.t./.f.)" ) } } )
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: codeblöcke

Beitrag von AUGE_OHR »

hi,

wenn wir von den Parameter eines Codeblock zwischen den || ( Pipe ) reden sollten wir unterscheiden zwischen eigenen
und den von XbParts welches eigentlich Callback Slots sind.

XbParts sind ja Windows Controls. Windows arbeitet mit Events. eine Windows Event loop sieht nun so aus

Code: Alles auswählen

METHOD Xbp_wndproc(hWnd,nMsg,wp,lp)
...
   DO CASE
       CASE nMsg = WM_* // WM_ Konstenten
          ...
       CASE nMsg = WM_NOTIFY
          ...
          // Codeblock evaluieren und an Xbase++ zurück geben
          RETURN Eval(bBlock, Self , wp , lp )
wenn ich also unter Xbase++ eine Aktion auslöse bekommt Windows einen Notify Event.
um das "Ergebnis" nach Xbase++ zurück zu bekommen wird der Codeblock im GUI Thread evaluiert und die Parameter zurück gegeben.
die Reihenfolge der Parameter wird dabei umgekehrt sodass wir |mp1,mp2,self| unter Xbase++ haben.

Ein Beispiel für "echte" Callback Slots wären o:measureItem und o:drawItem welche man für Ownerdraw (z.b. Menu) verwendet.

Code: Alles auswählen

INLINE METHOD My_MEASUREITEM(wp,lp)
...
   ::oMeasureitemstruct:_link_(lp,.F.)

      IF VALTYPE( ::bMeasureItem ) == "B"
         ::aDims := { ::oMeasureitemstruct:itemWidth ,;
                      ::oMeasureitemstruct:itemHeight  }
         //
         // now "send" it to Xbase
         //
         EVAL(::bMeasureItem, ::oMeasureitemstruct:itemID , ::aDims , Self)

         RETURN
      ELSE

         cCaption    := ::GetItem(::oMeasureitemstruct:itemID)
         aTextSize   := ::GetTextExtentPoint(cCaption)

         ::oMeasureitemstruct:itemWidth  := aTextSize[1]
         ::oMeasureitemstruct:itemHeight := aTextSize[2]
      ENDIF

REUTRN { ::oMeasureitemstruct:itemWidth, ::oMeasureitemstruct:itemHeight }
gruss by OHR
Jimmy
Antworten