XbpBrowse - Beispiel will nicht [erledigt]

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

Moderator: Moderatoren

Antworten
Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 484
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 94065 Waldkirchen
Hat sich bedankt: 14 Mal
Danksagung erhalten: 5 Mal

XbpBrowse - Beispiel will nicht [erledigt]

Beitrag von Wolfgang_B »

Bin wieder mal frustriert :angry4:

Versuche mich gerade in XbpBrowse einzuarbeiten. Irgendwie habe ich den Eindruck, daß ich zu doof für Xbase++ bin. Wenn ich das Beispiel in der Hilfe übernehme, findet er in der Funktion die Variablen nRecNo und nLAstRec nicht. Wenn ich die dann mit übergebe, kommt nichts vernünftiges raus -> Ein Browse mit dem ersten Arrayelement, und das 20 Mal. Ist irgendwie langweilig. Ws ist denn hier schon wieder falsch?? :(

Beste Grüße
Wolfgang

Code: Alles auswählen

  #include "xbp.ch"
   #include "appevent.ch"

   #PRAGMA LIBRARY( "XPPUI2.LIB" )

   // Global variables for maintaining
   // the data source (array)
   STATIC aData
   STATIC nLastRec 
   STATIC nRecno   

   PROCEDURE Main()

    LOCAL oBrowse
    LOCAL nEvent
    LOCAL oXbp := NIL
    LOCAL mp1  := NIL
    LOCAL mp2  := NIL
    LOCAL oCol
    LOCAL nWidth
    LOCAL oGroup

       // Create group box as backdrop for the browse
      oGroup := XbpStatic():New()
      oGroup:Type    := XBPSTATIC_TYPE_GROUPBOX
      oGroup:Caption := "Inventory"
      oGroup:Create( ,,, {440,250} )

      CenterControl( oGroup )

      // Initialize array data for the browse as well as associated status variables 
      aData    := { {"Magazines",  133, .T.},;
                    {"Newspapers", 15,  .T.},;
                    {"Books",      32,  .T.},;
                    {"Postcards",  833, .F.} }
      nLastRec := Len(aData)
      nRecno   := 1

       oBrowse := XbpBrowse():New( oGroup ) 
      oBrowse:SkipBlock     := {|nSkip,oBrowse| DoSkip(nSkip,oBrowse) }
      oBrowse:GoBottomBlock := {||  nRecno := Len(aData) }
      oBrowse:GoTopBlock    := {||  nRecno := 1 }
      oBrowse:PosBlock      := {||  nRecno }
      oBrowse:PhyPosBlock   := {||  nRecno }
      oBrowse:GoPhyPosBlock := {|n| nRecno := n }

      oBrowse:LastPosBlock  := {|| Len(aData) }
      oBrowse:FirstPosBlock := {|| 1 }
      oBrowse:CursorMode    := XBPBRW_CURSOR_ROW
      oBrowse:UseVisualStyle := .F.
      oBrowse:Create( ,, {20,20}, {400,200},, .F. )

      // Add columns to the browse
      oBrowse:AddColumn( {|| aData[nRecno,1]}, 15, "Publication" )
      oBrowse:AddColumn( {|| aData[nRecno,2]}, 5,  "In Stock" )
      oBrowse:AddColumn( {|| aData[nRecno,3]}, 1,  "Web Shop" )

       oBrowse:HScrollObject:UseVisualStyle  := .T.
      oBrowse:VScrollObject:UseVisualStyle  := .T.

      oBrowse:Show()
      SetAppFocus( oBrowse )

      nEvent := xbeP_None
      DO WHILE nEvent != xbeP_Close
         nEvent := AppEvent( @mp1, @mp2, @oXbp )
         oXbp:HandleEvent( nEvent, mp1, mp2 )
      ENDDO
 
      oBrowse:Destroy()

   RETURN

   ****************************************************************** 
   * Skipper function that moves the record pointer through the
   * data source (array)
   ****************************************************************** 
   FUNCTION DoSkip( nSkip )

    LOCAL nCanSkip

      IF nRecno + nSkip < 1             // "BoF"
         nCanSkip := 1 - nRecno
      ELSEIF nRecno + nSkip > nLastRec  // "EoF"
         nCanSkip := nLastRec - nRecno
      ELSE
         nCanSkip := nSkip
      ENDIF

      nRecno += nCanSkip

   RETURN nCanSkip
Zuletzt geändert von Wolfgang_B am Mo, 23. Apr 2018 19:59, insgesamt 1-mal geändert.
Beste Grüße
Wolfgang

Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
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: XbpBrowse - Beispiel will nicht

Beitrag von georg »

Hallo, Wolfgang -


ich habe Dein Beispiel einfach mal kopiert, in eine Programmdatei gepackt, compiliert und gelinkt, und es funktioniert.

Denkbar als Ursache für Dein Problem wäre, wenn Du die STATIC-Deklarationen dieser Variablen nach Main() verschoben hättest. Da sie (in Deinem Beispiel) vor der ersten Funktion liegen, sind sie in der ganzen Programm-Datei (!) sichtbar. Würden sie innerhalb von Main() liegen, dann könnten andere Funktionen NICHT auf diese Variablen zugreifen.

Kannst Du mal die XppError.log posten?
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 484
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 94065 Waldkirchen
Hat sich bedankt: 14 Mal
Danksagung erhalten: 5 Mal

Re: XbpBrowse - Beispiel will nicht

Beitrag von Wolfgang_B »

Hallo Georg,
steht nichts aufregendes drin ...

Code: Alles auswählen

FEHLERPROTOKOLL von "C:\VWIN\vedasw.EXE" Datum: 23.04.2018 19:28:56

Xbase++ Version     : Xbase++ (R) Version 2.00.570
Betriebssystem      : Windows 8 06.02 Build 09200
VEDASW Version      : 2.20.6.1
Kunde               : ROS
Benutzer            : XXXX
------------------------------------------------------------------------------
oError:args         :
           -> NIL
oError:canDefault   : N
oError:canRetry     : Y
oError:canSubstitute: N
oError:cargo        : NIL
oError:description  : Unknown variable
oError:filename     : 
oError:genCode      :         22
oError:operation    : nRecno
oError:osCode       :          0
oError:severity     :          2
oError:subCode      :       2000
oError:subSystem    : BASE
oError:thread       :          1
oError:tries        :          1
------------------------------------------------------------------------------
CALLSTACK:
------------------------------------------------------------------------------
Aufgerufen von DOSKIP(1949)
Aufgerufen von (B)ARRAY_BROWSE(1907)
Aufgerufen von XBPBROWSE:DOSKIP(2847)
Aufgerufen von XBPBROWSE:FORCESTABLE(1328)
Aufgerufen von XBPBROWSE:HANDLEEVENT(1903)
Aufgerufen von XBPBROWSE:SHOW(4012)
Aufgerufen von ARRAY_BROWSE(1928)
Aufgerufen von (B)TESTSEEMENU(215)
Beste Grüße
Wolfgang

Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 484
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 94065 Waldkirchen
Hat sich bedankt: 14 Mal
Danksagung erhalten: 5 Mal

Re: XbpBrowse - Beispiel will nicht

Beitrag von Wolfgang_B »

Das wars!! Ich dachte immer, daß die Variablendefinition in der jeweiligen Funktion stehen muß. Irgenwie sah das komisch aus, deswegen habe ich diese STATIC-Variabeln verschoben.
Wenn ich richtig interpretiere, verhalten sich die STATIC-Var. ähnlich wie PUBLIC-Var. ...

Danke für den Hinweis. Wieder was gelernt!!!
BEste Grüße
Wolfgang
Beste Grüße
Wolfgang

Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
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: XbpBrowse - Beispiel will nicht

Beitrag von georg »

Hallo, Wolfgang -


dann wirf doch mal ein Auge auf diesen Artikel: Static Variablen
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: XbpBrowse - Beispiel will nicht

Beitrag von brandelh »

Eine STATIC ist eine dauerhafte Lokal, aber bezogen auf den Context.
Wenn die STATIC in einer Funktion steht, dann ist sie wie local nur dort sichtbar, von außen sicher, aber bei jedem Aufruf wie beim letzten ...
SetAppWindow() speichert den parameter sicherlich in einer static in der funktion.

Wenn eine Static in einer Datei außerhalb aller prozeduren und funktionen steht,
dann ist sie in allen Funktionen und Prozeduren in dieser Datei definiert werden sichtbar.
Gruß
Hubert
Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 484
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 94065 Waldkirchen
Hat sich bedankt: 14 Mal
Danksagung erhalten: 5 Mal

Re: XbpBrowse - Beispiel will nicht

Beitrag von Wolfgang_B »

Alles klar. Verstanden. Jetzt wird die Sache logischer.
Danke nochmal, Georg und Hubert
Beste Grüße
Wolfgang

Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
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: XbpBrowse - Beispiel will nicht [erledigt]

Beitrag von AUGE_OHR »

eine STATIC die "oben" vor der ersten Function/Procedure steht nennt man "Fieldwide" STATIC und ist im gesamten PRG "sichtbar".

IMHO ist eine "Fieldwide" STATIC / PUBLIC nicht Threadsafe und es geht auch ohne ... muss mal nach dem Code suchen
gruss by OHR
Jimmy
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: XbpBrowse - Beispiel will nicht [erledigt]

Beitrag von brandelh »

AUGE_OHR hat geschrieben: Mo, 23. Apr 2018 22:16eine STATIC die "oben" vor der ersten Function/Procedure steht nennt man "Fieldwide" STATIC und ist im gesamten PRG "sichtbar".
der richtige Begriff ist filewide also sichtbar in der ganzen Datei, mit Feldern hat das nichts zu tun ;-)
AUGE_OHR hat geschrieben: Mo, 23. Apr 2018 22:16 IMHO ist eine "Fieldwide" STATIC / PUBLIC nicht Threadsafe und es geht auch ohne ... muss mal nach dem Code suchen
ich denke Alaska würde dir da widersprechen ;-)
Die STATIC ist auf jeden Fall threadsave, was bedeutet, dass die Variable als solche (also der Zeiger auf) auch bei konkurierenden Zugriffen nicht zerstört wird.

