Snel data ingeven met een tekstgebied (TextArea)

Gambas2 TextArea Input, leeg (screenshot)

Tekstgebied voor invoer

Als je op een scherm (Form) data laat ingeven moet je altijd een compromis zoeken tussen

  1. efficiëntie van de input
  2. controle van de input

Door punt “controle” zou je geneigd kunnen zijn meer aparte tekstvelden te gaan gebruiken, waarvan je telkens de invoer controleert. Waarbij de gebruiker, om zijn hele invoer te kunnen doen, dan wel telkens van veld moet veranderen (indien: implementeer TAB mogelijkheid!).

Een tekstgebied (TextArea), dat je eventueel “in de hoogte” vormgeeft, laat toe snel opeenvolgende woorden (zinnen) in te geven, hier vooral een reeks onder elkaar dus.

Ik laat de gebruiker achtereenvolgens de invoer doen, en op het moment dat hij het tekstgebied verlaat, doe ik de controle en geef feedback. Daarvoor worden de regels van het tekstgebied gesplitst in “zinnen”, die elk als één invoer beschouwd worden.

Gambas2 TextArea Input End (screenshot)

Na drie lijnen invoer, een enter, en nog een…

PUBLIC SUB doImportClassValues()

  DIM sLine AS String
  DIM hArrStr AS NEW String[]
  hArrStr = Split(txaeClassNames.Text, gb.NewLine) 
  
  setState(cAdd)
  
  FOR EACH sLine IN hArrStr
    doCheckSave(sLine)
  NEXT 
  

Om het toetsenbord niet te moeten verlaten bij het einde van de invoer, tel ik twee achtereenvolgende “volgende regel” (enter/return) als teken om te stoppen: gebruiker heeft een lege regel ingevoerd, en daarna nog één. Dat is het teken voor “klaar”, de verwerking van de invoer wordt gestart.

Om gemakkelijk toegang te geven tot de invoer in het tekstgebied gebruik ik bv een dubbelklik op het tekstgebied.

De teller voor het aantal enters is vooraf hoger gedefinieerd als
PRIVATE $iLastEnter AS integer

De toets voor enter/return wordt zo getest en geteld:

PUBLIC SUB txaeClassNames_KeyPress()
'
  IF Key.Code = Key.Enter OR Key.Code = Key.Return
    INC $iLastEnter 
    IF $iLastEnter = 2
      doCheckSaveValues(txaeClassNames.Text)
      $iLastEnter = 0
    ENDIF 
  ELSE 
    $iLastEnter = 0
  ENDIF 
'
END

Inputbox

Gambas InputBox

Snel data laten ingeven vanuit code

De inputbox komt niet voor in het menu rechtsonder, bij de tabbladen Form of Container, en daardoor zou je deze functie over het hoofd kunnen zien.

Ze is handig om vanuit code snel invoer toe te laten, omdat je het antwoord onmiddellijk als waarde terugkrijgt.

De tekst die weergegeven moet worden als vraag om invoer of als verklaring, wordt als parameter meegegeven.

Op dezelfde manier kan (optioneel) een titel voor het venster gegeven worden.

Ook optioneel is een “standaardwaarde”, wat wil zeggen dat ze vooraf ingevuld wordt;

teruggeefwaarde = InputBox("Geef een getal (in cm) van 1-999 ", "Lengte-invoer", "***")

Er kunnen zowel cijfers als letters ingegeven worden, dus invoer controleren!

De tekst met de vraag binnen het venster, kan opmaak kenmerken meekrijgen:

InputBox("Geef een getal <em>(in cm)</em> <br> <font color='darkgreen'>van 1-999</font>", "Lengte-invoer", "***")

Opgelet; de sterretjes betekenen hier niet ‘onzichtbare ingave’ zoals voor “wachtwoord”.

Het PaxHeaders spook / PaxHeaders Ghosts

PaxHeaders Ghosts (NL: Het PaxHeaders spook …)

Suddenly, the packages that I make with Gambas2 seem to be much bigger than before. If I examine (look into the tar.gz files with Konqueror), they seem to contain the compiled .gambas file, which has landed in the source directory some moment; so I remove that. But also I found some mysterious “PaxHeader” directories. These always end with a 4 digit number, that becomes bigger at every creation. This can be reproduced by making an new project, and create a package from within the Gambas2 IDE. One example of a directory that appears is:

PaxHeaders.5028

This occurs for me on OpenSuse 12.2 Mantis, with Gambas2 (2.24), on openSUSE Linux kernel 3.4.47-2.38-desktop.

On this moment I don’t see anything mentioned on the gambas-user list, I suppose it has nothing to do with gambas itself. One mention I found is on a KDE list.

You can “see” this gosts with Konqueror, but not with Ark of with Dolphin. Maybe Konqueror sees something that is not there? (or the other way around in Ubuntu?)

Might be corrected with an openSUSE update soon…


Het PaxHeaders spook

Op een bepaald moment ontdek ik dat de tar.gz bestanden die gemaakt worden vanuit de Gambas2 IDE veel groter geworden zijn. Met KDE’s bestandsbeheerder zie ik dat er een .gambas inzit, wat staat voor het gecompileerde programma. Dat is in de source directory terechtgekomen, en wordt zo als bestand mee in het pakket opgenomen; ik verwijder het uit de broncodemap.
Ik merkte echter ook dat er in de .tar.gz een aantal eigenaardige directories zitten.
Ze hebben een naam die begint met PaxHeader en eindigen met een 4-cijferig nummer, zoals bv

PaxHeaders.5028

Het komt voor op de huidige OpenSuse 12.2 Mantis, with Gambas2 (2.24), on openSUSE Linux kernel 3.4.47-2.38-desktop.

Je “ziet” het ook alleen met Konqueror, niet met Ark of met Dolphin, wat er misschien op wijst dat Konqueror iets weergeeft dat er helemaal niet is?

Vermoedelijk ligt het anders aan KDE of de onderliggende bibliotheken die gebruikt worden om de bestanden in te pakken.

Ik hou in de gaten of er updates zijn, en wanneer het verholpen is…


update 5/9; dit zou een verklaring kunnen zijn (hoewel omgekeerd tussen konqueror en dolphin): een bug in de bestandsbeheerder die enkel een foute weergave doet; hier vermelding bij Ubuntu, een andere distributie, die ook met KDE werkt:


…show misleading PaxHeader..

Version: (using KDE 4.3.0)
Installed from: Ubuntu Packages

Some tar files created in KDE 4.3 from within Dolphin’s context menu do not
show their contents properly. When clicking on them to show them as a folder,
they have some PaxHeader folders inside and these have the wrong directory
structure. However, when deflating the tar.gz file the resulting directory is
in fact as it should be. Therefore, it is only the Dolhin view mode that is
bugged, not the creation or deflation of the tar.gz files.

Parameters doorgeven

Parameters tussen haakjes

Parameter passing of parameters doorgeven naar een procedure, functie (of een klasse) gaat door ze tussen gewone ronde haakjes te zetten:

procedure1(string1, string2)

resultaat = functie1(parameter1, parameter2)

De parameters kunnen getallen, tekst enz. zijn, afhankelijk hoe ze gedeclareerd zijn in de procedure.

Bv in de FMain form toon je het resultaat in een TextLabel1:

TextLabel1.Text = produkt(15, 3)

De procedure kan er zo uitzien:

PUBLIC SUB produkt(i AS INTEGER, j AS INTEGER)
   RETURN i * j
END

Een array als parameter

Het wordt een beetje ingewikkelder als je geen gewone parameters (integer, float, string..) wil geven, maar een “hoger” type, als een array.

Stel dat de klasse er zo uitziet:

PUBLIC SUB _new(ArrayOfParameters AS VARIANT)
   iNumberOfParameters = ArrayOfParameters.Count
   myParameters = ArrayOfParameters
END

En volgende methodes bevat:

PUBLIC SUB getParameters() AS Integer
   RETURN myParameters.Count
END

PUBLIC SUB getParameter(i AS Integer) AS Float
   RETURN myParameters[i]
END

De aanroep kan dan zo gebeuren (code van FMain):

PUBLIC arrFloats AS NEW FLOAT[]
PUBLIC hClass AS CReceiver


PUBLIC SUB _new()
   arrFloats.Add(1.1)
   arrFloats.Add(1.3)
   arrFloats.Add(2.4)
'
   hClass = NEW CReceiver(arrFloats)
END

PUBLIC SUB Form_Open()
   SpinBox1.MaxValue = arrFloats.Count - 1
   SpinBox1.Value = SpinBox1.MaxValue