ABER nur bei read only Anwendung kann man sicher sein, was drin gespeichert wurde.
Schreiben mehrere Threads in die Variable ist die Reihenfolge des Zugriffs nicht eindeutig, somit kann man nicht davon ausgehen, dass das Programm tut was man erwartet.
Welcher Thread zuerst schreibt und somit der Wert gleich wieder überschrieben wird, hängt vom Zufall (Auslastung, Verarbeitungszeit etc.) ab.
Man kann das nutzen, wenn man weiß was man tut und die Threads gegenseitig steuert oder mit SYNC methods arbeitet.
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: XbpBrowse - Beispiel will nicht [erledigt]

Beitrag von AUGE_OHR »

brandelh hat geschrieben: Di, 24. Apr 2018 7:09 der richtige Begriff ist filewide also sichtbar in der ganzen Datei, mit Feldern hat das nichts zu tun ;-)
JA ... FILE muss es heissen.

nun denke ich immer gleich daran das es "mehrfach" genutzt werden könnte was bei CLASS Code ja kein Problem ist.
doch ... ein Problem gab es mit Ivar "im" Codeblock

so meckert der Compiler

Code: Alles auswählen

   ::oBrowse:AddColumn( { || aData[ ::nPosBild, ID_Bild     ] }, 11, "Bild" )
aber so geht es

Code: Alles auswählen

LOCAL oSelf := self
   ::oBrowse:AddColumn( { || aData[ oSelf:nPosBild, ID_Bild     ] }, 11, "Bild" )
und das ist die Array "Skipper" Zeile "all-in-one"

Code: Alles auswählen

//j oBrowse:SkipBlock    := { |nSkip| oSelf:ASkip( nSkip, LEN( aData ), oSelf ) }
//j
//j so kann man ASkip() sparen
//j
   oBrowse:SkipBlock     := {|nSkip| -oSelf:nPosBild + (oSelf:nPosBild := MAX(1, MIN(LEN(aData), oSelf:nPosBild + nSkip))) }
eine Method ASkip() wird nicht gebraucht, Rest wie üblich

Hinweis : oSelf:nPosBild == nRecno
gruss by OHR
Jimmy
Antworten