END

PUBLIC SUB Button1_Click()
   TextLabel1.Text = hClass.getParameters()
END

PUBLIC SUB Button2_Click()
   TextLabel2.Text = hClass.getParameter(SpinBox1.Value)
END

Code voor groep van controls: group en tag

Controls op het scherm (en sommige andere objecten) hebben een “tag” eigenschap, die je zelf kan gebruiken naar eigen goeddunken. Een aantal controls in een container of group kunnen herkend worden aan de waarde van de tag property. Zo kan je alle “child” objecten van een container doorlopen tot je de gewenset “tag” inhoud vindt. Dat kan zowel een string als een getal of eender welke ” variant” zijn. Ps: Een timer heeft geen “tag”, een Form wel.

Bij een Form kan je de tag gebruiken om een toestand bij te houden, bv add/edit/saved mode.

Wil je dezelfde “event handlers” gebruiken voor een aantal controls, dan kan je ze in een group opnemen. In de eigenschappen staat de group bovenaan, onder de control (Class) en (Name): (Group).

Stel dat je 12 knoppen op je scherm hebt, die je allemaal als Group “grpKnoppen” hebt gegeven. Dan kan je:

PUBLIC SUB grpKnoppen_Click()
  
  Message.Info("Knop geklikt: " & LAST.Name)
  
END

Je kan verschillende objecten in dezelfde groep steken, en dan kan je voor alle de Tag eigenschap (of Name, Text, …) gebruiken.
Maar je moet er wel op letten dat de eigenschap die je aanspreekt bestaat (desnoods op object type controleren in je code).
bv grpObjecten:

PUBLIC SUB grpObjecten_Click()
  
  Message.Info(LAST.Name & "; " & LAST.Text & "; Tag:" & LAST.Tag)
  
END

In de Tag kan je een verwijzing bewaren, bv

  • index van een Array met andere waarden
  • record id van een record uit een database (via result set bv)

Je kan ook gebruik maken van een container waarin de objecten zitten (bv Frame1 dat Buttons bevat), en die je kan aflopen als “enumerated type”:
Als je een ListBox1 op je Form hebt kan je zo de objecten oplijsten:

PUBLIC SUB showAllChildren()
  
  DIM hObject AS Object
  
  FOR EACH hObject IN Frame1.Children
    ListBox1.Add(hObject.Name & ": " & hObject.Tag, 0)
  NEXT 
  
END

Klik en sleep

Dit is het meest minimale voorbeeld van klik en sleep of drag’n drop: je sleept een tekst van de linkse tekstbox naar het rechtse tekstlabel

Schermafbeelding Kleinste klik en sleep voorbeeld

Schermafbeelding Kleinste klik en sleep voorbeeld

Je hebt twee objecten nodig (zie schermafbeelding), en de volgende code in FMain.Form :

Van tekstbox …

PUBLIC SUB TextBox1_MouseDrag()
  IF Mouse.Left
    TextBox1.Drag(TextBox1.Text)
  ENDIF 
END

naar tekstlabel:

PUBLIC SUB TextLabel1_Drop()
  TextLabel1.Text = Drag.Data
END

Het voorwerp dat ontvangt moet de eigenschap voor ontvangen van “drop” ingesteld hebben.
Dat kan zowel in de schermontwerper bij eigenschappen, als in code (bv bij openen venster):

PUBLIC SUB Form_Open()
  TextLabel1.Drop = TRUE
END

Wat je nog extra kan doen:

  • Oorspronkelijke tekst laten verdwijnen bij slepen van ..
  • Icoon van het gesleepte tonen terwijl het slepen doorgaat (meestal als je een beeldje sleept).
  • Andere dingen (als waarde opslaan in buffer, teller verhogen enz)
  • Na “drop” het object afsluiten*: in PUBLIC SUB TextLabel1_Drop() regel toevoegen met TextLabel1.Drop = FALSE

* (26/6/2014 correctie: afsluiten voor nieuwe drop natuurlijk door de waarde FALSE, niet TRUE zoals er eerst stond).

Gambas voorbeeld-programma’s

Hier een heel lijstje, waaronder

  • labTimer, een programma voor analoge fotografie, met een timer voor de fotograaf; ontwikkel, fixeer en spoelbewerkingen.
  • dbLogger, een programma voor radio-amateurs, om te loggen
  • Xjig Puzzle Manager, een programma om puzzels te maken met xjig ( http://sourceforge.net/projects/xjig/ ; soort digitale zaag om foto’s in puzzelstukjes te zagen voor Linux-X11-systeem).

Engelstalig:
http://freecode.com/tags/gambas

En hier veel handige voorbeeldjes als LIFO en FIFO (buffers in/uit), ping, tekstmanipulatie, tekenen, FTP, enz.
Spaanstalig!
http://sologambas.blogspot.com.es/2012/08/haciendo-ping-en-gambas.html

Gambas 3 <> Gambas 2

Gambas2-Gambas3 incompatibiliteit
Gambas2 code is niet volledig compatibel met Gambas3 code, je kan die niet zomaar draaien. In de ontwikkeling van Gambas2 werd al aangegeven welke dingen zouden gaan verdwijnen (bv. “backcolor”).

Omzetten Gambas2-Gambas3
Bij het openen/importeren van een Gambas2 programma in Gambas3 zorgt de IDE voor het converteren van het Gambas2 naar een Gambas3 programma. Dat verloopt “redelijk” goed.

Behalve…
Volgende problemen heb ik gehad
normaal hebben ze te maken met het verschil tussen de twee versies, tenzij er toevallig echte bugs tussen zitten; zowel van de code als van de gambas-versie.

Voorbeelden:

backcolor, forecolor
De eigenschap van “BackColor” bestaat niet in Gambas3; te vervangen door “Background”.
Gridview_Cell.BackColor -> Gridview_Cell..Background
Gridview_Cell.ForeColor -> Gridview_Cell.Foreground

Hetzelfde voor ForeColor -> ForeGround

HSplit instellingen
Het bewaren en terug ophalen van waarde van een HSplit container.
(foutmelding op string: “Type mismatch: wanted Integer[], got String instead” bij ophalen Setting)
HSplit1.Settings = Settings[“Screen/Spitter”, “150,600,300,160”]
(dit effect verdween nadat de settings file gekopieerd werd naar deze computer – de fout zit dus in de alternatieve waarde-string; mogelijk bug van dit programma.)
Gevonden in een artikel op de mailinglist:
– bewaar:
Settings["Screen/HSplit1.Layout"] = HSplit1.Layout
– ophalen:
HSplit_Main.Layout = Settings["Screen/HSplit1.Layout"] = HSplit1.Layout
Dit werkte, en in de config file wordt het
Splitter.Layout=[0, 160, 780, 470, 470]
in plaats van:
Splitter="0, 160, 780, 470, 470"

Database connection open?
empty result set retrieving data from mysql/mariadb… “connection is not opened”
Opgelost met het toevoegen van een “TRY $hCon.Open”
(niet onderzocht waar het verschil tussen 2 en 3 hier zit).

Text cursor positie
Hier niet helemaal zeker van wat 2 betreft, maar ik ondervond dat ik de cursor zelf bovenaan moet zetten in 3.
TextArea1.Pos = 0

Gambas 2 op openSUSE 11.4

Door omstandigheden moet ik Gambas2 op een nieuwe openSUSE 11.4 installeren, op het randje (over eigenlijk) van de levensduur van deze distributie. Onmiddellijk duikt ook de vraag op hoe hier gambas2 op te krijgen, als de repositories niet meer beschikbaar zouden zijn.

http://software.opensuse.org/package/gambas2

levert twee mogelijkheden op voor openSUSE 11.4:

KDE:KDE3
2.24.0
32 Bit
64 Bit
Source
1 Click Install

home:swyear
2.20.2
Source
1 Click Install

Geluk?

(upd 2015-05) Versie 2.20
Ook nu een “nieuwe” opensuse 11.4 install waarvoor ik Gambas nodig heb. Ik plak de swyear URL in Yast Softwarebronnnen:
repositories/home:/swyear/openSUSE_11.4
Gambas2 kan daarna gestart worden in KDE, maar kreeg geen menu-item/icoon (zelfs niets in recent geïnstalleerd menu).
Bovendien

  • is dit (v. 2.20) niet de meest recente versie die bestaat van Gambas2 (v. 2.24)
  • zitten de voorbeelden er niet bij.

Een menu-item kan je zelf maken, het icoon vind je hier op https://build.opensuse.org/package/show/Education/gambas2
(end upd 2015-05)

2.24
Ik kies de meest recente (bovenste), hoewel daar enkel gesproken wordt over de runtime.

Er wordt kort iets geïnstalleerd, maar in het menu komt Gambas niet voor nadien.

In Yast, Software Management, zoek “gambas”, krijg je wel een uitgebreide keuze aan gambas op het menu: het zijn alle aparte onderdelen; de Gambas2 Runtime Environment blijkt al aanwezig te zijn. Ik selecteer nu de “Gambas IDE” : (dan komt de rest van de componenten mee)

gambas2-ide – The Gambas Development Enviroment.

Nadien is Gambas 2.24 geïnstalleerd, en ook vanuit het menu bereikbaar (niet zo fraai benoemd*):

Menu Recently Installed/Gambas2

Menu Development (nieuw bijgekomen) / “Integrated Envir. (Basic Development Environment) *
Je kan die bescrhijving veranderen met de menu editor: Menu, “programma’s bewerken”, Development openklikken en daar blijkt dat de oorzaak KDE is: Als er maar 1 item voorkomt in het menu krijgt het menu geen submenu’s om dat item te starten, maar telt het menu zelf, hier “Integrated Environment”. Dat werkt goed als je een menu hebt dat “Spreadsheet” heet, en dan bevolkt wordt door 1 of meer spreadsheet programma’s, maar hier is het onduidelijk. Maak eventueel een nieuw submenu op hoofdniveau aan (bv “Snel” met icoon van hartje of rode bol of iets zeer herkenbaars) en zet het daarin (kopieer of sleep).

Upd: Of pech?
Later lukte het niet meer op deze manier, maar eind oktober 2014 installeerde ik zo:
– Yast, Softwarebronnen, toevoegen (URL opgeven).
– plak daar:
http://download.opensuse.org/repositories/KDE:/KDE3/openSUSE_11.4/
Bevestigen en in het softwarbeheer gaan kijken.
Zoek, “gambas2”; kies de gambasIDE en alles wat nodig is wordt mee geselecteerd.


Upd nov 2014
Andere situatie: nieuwe opensuse 2014 installatie met alleen de runtime: ook van http://software.opensuse.org/package/gambas2, dan onder “unsupported distributions” openen, en dan
KDE:KDE3 – 2.24.0 32 Bit
En bevestigen; er begint een download die redelijk wat extra paketten ook afhaalt.
Nadien is de gambas runtime geïnstalleerd:

gambas2 – Runtime Environment for Gambas

/usr/bin/gambas2
/usr/bin/gambas2-database-manager.gambas
/usr/bin/gambas2.gambas

3 files total

Volgende vraag: hoe gebruiken? Ik heb de runtime geïnstalleerd en ik heb een programma dat in de gambas IDE gecompileerd werd tot een .gambas bestand. Bij pogingen het programma te draaien krijg ik altijd foutmeldingen, bv

/usr/bin/env: gbr2: No such file or directory

gbr is een link naar gbx (zag ik op een systeem met de hele Gambas2 IDE); gbr en gbx bestaan niet hier. Maar zelfs als ze even geleend worden van het andere systeem werkt het hier niet mee.

Ik doe nog eens het ommetje langs de opensuse website en kies nog eens de install van de 32bit versie uit de KDE3 repository:
http://software.opensuse.org/package/gambas2
En na wachtwoord vraag begint packagekit weer iets te installeren. Een hele lijst zelfs, waarin ik zie voorbijkomen:
waarin ook gambas2, en verder: samba, gimp-help, libreoffice converter en extentions, enz… om te eindigen in “File was installed successfully”.
Maar ik zie verder niet veel verschil, behalve dat mijn harddisk nu voor 4.4 Gb vol is ipv 3.9.

Ik voeg dus nog de KDE3 repository toe, manueel, want de community optie werkt niet in mijn huidige 11.4:
http://download.opensuse.org/repositories/KDE:/KDE3/openSUSE_11.4/

Daarna is er veel meer Gambas2 in Yast/Software management.
Ik zie nu alle afzonderlijke componenten, en kies de gambas2-gb-gui alleen uit. Die vereist dan nog een paar extra componenten, zoals de “runtime”- die zal daarmee vervangen worden veronderstel ik.
Ik zit nu aan 4.5 Gb ruimtegebruik.
Ik mis nu gb.form, die in het package management eruitziet als:
gambas2-gb-form - The control component for both GTK+ and qt
(Dat moet je weten als je zypper wil gebruiken). Install.
Zelfde voor:
gb.db: zypper install gambas2-gb-db
gb.db.form: zypper install gambas2-gb-db-form
gb.settings: zypper install gambas2-gb-settings
gb.qt: (dit zijn er een paar meer):
zypper install gambas2-gb-qt

Loading repository data…
Warning: Repository ‘openSUSE-11.4-Update’ appears to outdated. Consider using a different mirror or server.
Reading installed packages…
Resolving package dependencies…

The following NEW packages are going to be installed:
gambas2-gb-qt kdelibs3-default-style qt3

The following recommended package was automatically selected:
kdelibs3-default-style

3 new packages to install.
Overall download size: 3.1 MiB. After the operation, additional 10.2 MiB will be used.
Continue? [y/n/?] (y):
Retrieving package qt3-3.3.8c-219.1.i586 (1/3), 2.8 MiB (9.1 MiB unpacked)
Retrieving: qt3-3.3.8c-219.1.i586.rpm [done (377.9 KiB/s)]
Retrieving package kdelibs3-default-style-3.5.10-232.1.i586 (2/3), 128.0 KiB (381.0 KiB unpacked)
Retrieving: kdelibs3-default-style-3.5.10-232.1.i586.rpm [done (0 B/s)]
Retrieving package gambas2-gb-qt-2.24.0-22.1.i586 (3/3), 190.0 KiB (696.0 KiB unpacked)
Retrieving: gambas2-gb-qt-2.24.0-22.1.i586.rpm [done]
Installing: qt3-3.3.8c-219.1 [done]
Installing: kdelibs3-default-style-3.5.10-232.1 [done]
Installing: gambas2-gb-qt-2.24.0-22.1 [done]

Maar daarna draait de applicatie perfect! En zonder de Gambas2-IDE.

Eens de meestgebruikte componenten geïnstalleerd zijn toekomstige programma’s minder omslachtig te installeren, tenzij ze weer een nieuwe component nodig hebben.
Dit soort afhankelijkheden wordt waarschijnlijk opgevangen als je vanuit Gambas installatie-packages maakt.


Upd 2016-01-19: toevoegen repo gaat niet in Yast, wel zo:
zypper ar http://download.opensuse.org/repositories/KDE:/KDE3/openSUSE_11.4 gambasKDE3

Door de bestanden in een map lopen (files in directory)

Hier een stukje code waar door een map (directory) wordt gelopen en alle bestanden uit die directory worden weergegeven.

  • De directory komt hier uit een object ($hCardGame.sLocation), maar het is een gewone string met het volledige pad in, je kan het als test vervangen door de home directory zoals in de commentaar van de code wordt gesuggereerd.
  • Set1 is de subdirectory die doorlopen wordt.
  • De selectie van de files is hier een aantal grafische bestanden: png, jpg, jpeg; die worden eerst in een array gestoken.
  • Dan wordt de array uitgelezen met een FOR EACH / NEXT lus
  • Binnen die lus gebeurt een test, hier om te kijken of de lijst met namen niet te lang wordt
  • De uitvoer gaat naar een listbox, hier lsbxLog genaamd.

Dus behalve onderstaande code heb je daarbuiten de listbox en het object met eigenschap sLocation nodig (of vervang het door een parameter in de procedure).

PUBLIC SUB listImages()
  
  DIM sDirectory AS String
  DIM aFiles AS String[]
  DIM sFileName AS String
  DIM sList AS String 
  
'  Directory = System.User.Home
  sDirectory = $hCardGame.sLocation &/ "Set1"
  lsbxLog.Add(sDirectory, 0)
  aFiles = Dir(sDirectory, "*.png")
  aFiles.Insert(Dir(sDirectory, "*.jpg"))
  aFiles.Insert(Dir(sDirectory, "*.jpeg"))
  
  sList = ""
  FOR EACH sFileName IN aFiles
    sList &= ";" & sFileName
    IF Len(sList) > 80
      lsbxLog.Add(sList, 0) ' buffer full, show current part
      sList = ""
    ENDIF 
  NEXT
  lsbxLog.Add(sList, 0) ' final part
  
END