Τρίτη, 15 Αυγούστου 2017

Αναθεώρηση 28 (Έκδοση 8.9)

Βρέθηκε ένα λάθος που παρουσιάζεται μόνο στα Windows 10. Διορθώθηκε έμμεσα επειδή δεν έχω στο περιβάλλον προγραμματισμού υπολογιστή με Windows 10 (θα φτιάξω όμως σε Virtual Box όταν βρω χρόνο). Εφόσον στα Ελληνικό Ε όταν ήταν πρώτο γράμμα, ως όνομα στοιχείου ελέγχου (control) στη φόρμα χρήστη, έβγαινε λάθος,τότε η λύση είναι εύκολη, τα ονόματα στα στοιχεία θα είναι στα αγγλικά! Το γιατί το κάνει, και που ακριβώς δεν μπόρεσα να το βρω, όμως βρήκα τι έπρεπε να κάνω ώστε να δημιουργήσω το αποτέλεσμα του λάθους από Windows 10 σε Windows 7, κάνοντας βηματική εκτέλεση και προκαλώντας καθαρισμό σε ένα αλφαριθμητικό που κανονικά είχε το όνομα του στοιχείου. Δυο εντολές καθορίζουν αυτό το όνομα, και πιθανολογώ ότι είναι στην πρώτη, μια που επιστρέφει το όνομα του στοιχείου μέσα στο κώδικα της VB6,το UserControl.Ambient.DisplayName, και η δεύτερη η GetStrUntilB() που είναι μια δική μου συνάρτηση που ξέρω ότι δουλεύει καλά, και θα είχε φέρει λάθη και σε άλλα σημεία.

Ο κώδικας σε VB6, στο μοναδικά UserControl της M2000 (και το οποίο χρησιμοποιείται σε όλες τις φόρμες - και στο διορθωτή προγραμμάτων)
Παρατηρήστε ότι η Sub MoveTwips, πρέπει να συνδέσει το Control mo, βάσει του ονόματος που έχει το UserControl στο οποίο καλέσαμε την MoveTwips, διαβάζοντας από το πατρικό (τη φόρμα) τον δείκτη σε αυτό. Δηλαδή μέσα στο κώδικα του UserControl ο μοναδικός τρόπος να πάρουμε ένα δείκτη στο αντικείμενο που ουσιαστικά βρίσκεται στη φόρμα, είναι με χρήση του ονόματος, στη λίστα στοιχείων (controls) στη φόρμα.

Public Sub MoveTwips(ByVal mleft As Long, ByVal mtop As Long, mWidth As Long, mHeight As Long)
      Dim mm$, mo As Control, nm$, cnt$, p As Long
      mm$ = UserControl.Ambient.DisplayName
      nm$ = GetStrUntilB(p, "(", mm$ & "(", True)
      cnt$ = GetStrUntilB(p, ")", mm$, True)
      On Error Resume Next
      If UserControl.Parent Is Nothing Then Exit Sub
      If Err.Number > 0 Then Exit Sub
      If cnt$ <> "" Then
            Set mo = UserControl.Parent.Controls(nm$).item(CInt(cnt$))
      Else
            Set mo = UserControl.Parent.Controls(nm$)
      End If
      If mWidth < 100 Then
            mo.Move mleft, mtop, mo.Width, mo.Height
      ElseIf mHeight < 100 Then
            mo.Move mleft, mtop, mWidth, mo.Height
      Else
            mo.Move mleft, mtop, mWidth, mHeight
      End If
End Sub.

Σάββατο, 5 Αυγούστου 2017

Αναθεώρηση 27 (Έκδοση 8.9)

Μερικές προσθήκες εσωτερικές (διορθώθηκε και η 26 που βγήκε για λίγο)
Μπήκε η δυνατότητα να δώσουμε στο σωρό ένα αντικείμενο και να το φορτώσουμε σε θέση πίνακα. Για ομάδες και λάμδα συναρτήσεις γίνονταν, όπως γίνονταν και με άμεση εκχώρηση (πχ το Α(2)=(1,2,3) είναι άμεση εκχώρηση, ενώ το Στη Β(2)=(1,2,3) είναι έμμεση, επειδή πρώτα υπολογίζεται η δεξιά έκφραση και μετά η αριστερή, ενώ μεσολαβεί η τοποθέτηση του αποτελέσματος στο σωρό τιμών). Η δυνατότητα λοιπόν που μπήκε είναι άμεσα συνδεδεμένη και με το πώς διαβάζουν τμήματα και συναρτήσεις από το σωρό (αφού διαβάζουν με τη Διάβασε, ή READ)

Dim A(10), B(10)
A(2)=(1,2,3)
let B(2)=(1,2,3)
\\ let is equivalent with two commands
\\ Push (1,2,3) : Read B(2)
Print A(2)(2), B(2)(2)

Διάλειμμα για διακοπές!





Παρασκευή, 4 Αυγούστου 2017

Εγχειρίδιο της Μ2000 - Τεύχος 35ο

17.6 Λίστα.Εισαγωγής (Combo)
Το στοιχείο Λίστα.Εισαγωγής έχει πάνω στη φόρμα ένα στοιχείο Εισαγωγή (textbox) και εμφανίζει με το κάτω βελάκι ή με κλικ με το ποντίκι ένα στοιχειο Λίστα (listbox), σε ξεχωριστό παράθυρο (φαίνεται σαν αναπτυσσόμενη λίστα), λέγεται αναδιπλούμενη λίστα, και εξαφανίζεται όταν αλλάξει η εστίαση σε άλλο στοιχείο στη φόρμα. Η θέση του ξεχωριστού παράθυρου μπορεί να αλλάξει ανάλογα με το που βρίσκεται το στοιχείο σε σχέση με την οθόνη του υπολογιστή. Αν είναι χαμηλά θα βγει πάνω από το στοιχείο Εισαγωγή.  Στο στοιχείο Εισαγωγή θα υπάρχει ένας τίτλος (ιδιότητα "Label") και δίπλα ένα βελάκι σαν τρίγωνο με την βάση από πάνω. Όταν εισάγουμε κείμενο τότε αυτό φαίνεται αμέσως μετά το βελάκι. Στη διαφοροποίηση σε μενού δεν έχουμε κείμενο δεξιά από το βελάκι.


Χρήσεις της Λίστας Εισαγωγής
  • Μενού επιλογών, με διάφορα στοιχεία στη λίστα, χωρίς τη χρήση του πεδίου επιλογής για εμφάνιση επιλογής. Τα στοιχεία της λίστας μπορεί να είναι ομάδες στοιχείων με φερόμενη κουκίδα δεξιά, όπου μια κουκίδα είναι συνέχεια επιλεγμένη, μπορεί να είναι απλά στοιχεία με κουκίδα δεξιά (όπως το στοιχείο Επιλογή ή Checkbox), ή απλά στοιχεία (όπως πλήκτρο ή button), ή μια διαχωριστική γραμμή. Τα στοιχεία μπορεί να είναι ενεργά ή όχι.
  • Αναπτυσσόμενη λίστα για επιλογή στο πεδίο εισαγωγής μόνο από τη λίστα
  • Πεδίο εισαγωγής, με αυτόματη συμπλήρωση βάσει λίστας, με δυνατότητα συμπλήρωσης

Στη λίστα μπορούμε να κάνουμε επιλογές και μπορεί να υπάρχει ανάδραση, ώστε να έχουμε πληροφόριση για τις επιλογές, χωρίς να κάνουμε αλλαγή κατάστασης, δηλαδή χωρίς αλλαγή επιλογής στο στοχείο Εισαγωγή ή χωρίς επιλογή ενέργειας, όταν λειτουργεί ως μενού. Η επιλογή στη λίστα γίνεται με βελάκια, με click σε μη επιλεγμένο, ή με πλήκτρο αρχικού γράμματος (όπου διαδιχικά, με το ίδιο πλήκτρο, μεταφέρεται η επιλογή σε στοιχεία στη λίστα με ίδιο πρώτο γράμμα). Ολοκληρώνουμε την επιλογή μας με Enter, ή με click πάνω στο επιλεγμένο, ή με σύρσιμο δεξιά (πρέπει να αφήσουμε την επιλογή εντός της λίστας για να πιάσει η ενέργεια)

Γεγονότα
  • About
  • MenuChecked item
  • DblClick item
  • Move item
  • Scroll item
  • Click item
  • OpenMenu
  • PickOther item
  • AutoCompleteDone word$
Ιδιότητες
UseOnlyTheList
AutoComplete
NoCaseSensitive
Index
ListText
Label μόνο για να αλλάξουμε τιμή
menuEnabled()  πέρνει στοιχείο στις παρενθέσεις και βάζουμε αληθές ή ψευδές
id(item) δίνει αλφαριθμητικό με αναγνωριστκό για μενού.
List(item) δίνει και παίρνει αλφαριθμητικό
Text δίνει και παίρνει το κείμενο που εμφανίζεται στην Εισαγωγή
locked
ListRadioPrivate() παίρνει μια τιμή Αληθής ή Ψευδής
ListSelected() διαβάζει και δίνει τιμή Αληθής ή Ψευδής
ListChecked() διαβάζει και δίνει τιμή Αληθής ή Ψευδής
ListMenu()
ListRadio()
ListSep()
(συνεχίζεται)
Μέθοδοι
Move
FontAttr
additem

MenuItem
(συνεχίζεται)

Παράδειγμα με αυτόματη συμπλήρωση και πρόσθεση στοιχείων
Σε αυτό το παράδειγμα ότι γράφουμε και βάζουμε στη λίστα θα είναι σε κεφαλαία γράμματα. Όταν επιλέγουμε κάτι στη λίστα με απλό κλικ, ή με βελάκια, ή με ολίσθηση ή με επιλογή πρώτου γράμματος, παράγονται γεγονότα Click(), Scroll(), PickOther() τα οποία τροφοδοτούν ένα στοχείο Εισαγωγή, το Εισ1. Το ίδιο γίνεται όταν γράφουμε τα πρώτα γράμματα στο πεδίο εισαγωγής της Λίστας Εισαγωγής και αυτόματα συμπληρώνεται, καθώς τότε παράγεται το γεγονός AutoCompleteDone().
Η ιδιότητα ListText έχει μια διαφοροποίηση σε σχέση με το τι κάνει όταν εκχωρούμε τιμή και το τι κάνει όταν διαβάζουμε τιμή. Στην εκχώρηση βάζει ένα αλφαριθμητικό με παραγράφους ως την νέα λίστα εισαγωγής. Στην ανάγνωση δίνει ή κενό αλφαριθμητικό αν δεν έχουμε επιλέξει κάτι στη λίστα, ή το επιλεγμένο στη λίστα. Έτσι διαβάζουμε τη λίστα! Θα μπορούσαμε να τη διαβάσουμε ως Λίστα$(Επιλ_λίστας) (επειδή έχουμε ορίσει το Επιλ_λίστας να είναι η ιδιότητα ListIndex, και το Λίστα$() να είναι η ιδιότητα List. Η ιδιότητα list έχει μια παράμετρο και έτσι φτιάχνουμε ένα πίνακα (ουσιαστικά φαίνεται σαν πίνακας, αλλά είναι αντικείμενο με μια παράμετρο που επιστρέφει τιμή, ή δέχεται τιμή, δηλαδή μπορούμε να αλλάξουμε κάποιο στοιχείο). 

Επειδή ανοίγουμε το παράθυρο σαν modal (δηλαδή περιμένει για να κλείσει), και επειδή δεν μπορούμε να πάμε την εστίαση σε ένα στοιχείο πριν η φόρμα γίνει ορατή, εκτελούμε ένα νήμα μιας χρήσης με την Μετά, όπου σε 2/10 του δευτερολέπτου στέλνουμε την εντολή για να κινηθεί η εστίαση στο στοιχείο Εισ1, αφού θα έχει ανοίξει η φόρμα..

Πώς δουλεύει η αυτόματη συμπλήρωση:
Καθώς πληκτρολογούμε γράμματα εμφανίζεται η λέξη που βρίσκει το στοιχείο στην λίστα. Όμως παρόλο που φαίνονται τα γράμματα που δεν έχουμε πληκτρολογήσει, αμέσως μετά το δρομεά, αυτά δεν υπάρχουν σε αυτό που μόλις έχουμε πληκτρολογήσει. Έτσι συνεχίζοντας να πληκτρολογούμε γίνεται νέα εύρεση και αν δεν βρεθεί βλέπουμε το συμπλήρωμα να εξαφανίζεται. Ομοίως αν πάμε στο τέλος της λέξης που έχει βρεθεί και ξεκινήσουμε να σβήνουμε γράμματα, τα γράμματα μετά το δρομέα δεξιά δεν φαίνεται να σβήνονται όσο ακόμα συμπληρώνονται αυτόματα, ή μπορεί να αλλάξουν αν για τα γράμματα που όντως υπάρχουν βρεθεί άλλο συμπλήρωμα. Σε κάθε περίπτωση αναζήτησης παράγεται ένα γεγονός AutoCompleteDone.

Πώς δουλεύει η επιλογή στη λίστα με πλήκτρο:
Όταν έχουμε ανοίξει τη λίστα, με κάτω βελάκι ή με το ποντίκι, μπορούμε να πατήσουμε το πρώτο γράμμα σε αυτό που μας ενδιαφέρει, και αν υπάρχει η επιλογή στη λίστα, που έχει αυτό το γράμμα στη πρώτη θέση, θα μεταφερθεί στο πρώτο που θα βρεθεί, μετγά από το σημείο που βρίσκεται η τωρινή επιλογή, ή απο την αρχή αν είμαστε στο τέλος της λίστας, ή δεν υπάρχει άλλο μέχρι το τέλος αυτής . Αν το ξαναπατήσουμε θα πάει στο επόμενο που θα βρεθεί. Κάθε φορά που κάνουμε αναζήτηση με γράμμα παράγεται ένα γεγονός PickOther. Αν πατήσουμε enter ή κάνουμε click στο επιλεγμένο ή σύρουμε δεξιά, θα παραχθεί το DblClick. Η επιλογή με γράμμα λειτουργεί σε κάθε διαμόρφωση, και όχι ειδικά στην αυτόματη συμπλήρωση.


Σε Widnows 10, βρέθηκε ένα πρόβλημα, και λόγω ότι είμαι σε διακοπές, δεν θα μπορέσω να το φτιάξω. Όταν λοιπόν μετά την όρισε ξεκινάει το όνομα αντικειμένου με Ε κεφαλαίο υπάρχει θέμα με την εμφάνιση του στοιχείου! Μου είναι αδύνατον να κατανοήσω τώρα, πώς τα 10 κάνουν τέτοιο πράγμα όταν ο κώδικας τρέχει κανονικά σε 8, 7, XP. Αν δώσουμε το Ε με μικρό ε, δηλαδή από Εισ1 σε εισ1 δεν υπάρχει πρόβλημα. Όπως το είδα μόνο στο Ε έχει πρόβλημα και αυτό αν είναι στην αρχή, και μόνο στην Όρισε!
Στην αναθεώρηση 28, διορθώθηκε έμμεσα, δηλαδή τα ονόματα των στοιχείων εσωτερικα είναι με επιλογή από τον διερμηνευτή, με χαρακτήρες συμβατούς, από το A αγγλικό έως Z αγγλικό.


Όρισε Φόρμα1 Φόρμα
Όρισε ΛιστΕισ1 Λίστα.Εισαγωγής Φόρμα Φόρμα1
Όρισε εισ1 Εισαγωγή Φόρμα Φόρμα1
Με Φόρμα1,"Title" ως Τίτλος$
Με ΛιστΕισ1,"Edit", Αληθές,"UseOnlyTheList", Ψευδές,"autocomplete", Αληθές, "ListIndex" ως Επιλ_λίστας, "ShowAlways", Αληθές
Με ΛιστΕισ1,"Label","ΛιστΕισ1", "ListText" ως Στοιχεία$, "list" ως Λίστα$(), "text" ως ΛιστΕισ1$
Στοιχεία$={ΑΛΦΑ
            ΔΕΛΤΑ
            ΓΑΜΜΑ
            ΒΗΤΑ
            }
Με ΛιστΕισ1,"Find" ως Βρες()
Μέθοδος ΛιστΕισ1,"Sort"
ΛιστΕισ1$=Λίστα$(Βρες("ΓΑΜ*"))

Μέθοδος ΛιστΕισ1,"Move", 1000,1000,6000,600
Μέθοδος Εισ1, "Move", 1000,2900,6000,600

Με Εισ1,  "text" ως Εισ1Κείμενο$ , "ShowAlways", Αληθές
Συνάρτηση ΛιστΕισ1.about {
      Περί "Βοήθεια ΛιστΕισ1", "Διάλεξε ή γράψε τα πρώτα γράμματα, μπορείς να προσθέσεις νέο στη λίστα"
}
Συνάρτηση ΛιστΕισ1.AutoCompleteDone {
      Εισ1Κείμενο$=Στοιχεία$
}
Συνάρτηση ΛιστΕισ1.PickOther {
      Εισ1Κείμενο$=Στοιχεία$
}
Συνάρτηση ΛιστΕισ1.dblclick {
      ΛιστΕισ1$=Κεφ$(ΛιστΕισ1$)
      Εισ1Κείμενο$=ΛιστΕισ1$
      Τίτλος$=ΛιστΕισ1$
      Αν Βρες(Τίτλος$)= -1 Τότε {
                  Μέθοδος ΛιστΕισ1,"additem", Τίτλος$
                  Μέθοδος ΛιστΕισ1,"Sort"
                  Επιλ_λίστας=Βρες(Τίτλος$)
      }
}
Συνάρτηση ΛιστΕισ1.click {
      Εισ1Κείμενο$=Στοιχεία$
}
Συνάρτηση ΛιστΕισ1.scroll {
      Εισ1Κείμενο$=Στοιχεία$
}
Μετά 200 {Μέθοδος Εισ1,"GetFocus"}
Μέθοδος Φόρμα1, "show", 1
Περί ""
Όρισε Εισ1 Τίποτα
Όρισε ΛιστΕισ1 Τίποτα
Όρισε Φόρμα1 Τίποτα



Θα μπορούσαμε να μην δεχτούμε αλλαγή τιμής σε τιμή που δεν υπάρχει στη λίστα. Τότε όμως θα πρέπει όταν αφήνουμε το στοιχείο αυτό, για να επιλέξουμε άλλο, να σκεφτούμε έναν τρόπο να καθαρίσουμε τυχόν γράμματα που έχουν γραφτεί σε αυτό. Η άλλη πιο απλή λύση θα είναι να ξεκινήσουμε χωρίς Edit, δηλαδή την ιδιότητα Edit να την έχουμε με τιμή Ψευδές. Σε αυτήν την περίπτωση, επειδή δεν έχουμε δρομέα φανερό (caret) να αναβοσβήνει, το στοιχείο χρωματίζεται, με ένα πράσινο χρώμα και επειδή έχουμε το ShowAlways με τιμή Αληθές, και να χάσει την εστίαση παραμένει αυτό το χρώμα.


Παράδειγμα με επιλογή από τη λίστα




Όρισε Φόρμα1 Φόρμα
Όρισε ΛιστΕισ1 Λίστα.Εισαγωγής Φόρμα Φόρμα1
Όρισε εισ1 Εισαγωγή Φόρμα Φόρμα1
Με Φόρμα1,"Title" ως Τίτλος$
Με ΛιστΕισ1,"UseOnlyTheList", Αληθές, "ListIndex" ως Επιλ_λίστας
Με ΛιστΕισ1,"Label","ΛιστΕισ1", "ListText" ως Στοιχεία$, "list" ως Λίστα$(), "text" ως ΛιστΕισ1$
Στοιχεία$={ΑΛΦΑ
            ΔΕΛΤΑ
            ΓΑΜΜΑ
            ΒΗΤΑ
            }
Με ΛιστΕισ1,"Find" ως Βρες()
Μέθοδος ΛιστΕισ1,"Sort"
ΛιστΕισ1$=Λίστα$(Βρες("ΓΑΜ*"))

Μέθοδος ΛιστΕισ1,"Move", 1000,1000,6000,600
Μέθοδος Εισ1, "Move", 1000,2900,6000,600

Με Εισ1,  "text" ως Εισ1Κείμενο$ , "ShowAlways", Αληθές
Συνάρτηση ΛιστΕισ1.about {
      Περί "Βοήθεια ΛιστΕισ1", "Διάλεξε ή γράψε τα πρώτα γράμματα, μπορείς να προσθέσεις νέο στη λίστα"
}
Συνάρτηση ΛιστΕισ1.PickOther {
      Εισ1Κείμενο$=Στοιχεία$
}
Συνάρτηση ΛιστΕισ1.dblclick {
      Εισ1Κείμενο$=ΛιστΕισ1$
      Τίτλος$=ΛιστΕισ1$
}
Συνάρτηση ΛιστΕισ1.click {
      Εισ1Κείμενο$=Στοιχεία$
}
Συνάρτηση ΛιστΕισ1.scroll {
      Εισ1Κείμενο$=Στοιχεία$
}
Μετά 200 {Μέθοδος Εισ1,"GetFocus"}
Μέθοδος Φόρμα1, "show", 1
Περί ""
Όρισε Εισ1 Τίποτα
Όρισε ΛιστΕισ1 Τίποτα
Όρισε Φόρμα1 Τίποτα
















Αναθεώρηση 25 (Έκδοση 8.9)

Προσθήκες συναρτήσεων για ιδιότητες αντικειμένων τύπου COM, ιδιότητα(), ιδιότητα$(), property(), property$()

declare form1 form
declare list1(3) listbox form form1
controls=(,)
link controls to controls$()
inventory listindex, titlelist
for i=0 to 2 {
      Method list1(i), "move", 2000,1100+i*1000, 5000,900
      With list1(i), "list" as new list$(), "DisplayLines", 2, "listindex" as new listind, "title" as new mTitle$
      With list1(i), "text", {aaaaaaa
            bbbbbbbbbb
            cccccccc
            }
      Append titlelist, i:=property$(mTitle$)
      Append listindex, i:=property(listind)
      Print listindex(i), type$(listind)
      Append controls, (list$(),)
      Print len(controls$())
      controls$(i)(0)="ok"+str$(i)
      Print list$(0), "ok", controls$(i)(0)
}
     listindex(0)=2
     titlelist$(0)="ok..."
Print len(listindex)
function form1.click {
     listindex(0)=2
}
function list1.dblclick {
      Read New Who, what
      Print listindex(who), who, what
      Refresh
}
method form1, "show",1
declare list1() nothing
declare form1 nothing



Το παρακάτω πρόγραμμα δουλεύει καλά τώρα, και χρησιμοποιεί ένα εξωτερικό αντικείμενο, το vbRichClient 5 από εδώ  http://www.vbrichclient.com/, το οποίο έχει ένα σωρό αντικείμενα και συνάμα έχει δικές του φόρμες, του συστήματος Cairo. Δείτε πως παίρνουμε τα γεγονότα για φόρμες που ανήγουμε προσωρινά με Modal τρόπο:
Κάθε φορά που κάνουμε click στη κίτρινη φόρμα, ανοίγουν έξι "κόκκινες" Modal φόρμες, και κάθε φορά πρέπει να κλείσουμε την πιο μπροστά για να πάμε στην πιο πίσω μέχρι να φτάσουμε στην κίτρινη πάλι. Συνάμα αν κάνουμε κλικ στην κόκκινη φόρμα


Δείτε κάτι ακόμα: Υπήρχε πρόβλημα όταν ξεκίναγα μια "κόκκινη" φόρμα μέσα στην συνάρτηση εξυπηρέτησης γεγονότος, μπορούσε να ανοίξει τέσσερις φόρμες και μετά για άνγωστη αιτία δεν άνοιγε άλλη! Το σκέφθηκα λοιπόν και έβαλα την εντολή After miliseconds {} ή Μετά χιλιοστά_δευτερολέπτου {}, το οποίο είναι νήμα που θα τρέξει αφού το γεγονός θα έχει επισρέψει!

Επίσης από αυτή την αναθεώρηση έβαλα στα γεγονότα που στέλνονται στην Μ2000 (συναρτήσεις με όνομα αντικειμένου μετά μια κάτω παύλα και μετά το όνομα του γεγονότος, να ακολουθεί στο τέλος το αντικείμενο (μια αναφορά του) που στέλνει το γεγονός! Έτσι η Form2_Click δουλεύει με τη σειρά για όλες τις φόρμες που ανοίγουν η μία μετά την άλλη (έξι τον αριθμό)

Επίσης δείτε στο Form2_move ότι διαβάζουμε με αναφορά τα Χ και Υ (σημαίνει ότι μπορούμε να τα αλλάξουμε). Και σε αυτό το γεγονός στο σωρό τιμών (που καθαρίζει μετά την κλήση από το σύστημα των γεγονότων, εντός του διερμηνευτή), ακολουθούν δυο στοιχεία, ένα αλφαριθμητικό με πληροφορίες, και ένα ακόμα, το αντικείμενο που στέλνει το γεγονός (αυτό προστέθηκε σε αυτή την αναθεώρηση).

Επίσης δείτε το  πως δημιουργούμε το Form2. Επειδή θέλουμε να βγει 6 φορές με 6 νήματα, και κάθε νήμα θα μπλοκάρει για όσο η φόρμα Form2 θα είναι ανοιχτή, σημαίνει ότι στο τμήμα θα υπάρχουν 6 Form2, δηλαδή με ίδιο όνομα και σε αναζήτηση θα βρίσκεται το τελευταίο που γράφτηκε.ενώ η διαγραφή δεν θα γίνεται στο νήμα! Το νήμα δηλαδή δεν διαγράφει ότι τυχόν φτιάχνει. Αν ανοίξουμε 600 φόρμες θα υπάρχουν 600*Ν μεταβλητές όπου Ν είναι όσες χρειάστηκε να φτιαχτουν ως νέες στο κάθε νήμα.
Τώρα πώς ξέρουμε ότι θα καθαρίσουν οι μεταβλητές αυτές με την ανάποδη σειρά; Οι φόρμες άνοιξαν σαν Modal δηλαδή πρέπει να κλείσουμε την τελευταία που άνοιξε, και μετά την προτελευταία, και αυτή είναι η σειρά που πρέπει να "καθαρίσουν" και τα αντικείμενα.

Δείτε επίσης πως όταν κρατάμε πατημένο το [X] για κλείσιμο της φόρμας στο RC5 σταματάνε ακόμα και τα νήματα στην Μ2000. (πράγμα που δεν συμβαίνει με τις φόρμες της Μ2000, αφού το τετραγωνάκι στις φόρμες για το κλείσιμο δεν είναι το ίδιο με το κουμπί στις φόρμες της VB6). Ουσιαστικά η Μ2000 έχει ένα μέρος δικό της σε σχέση με τον Window manager, και αυτό ευθύνεται για το πώς χειρίζεται το κλείσιμο και τα modal παράθυρα (πχ η φόρμα ¨Ελεγχος είναι ανεξάρτητη από τα παράθυρα χρήστη που μπορεί να ανοίξουμε με modal τρόπο. Επίσης μπορούμε να ανοίξουμε μη modal παράθυρα από ένα modal παράθυρο, και μετά αν ανοίξουμε ένα Modal θα κλείσει όλα τα προηγούμενα και όταν το κλείσουμε θα ανοίξει μόνο τα αμέσως προηγούμενα που ήταν ανοιχτά, μέχρι να κλείσουμε και το ένα modal, που άνοιξε τα μη modal, οπότε θα ελευθερωθούν τα κάτω από αυτό! Το παράθυρο της βοήθειας είναι και αυτό εκτός των Modal παραθύρων.Τα modal παράθυρα απενεργοποιούν και την κονσόλα. Το κώδικα για αυτό το σύστημα το έχω γράψει εδώ και καιρό, αλλά είναι μια ιδέα με "μαγικούς" αριθμούς, στην ουσία τυχαίους, που διαλέγει το σύστημα, με "νόημα" που δηλώνουν το ποιος έχει το πάνω χέρι. Οπότε όταν ένα modal παράθυρο κλείνει στέλνει στα άλλα το μήνυμά του. Ένα παράθυρο που έχει "απενεργοποιηθεί", ουσιαστικά μπορεί να δουλεύει κανονικά, εκτός από το να δέχεται κλικ και πλήκτρα, δηλαδή μπορεί να μετακινηθεί, ακόμα και να κλείσει! Ακόμα και το messagebox είναι της Μ2000, το Ask() ή Ρώτα(), και βγαίνει πάνω από όλα τα άλλα, ως modal και αυτό. Εδώ έχει μια ιδιαιτερότητα η Μ2000, δεν επιτρέπει δεύτερο messagebox να βγει. Δηλαδή αν το βάλουμε σε ένα νήμα (τα νήματα μπορούν να τρέχουν πίσω από το messagebox) θα βγει λάθος αν ήδη είναι ανοικτό. Ενώ οι φόρμες της Μ2000 είναι GuiM2000 αντικείμενα, οι διάλογοι της Μ2000 όπως το messagebox και για άνοιγμα φακέλων, αρχείων, επιλογής χρώματος και επιλογής γραμματοσειράς είναι ξεχωριτά αντικείμενα (είχαν γραφτεί πριν φτιαχτουν οι φόρμες χρήστη). Αυτά τα αντικείμενα έχουν την ιδιότητα να αλλάζουν μέγεθος με μεγέθυνση των στοιχείων τους και αυτά έχουν το ένα και μοναδικό glis4, ένα user control  γραμμένο στη VB6, με "ζωγραφιές"...δηλαδή δεν έχει κανένα άλλο control πανω στο user control, είναι μια επιφάνεια που σχεδιάζει ότι χρειάζεαι, ακόμα και το scoll bar...είναι ζωγραφιστό! Αποφεύγοντας την χρήση εξωτερικών στοιχείων, ή και βιβλιοθηκών η Μ2000 μπορεί να λειτουργεί το ίδιο από Xp ως και Windows 10, για όσο το βοηθητικό dll της VB6 τρέχει σε αυτά (μέχρι τον Οκτώβριο του 2025, αν και πιστεύω ότι δεν θα πάψει να υποστηρίζεται). Στην ουσία το M2000.exe και το Μ2000.dll (η γλώσσα μπορεί να φορτωθεί σε άλλες γλώσσες και να τρέχει από αυτές), χρειάζονται το msvbvm60.dll γιατί παρέχει συναρτήσεις κοινές αλλά και γιατί έχει το σύστημα των γεγονότων που λειτουργεί ως ενδιάμεσος με τις "πραγματικές" φόρμες των Windows. (στην ουσία κάθε φόρμα της Μ2000 είναι πάνω σε μια άδεια φόρμα της VB6 η οποία είναι ένα πραγματικό παράθυρο των Windows, και τα μηνύματα που λαμβάνει προωθούνται στη φόρμα της VB6, και από εκεί η M2000 τα προωθεί στο πρόγραμμα του χρήστη, τα δυο πρώτα μέρη είναι compiled, ενώ το τρίτο, ο κώδικας σε Μ2000 είναι Interpreted, αλλά ο διερμηνευτής είναι και αυτός compiled, δηλαδή δεν τρέχει ως interpreted Visual Basic 6, αλλά ως γλώσσα μηχανής.


Παρατηρήστε ότι οι συναρτήσεις για γεγονότα σε Com αντικείμενα έχουν _ και όχι τελεία όπως στις φόρμες της Μ2000. Αυτό συμβαίνει γιατί υπάρχει ξεχωριστό σύστημα "εσωτερικό". Ενώ τα γεγονότα για τα Com χρησιμοποιούν το Shink object, για μεταφορά γεγονότων από διαφορετικές διεργασίες


Ακόμα η χρήση του συγκεκριμένιυ εξωτερικού αντικειμένου είναι πειραματική.

clear
' cConstructor
'Title "",0
Declare AppForm Application Form
Declare New_c "{CAECC935-9C70-4176-8BED-C39B2E33B31F}"
Method New_c, "Cairo" as Cairo
'Print Type$(New_c)
'Print Type$(Cairo)
With Cairo, "WidgetForms" as Cairo.WidgetForms
Method Cairo.WidgetForms, "Create", 1,"My Main-Form Caption, Click Me!" withevents as Form1

Print type$(Form1)
vbYellow=65535
vbRed=255
vbFixedDialog=3
vbSizableToolWindow=5

Print Type$(Form1)
With Form1, "WidgetRoot" as Form1.WidgetRoot, "visible" as visible
Print type$(Form1.WidgetRoot)
With Form1, "hWnd" as Form1.hWnd
With Form1.WidgetRoot, "BackColor", vbYellow
          
Method Cairo.WidgetForms, "Create", vbSizableToolWindow, "MyToolWindow - Resize Me!", -1, 800, 600 as Form3
Method Form3,"SetMinMaxDimensions", 200, 400, 300, 600
With Form3, "visible" as Form3.visible
mClicks=0
\\ events
Function Form2_Click {
      drop
      read new form111
      mClicks++
      With form111, "Caption", "Click-Count so far:" +Str$(mClicks)
}
Function Form1_Move {
      Read New &X, &Y
      Print X, Y
      refresh
}
Function Form2_Move {
      Read New &X, &Y
      Print X, Y
      refresh
}
Function Form1_Click {
      Refresh
      \\ After start a new thread after 100 msec, and run once
      for i=1 to 6 {
      After 100 {
            Report "First we show a modal Dialog-Window, and count the Clicks on it"
            Method Cairo.WidgetForms, "Create", vbFixedDialog,"MyDialog ... Click Me!",-1 , 800, 600 withevents as new Form2
            With Form2, "WidgetRoot" as new Form2.WidgetRoot
            With Form2.WidgetRoot, "BackColor", vbRed
            Refresh
            Method Form2 "Show", 1
            Refresh
            Report format$("The Dialog was clicked {0} times.", mClicks)
            Report  {Now we show a non-modal ToolWindow, which remains in the ForeGround of this Form
                              and will close itself automatically, when the MainForm is destroyed
                              }
            Print
            refresh
            Declare Form2.WidgetRoot Nothing
            Declare Form2 Nothing
      }      
      }
     
}
Thread {
try {
      If pos>0 then print
      Print now, visible
      }
      refresh
} as alfa interval 100
Print Visible
Method Form1, "Show", 0, AppForm
Print Visible
\\\  not used here Method Cairo.WidgetForms, "EnterMessageLoop"
Task.Main 100 {
      if Form1.hWnd else exit
}
Threads erase
Declare form1 nothing
Declare form3 nothing
Declare cairo nothing
declare New_c nothing
Show  \\ to get focus to M2000 console




Τετάρτη, 2 Αυγούστου 2017

Αναθεώρηση 24 (έκδοση 8.9) προσθήκες!

Σε αυτήν την αναθεώρηση υπάρχει δυνατότητα να αποθηκεύουμε ιδιότητες σε πίνακες και καταστάσεις (λίστες με κλειδί) από αντικείμενα τύπου com (όπως και οι φόρμες χρήστη, και τα στοιχεία ελέγχου στις φόρμες αυτές), τα οποία δέχονται μια παράμετρο (αριθμό ή αλφαριθμητικό) είτε για να διαβάσουμε είτε για να γράψουμε τιμή.

Στο παράδειγμα που ακολουθεί, έχουμε μια φόρμα και θέλουμε να έχουμε ένα πίνακα από Listbox (λίστες). Έχουμε έναν δείκτη σε πίνακα το controls, τον οποίο συνδέουμε με το control$() (για να έχουμε και αυτό το interface στο αντικείμενο πίνακα). Καλούμε μια μέθοδο move για καθένα listbox για να δώσουμε θέσεις στην φόρμα. Μετά με την With ορίζουμε σε καθένα μια νέα List$(). Όταν ορίζουμε νέα, σημαίνει ότι η υπάρχουσα δεν σβήνει, αλλά ο διερμηνευτής βρίσκει πάντα την τελευταία. Άρα κάπου πρέπει να την κρατήσουμε. Εδώ την βάζουμε σε ένα αυτόματο πίνακα (δείτε τις παρενθέσεις και το κόμμα πριν την δεξιά παρένθεση, που δηλώνει ότι είναι αυτόματος πίνακας, ή δείτε στην αρχή που δίνουμε στην Controls έναν κενό πίνακα με το (,)). Αυτόν τον αυτόματο πίνακα τον βάζουμε στο τέλος του Controls, δηλαδή προσθέτουμε, και εδώ η ελληνική εντολή είναι η Προσθήκη.
Δείτε αμέσως μετά την εκχώρση όπου χρησιμοποιούμε τον πίνακα Control$() (είναι ο ίδιος ο Controls) και προσθέτουμε παρενθέσεις με την τιμή που θέλουμε για την ιδιότητα.

Εδώ χρειάζεται κανείς να καταλάβει μια ιδιαιτερότητα της Μ2000 σε σχέση με τις ιδιότητες αντικειμένων που συνδέουμε σε ονόματα όπως το list$(). Αυτές είναι αντικείμενα τύπου PropReference (property reference), τα οποία συνδέονται με μεταβλητές στο χώρο του τμήματος, έτσι ώστε να μην είναι άμεσα συνδεδεμένες με το αντικείμενο απ΄όπου χειριζόμαστε την ιδιότητα, το com αντικείμενο. Το πλεονέκτημα αυτού του τρόπου είναι ότι το αντικείμενο com είναι μόνο μια φορά συνδεδεμένο με τον διερμηνευτή και θα "Χαλάσει" θα γίνει δηλαδή αποδόμηση (deconstruct)  αν ορίσουμε τίποτα, δηλαδή με την Όρισε ....Τίποτα, ή αυτόματα στο τερματισμό εκτέλεσης του τμήματος. Αν κρατήσουμε τον πίνακα πψ σε μια γενική μεταβλητή, τότε τα αντικείμενα PropReference δεν θα μπορούν να χρησιμοποιηθούν, δεν θα βρίσκουν την σύνδεση (λέγεται hatdlink στον κώδικα της Μ2000), και θα βγεί λάθος.
Αυτός ο τρόπος με έξυπνους δείκτες, υπήρχε εδώ και πολλές εκδόσεις, και όταν φτιάχτηκαν πραγματικοί δείκτες όπως αυτοί για πίνακες, για καταστάσεις, και για σωρούς (τα τρία αντικείμενα με δείκτη της Μ2000), τότε υποχρεωτικά μπήκε λογισμικό για την εκκαθάριση των αντικειμένων, σε περίπτωση που υπάρχουν μεταξύ τους συνδέσεις, δηλαδή το Α σε κάποιο στοιχείο του να έχει δείκτη στο Β και το Β στο Α. Σε αυτά τα αντικείμενα η αποδόμηση μπορεί να γίνει μόλις φύγει και ο τελευταίος δείκτης προς αυτά, δηλαδή υπάρχει μετρητής δεικτών. Το σύστημα συλλογής σκουπιδικών βάζει ακόμα έναν δείκτη και μετά κάνει σε κάθε κρατημένο αντικείμενο, καθαρισμό, και μετά έναν έλεγχο για το αν έχουν μείνει ή όχι συνδέσεις, και καθαρίζει ανάλογα. Με τα αντικείμενα PropReference δεν υπάρχει θέμα να γράψουμε αναφορά σε κάποιο, γιατί δεν θα μας δώσει αναφορά, ενώ θα  φαίνεται σαν να είναι,έτσι το συνδεδεμένο σε αυτό com αντικείμενο θα παραμείνει με έναν δείκτη και μόλις καθαρίσει η μνήμη για μεταβλητές του τμήματος, θα χαθεί άμεσα. Αυτό μπορεί να γίνει αν διακόψουμε το πρόγραμμα, με πλήκτρο Esc, ή με λάθος. Έτσι λοιπόν όταν φτιάχνουμε φόρμες στην Μ2000  και κάνουμε λάθος, βγαίνεουμ στη κονσόλα με καθαρό το σύστημα από αντικείμενα που είχαμε ορίσει (όπως οι φόρμες και τα στοιχεία ελέγχου σε αυτές). Να γιατί και να ξεχάσουμε την Όρισε Φόρμα1 Τίποτα θα καθαρίσει έτσι και αλλιώς.


declare form1 form
declare list1(3) listbox form form1
controls=(,)
link controls to controls$()
for i=0 to 2 {
      Method list1(i), "move", 2000,1200+i*800, 5000,600
      With list1(i), "list" as new list$()
      Append controls, (list$(),)
      Print len(controls$())
      controls$(i)(0)="ok"+str$(i)
      Print list$(0), "ok", controls$(i)(0)
}
method form1, "show",1
declare list1() nothing
declare form1 nothing

Και εδώ το πρόγραμμα με Κατάσταση (Inventory)

declare form1 form
declare list1(3) listbox form form1
Inventory controls
For i=0 to 2 {
      Method list1(i), "move", 2000,1200+i*800, 5000,600
      with list1(i), "list" as new list$()
      Append controls, i:=list$()
      Print len(controls)
      controls$(i)(0)="ok"+str$(i)
      Print list$(0), "ok", controls$(i)(0)
}
Print len(controls)
method form1, "show",1
declare list1() nothing
declare form1 nothing
Title "Your Program"  \\ restore title in taskbar


Και εδώ δυο προχωρημένα (δεν έχει ακόμα βγει το τεύχος για το Combo ή ;Λίστα.Εισαγωγής). Εδώ με πίνακες.

declare form1 form
declare list1(3) combobox form form1
controls=(,)
Enabled=(,)
link controls, Enabled to controls$(), Enabled()
For i=0 to 2 {
      Method list1(i), "move", 2000,1200+i*800, 5000,600
      with list1(i),"MenuStyle", True, "MenuWidth", 3000,  "MenuEnabled" as new list1_enabled()
      with list1(i),"label", "Menu"+str$(i), "list" as new list$(), "MenuGroup","group_a"
      Method list1(i), "MenuItem","Command 1",True
      Method list1(i), "MenuItem","Command 2",false
      Method list1(i), "MenuItem","Command 3",True
      Append controls, (list$(),)
      Append Enabled, (list1_enabled(),)
      Print Type$(list1_enabled())
      controls$(i)(0)="ok"+str$(i)
      Print type$(Enabled(i)()), type$(controls$(i)())
      if i=1 then Enabled(i)(1)=true
      Print list$(0), "ok", controls$(i)(0), Enabled(i)(1)
}
method form1, "show",1
declare list1() nothing
declare form1 nothing


Και εδώ με Κατάσταση Ειδών:

declare form1 form
declare list1(3) combobox form form1
inventory controls, Enabled
For i=0 to 2 {
      Method list1(i), "move", 2000,1200+i*800, 5000,600
      with list1(i),"MenuStyle", True, "MenuWidth", 3000,  "MenuEnabled" as new list1_enabled()
      with list1(i),"label", "Menu"+str$(i), "list" as new list$()
      Method list1(i), "MenuItem","Command 1",True
      Method list1(i), "MenuItem","Command 2",false
      Method list1(i), "MenuItem","Command 3",True
      Append controls, i:=list$()
      Append Enabled, i:=list1_enabled()
      controls$(i)(0)="ok"+str$(i)
      Print type$(Enabled(i)()), type$(controls$(i)())
      if i=1 then Enabled(i)(1)=true
      Print list$(0), "ok", controls$(i)(0), Enabled(i)(1)
}
method form1, "show",1
declare list1() nothing
declare form1 nothing









Κυριακή, 30 Ιουλίου 2017

Εγχειρίδιο της Μ2000 - Τεύχος 34ο

17.5 Λίστα (ListBox) 
Το στοιχείο Λίστα περιέχει γραμμές ή και έναν τίτλο. Μια λίστα μπορεί να κάνει χρήση ενός εσωτερικού πίνακα γραμμών ή με κατάλληλο προγραμματισμό να δέχεται στοιχεία απ΄έξω, πιθανόν από εξωτερικό πίνακα, ή άλλη δομή.


Μια λίστα έχει ένα μέγεθος κατά πλάτος και κατά ύψος, όμως το περιεχόμενο των γραμμών μπορεί να είναι μεγαλύτερο και θα εμφανιστεί όσο μπορεί. Μπορούμε να καθορίσουμε τις γραμμές που θα εμφανίζονται στο ύψος αυτό, ή να αφήσουμε αυτόματα να υπολογίσει το στοιχείο βάσει του μεγέθους των γραμμάτων και του διάστιχου που μπορεί να έχει επιλεχθεί.

Ο εσωτερικός πίνακας γραμμών έχει δυνατότητα ταξινόμησης και αναζήτησης.

Σε μια λίστα ο δρομέας εμφανίζεται με έναν από τους τρεις τρόπους:
  • Προκαθορισμένος με αλλαγή χρώματος φόντου και γραμμάτων
  • Με αλλαγή χρωματισμού του κειμένου μόνο. Αυτό χρησιμοποιούμε όταν έχουμε διάφανο φόντο στο στοιχείο
  • Με δρομέα κάθετο (Caret) που αναβοσβήνει, για εισαγωγή κειμένου
Η κίνηση του δρομέα μεταξύ των στηλών γίνεται με τα βελάκια, με την μπάρα ολίσθησης που είναι κρυμμένη και εμφανίζεται όταν χρειάζεται, με τα Home/End/PageUp/PageDown. Με χρήση του shift και τα βελάκια ή όταν πάμε στις άκρες πάνω και κάτω μπαίνει η αυτόματη αλλαγή γραμμής, και ολισθαίνει η λίστα. Από το μέσον δεξιά της λίστας λειτουργεί και το τράβηγμα της λίστας, δηλαδή κρατάμε πατημένο το αριστερό πλήκτρο του ποντικιού και σπρώχνουμε τη γραμμή πάνω ή κάτω. Αν σταματήσουμε να σπρώχνουμε και κρατάμε ακόμα πατημένο το πλήκτρο του ποντικιού μπαίνει η αυτόματη ολίσθηση. Η διαφορά του τραβήγματος με την ολίσθηση με τα βελάκια (ή με το ροδελάκι του ποντικιού) είναι στο ότι με το τράβηγμα δεν αλλάζουμε το δρομέα, απλά αλλάζουμε τη θέαση της λίστας (αυτό ισχύει σε όλα τα στοιχεία της Μ2000, που δείχνουν πολλές γραμμές, ακόμα και στον διορθωτή τμημάτων και συναρτήσεων, και αυτός έχει το ίδιο στοιχείο εσωτερικά)

Υπάρχουν γεγονότα (Scroll και Click) που μας δείχνουν έμμεσα το περιεχόμενο της γραμμής (μας δίνουν τον αριθμό στοιχείου) κατά την κίνηση του δρομέα μεταξύ των γραμμών (δεν παράγεται όταν τραβάμε τις γραμμές)

Η επιλογή γραμμής μπορεί να γίνεται και με τράβηγμα της γραμμής δεξιά (και ρύθμιση μιας ιδιότητας και με τράβηγμα στα αριστερά). Υπάρχει γεγονός  (DblClick) που παράγεται όταν σε μια επιλεγμένη γραμμή δίνουμε κλικ με το ποντίκι, ή Enter, ή τράβηγμα δεξιά. Αυτό το γεγονός είναι διαφορετικό από την απλή επιλογή (σε μη επιλεγμένη γραμμή, έχουμε το Click ή το Scroll).

Με χρήση ιδιοτήτων και γεγονότων μπορούμε να συνδέσουμε λίστες τη μια δίπλα στην άλλη και κάθε τράβηγμα ή ολίσθηση σε μία να κάνει ολίσθηση στις διπλανές.

Έτσι πρακτικά η Λίστα γίνεται στήλη σε πίνακα λιστών. Αν συνδυαστούν οι προβαλόμενες λίστες με την δυνατότητα προβολής από εξωτερικό πίνακα τότε μπορούμε να ολισθαίνουν οριζόντια οι στήλες νοητά,  αλλάζοντας μόνο το πίνακα προβολής κάθε λίστας, χωρίς να χρειαζόμαστε επιπλέον στοιχεία, από τα αρχικά που τοποθετήσαμε στη φόρμα.


Γεγονότα
  • ValidList  με αναφορά περιεχόμενο$, θέση, στοιχείο
  • About παράγεται όταν πατάμε το Ctrl+F1
  • ListCount  με αναφορά μέγεθος_λίστας (όταν δώσουμε νούμερο, τότε δείχνει η λίστα ότι έχει τα στοιχεία που ορίσαμε, και μπορούμε να τα φορτώνουμε στο γεγονός External)
  • KeyDown με αναφορά κωδικός_πλήκτρου, θέση_ειδικών_πλήκτρων (shift, control, alt)
  • DblClick  γυρίζει δυο αριθμούς το στοιχείο και τη θέση αριστερά ή δεξιά (0 ή -1) που προκύπτει  ανάλογα το τράβηγμα (αν έχουμε ορίσει PanDouble ως αληθές, μπορούμε να σπρώχνουμε την γραμμή - στοιχείο- αριστερά, και παράγεται το DblClick με 0.  Επειδή αυτό το γεγονός βγαίνει και με Enter, μπορούμε να χρησιμοποιούμε το Shift μαζί με το Enter για να δίνουμε την κατεύθυνση αριστερά. Το ίδιο γίνεται και όταν κάνουμε κλικ με το ποντίκι και έχουμε πατημένο το Shift.
  • External  με αναφορά  περιεχόμενο$  (δίνουμε το περιεχόμενο, όταν έχουμε την ιδιότητα External με τιμή Αληθής)
  • Unicode  με αναφορά  χαρακτήρας_unicode$
  • Move γυρίζει το στοιχείο (τον αριθμό του) που είναι το πρώτο στη φανερή λίστα.
  • Scroll γυρίζει το στοιχείο (τον αριθμό του)
  • Click γυρίζει το στοιχείο (τον αριθμό του)
  • Color  με αναφορά  χρώμα (είναι αρνητικός αριθμός, πχ το #FF0000 (κόκκινο) είναι το -255)
  • Ascii με αναφορά  χαρακτήρας_ascii   (είναι αριθμός) 
Ιδιότητες
  • Index  αριθμός  στοιχείου Λίστας όταν έχουμε πίνακα Λιστών
  • locked κλειδώνει τη λίστα
  • Εnabled με Ψευδές δεν παράγονται τα γεγονότα ValidList, ListCount, External, Color
  • Title  βάζει/διαβάζει μια γραμμή τίτλου
  • Linespace βάζει/διαβάζει το διάστιχο
  • List() δίνει ένα πίνακα για να βάζουμε και να διαβάζουμε τα στοιχεία της λίστας
  • ListIndex  βάζει/διαβάζει το επιλεγμένο
  • ListIndex2 βάζει μόνο το επιλεγμένο χωρίς επανασχεδιασμό της λίστας.
  • listcount διαβάζει τον αριθμό των στοιχείων στη λίστα
  • Text βάζει/διαβάζει τα στοιχεία σε μια ένα κείμενο με γραμμές.
  • External βάζει/διαβάζει και με τιμή Αληθές λειτουργεί η εξωτερική λίστα
  • DisplayLines  βάζει μόνο τον αριθμό των φανερών στοιχείων στη λίστα (υπολογίζει αυτόματα το διάστιχο)
  • Transparent βάζει μόνο, με Αληθές κάνει τη λίστα διάφανη (σε αυτό το στοιχείο δεν έχουμε μέθοδο αλλά ιδιότητα Transparent
  • Center βάζει μόνο, με Αληθές κάνει τα στοιχεία να είναι κεντραρισμένα στη γραμμή
  • Edit βάζει μόνο, με Αληθές κάνει τις γραμμές της λίστας να διορθώνονται από το χρήστη
  • ScrollTo βάζει μόνο, παίρνει τον αριθμό στοιχείου στη κορυφή της φανερής λίστας
  • ScrollFrom διαβάζει μόνο, δίνει τον αριθμό στοιχείου στη κορυφή της φανερής λίστας
  • ShowAlways βάζει μόνο, με Αληθές μένει το στοιχείο με άσπρο φόντο
  • Find(), διαβάζει μόνο δέχεται ως όρισμα ένα αλφαριθμητικό (μπορεί να έχει * στο τέλος), και κάνει αναζήτηση στην εσωτερική λίστα.
  • HideCaret διαβάζει μόνο,  με Αληθές κρύβει την επιλογή
  • PanDouble διαβάζει μόνο, με Αληθές επιτρέπει και το τράβηγμα προς τα αριστερά.

Μέθοδοι
  • GetFocus δίνει εστίαση στο στοιχείο, βάσει ονόματος (ουσιαστικά κάνει ότι και η SetFocus)
  • SetFocus δίνει εστίαση στο στοιχείο, απευθείας στο στοιχείο στη φόρμα
  • Move δέχεται δυο ορίσματα συν δυο προεραιτικά, τα δυο πρώτα είναι η θέση στη φόρμα, τα left και top, και τα άλλα δυο είναι το πλάτος και ύψος του στοιχείου (σε twips).
  • FontAttr δέχεται ένα όρισμα με το όνομα γραμματοσειράς, και προαιρετικά δυο ακόμα, το μέγεθος και αν θέλουμε να έχουμε φαρδιά γράμματα (bold) 
  • Refresh
  • Add περιεχόμενο$, προσθέτει μια γραμμή στο τέλος (στην εσωτερική λίστα/εσωτερικό πίνακα)
  • AddFast δείκτης,  περιεχόμενο$ (ο δείκτης δεν χρησιμοποιείται προς το παρόν), προσθέτει περιεχόμενο χωρίς επανασχεδιασμό της λίστας.
  • Insert περιεχόμενο, προσθέτει ακριβώς μετά το επιλεγμένο
  • Clear καθαρίζει τη λίστα
  • Delete αριθμός_στοιχείου, διαγράφει το στοιχείο (από την εσωτερική λίστα)
  • ShowThis αριθμός_στοιχείου και προαιρετικά με αληθές αν δεν θα είναι επιλεγμένο,  ρυθμίζει τη λίστα για να φαίνεται το στοιχείο με αριθμό που δίνουμε
  • Sort με προαιρετική έναν αριθμό θέσης στη κάθε γραμμή απ΄όπου θα ξεκινάει η σύγκριση για την ταξινόμηση.
  • ColorsReset ορίζουμε τα χρώματα στα εξ ορισμού.
  • Colors ορίζουμε το "άσπρο" και προαιρετικά άλλα τρια χρώματα.

Το παρακάτω παράδειγμα βάζει μια λίστα σε μια φόρμα, και η λίστα έχει ένα μόνο στοιχείο που γράφει το όνομά της Λιστ1! Όμως δεν έχει επιλεχθεί η γραμμή με το Λιστ1

Όρισε Φόρμα1 Φόρμα
Όρισε Λίστ1 Λίστα Φόρμα Φόρμα1
Μέθοδος Φόρμα1, "move", 2000,2000,10000,8000
Μέθοδος Λίστ1, "move", 2000,2000,4000,4000
Μέθοδος Φόρμα1,"Show", 1
Όρισε Λιστ1 Τίποτα
Όρισε Φόρμα1 Τίποτα

Η όρισε Λιστ1 Τίποτα μπορεί να παραληφθεί, όπως και σε όλα τα στοιχεία μιας φόρμας, ακόμα και η Όρισε Φόρμα1 Τίποτα, γιατί θα συμβούν αυτόματα στην έξοδο από το τμήμα. Όμως καλό είναι να φαίνεται, γιατί μπορεί να εννοείται αλλά διαβάζεται καλύτερα όταν δίνουμε την εντολή.

Ένα ακόμα παράδειγμα για το πώς διαβάζουμε τη λίστα, εδώ δεν δίνουμε μέγεθος και θέση στη φόρμα, θα πάρει τα εξ ορισμού θέση και μέγεθος. Στη λίστα βάζουμε το ShowAlways (το έχουμε δει και στα άλλα στοιχεία). Σε μια ιδιότητα text βάζουμε τις γραμμές που θέλουμε να δείξουμε ως γραμμές της λίστας. Συνδέουμε μια μεταβλητή με την ιδιότητα Listindex. Όταν κάνουμε κλικ στην φόρμα τότε μας γράφει στη κονσόλα (πίσω από τη φόρμα) την τιμή της Επιλεγμένο (της ιδιότητας Listindex). Χωρίς επιλογή γυρίζει το -1, ενώ αν επιλέξουμε το Αθήνα γυρίζει το 0. Θα μπορούσαμε πριν την εμφάνιση της φόρμας να δώσουμε το Επιλεγμένο=1 και έτσι να έχει γίνει η επιλογή στη γραμμή με τη πόλη Θεσσαλονίκη. Εδώ βλέπουμε μια απλή λειτουργία όπου θέτουμε την επιλογή στη λίστα, και μπορούμε να διαβάσουμε την επιλογή από κάποιο άλλο γεγονός και όχι ειδικά κατά την αλλαγή επιλογής!

Όρισε Φόρμα1 Φόρμα
Όρισε Λίστ1 Λίστα Φόρμα Φόρμα1
Μέθοδος Λίστ1, "move", 2000,1000,4000,3000
Με Λίστ1, "ShowAlways",Αληθές,"text",{Αθήνα
                                    Θεσσαλονίκη
                                    Πάτρα
                                    }
Με Λιστ1, "Listindex" ως Επιλεγμένο
Συνάρτηση Φόρμα1.Click {
      Τύπωσε Επιλεγμένο
      Ανανέωση
}
Μέθοδος Φόρμα1,"Show", 1
Όρισε Φόρμα1 Τίποτα

Στο παρακάτω παράδειγμα έχουμε αφαιρέσει το γεγονός Φόρμα1.Click και έχουμε βάλει δυο άλλα, το Λιστ1.Click και το Λιστ1.Scroll. Όταν επιλέγουμε με κλικ (αριστερό πλήκτρο του ποντικού) στη λίστα παράγεται γεγονός, το ίδιο όταν αλλάζουμε γραμμή με βελάκια άνω και κάτω ή με το ροδελάκι του ποντικού (κάνει PageUp ή PageDown αλλά όταν είναι λίγες γραμμές πάει ανά γραμμή) ή με πλήκτρα PageUp και PageDown. Όταν κρατάμε πατημένο το αριστερό πλήκτρο και το μετακινούμε πάλι παράγεται γεγονός αλλά τώρα είναι διαφορετικό. Και στις δυο περιπτώσεις αλλάζει η ίδια ιδιότητα. Δείτε επίσης ότι όταν αλλάζουμε την ιδιότητα Listintex (ως μεταβλητή εδώ είναι η Επιλεγμένο) δεν παράγεται γεγονός click ή scroll.

Όρισε Φόρμα1 Φόρμα
Όρισε Λίστ1 Λίστα Φόρμα Φόρμα1
Μέθοδος Λίστ1, "move", 2000,1000,4000,3000
Με Λίστ1, "ShowAlways",Αληθές,"text",{Αθήνα
                                    Θεσσαλονίκη
                                    Πάτρα
                                    }
Με Λιστ1, "Listindex" ως Επιλεγμένο
Συνάρτηση Λιστ1.Click {
      Τύπωσε Επιλεγμένο
      Ανανέωση
}
Συνάρτηση Λιστ1.Scroll {
      Τύπωσε Επιλεγμένο, "Ολίσθηση"
      Ανανέωση
}
Επιλεγμένο=1
Μέθοδος Φόρμα1,"Show", 1
Όρισε Φόρμα1 Τίποτα

Στο παρακάτω παράδειγμα έχουμε βάλει μια ιδιότητα που παίρνει μια παράμετρο, και φαίνεται σαν πίνακας, την Λιστ1$(). Αυτή μπορεί να παίρνει τιμές ή να δίνει τιμές. (ότι όνομα  θέλουμε βάζουμε, ακόμα και με τελεία, δηλαδή το Λιστ1.Λιστα$() θα ήταν αποδεκτό. Εδώ έχουμε επιπλέον μια προσθήκη στη λίστα με τη μέθοδο Add, και μια αλλαγή εμφάνισης στο στοιχείο της λίστας 0.
Προστέθηκε και η ιδιότητα Find η οποία λειτουργεί σαν συνάρτηση και επιστρέφει τιμή βάσει ενός αλφαριθμητικού που μπορεί να έχει χαρακτήρες όπως * και ? και άλλους (δείτε την ~ στα αλφαριθμητικά, είναι η Like της Visual Basic 6)
Επίσης μπήκε μια Αν Αληθές Τότε {} για να το δούμε και χωρίς το Αληθές, με Ψευδές,όπου στην μια περίπτωση κάνουμε ταξινόμηση και επιλέγουμε τη Θεσαλλονίκη, που εδώ δεν αλλάζει θέση, αλλά θα μπορούσε να αλλάξει, και στην άλλη απλά επιλέγουμε απευθείας το στοιχείο 1 (το δεύτερο).

Όρισε Φόρμα1 Φόρμα
Όρισε Λίστ1 Λίστα Φόρμα Φόρμα1
Μέθοδος Λίστ1, "move", 2000,1000,4000,3000
Με Λίστ1, "ShowAlways",Αληθές,"text",{Αθήνα
                                    Θεσσαλονίκη
                                    Πάτρα
                                    }
Με Λιστ1, "Listindex" ως Επιλεγμένο, "List" ως Λιστ1$(), "Find" ως Λιστ1Εύρεση()
Συνάρτηση Λιστ1.Click {
      Τύπωσε Επιλεγμένο, Λιστ1$(Επιλεγμένο)
      Ανανέωση
}
Συνάρτηση Λιστ1.Scroll {
      Τύπωσε Επιλεγμένο, Λιστ1$(Επιλεγμένο), "Ολίσθηση"
      Ανανέωση
}
Συνάρτηση Φόρμα1.click {
     τοπική Μ=Λιστ1Εύρεση("Π*")
    Αν Μ>-1 τότε Επιλεγμένο=Μ
}
Μέθοδος Λιστ1, "Add", "Καβάλα"
Λίστ1$(0)="*Αθήνα*"
Αν Αληθές Τότε {
      Μέθοδος Λιστ1, "Sort"
      Επιλεγμένο=Λιστ1Εύρεση("Θ*")
} Αλλιώς Επιλεγμένο=1
Μέθοδος Φόρμα1,"Show", 1
Όρισε Φόρμα1 Τίποτα


Με τα παραπάνω είδαμε πώς βάζουμε ονόματα ή ότι άλλο θέλουμε στη λίστα, πως βλέπουμε αν κάτι αλλάξει σε αυτή, πώς αλλάζουμε κάτι σε αυτήν, πως ταξινομούμε και πώς βρίσκουμε ένα στοιχείο μετά την ταξινόμηση για να το θέσουμε ως επιλεγμένο. Η ταξινόμηση έχει προαιρετικά μια ακόμα παράμετρο που λέει πόσους χαρακτήρες αν αφήσει από τα αριστερά κατά τις συγκρίσεις. Έτσι αν αριστερά είχαμε έναν αριθμό σε κάθε γραμμή με σταθερό πλάτος θα μπορούσαμε να ταξινομούμε βάσει του κειμένου μετά τον αριθμό.

Αυτό που δεν έχουμε δει είναι το γεγονός dblclick, το οποίο παράγεται όταν κάνουμε κλικ στο επιλεγμένο, ή όταν το τραβάμε δεξιά, ή όταν πατάμε Enter.  Εδώ καλούμε το γεγονός και προγραμματιστικά όταν κάνουμε κλικ στη φόρμα, με μια κάλεσε τοπικά (η κάλεσε τοπικά βλέπει συναρτήσεις που ανήκουν στο τρέχον τμήμα ή συνάρτηση, και τις καλεί ως τμήμα - αν υπάρχει επιστροφή με = τότε θα το δει ως λάθος με το νούμερο της επιστροφής, οπότε δεν βάζουμε σε αυτές τις συναρτήσεις εξυπηρέτησης γεγονότων το = τιμή...)
Γιατί υπάρχει ξεχωριστό γεγονός, ενώ όπως είδαμε πριν μας βόλευε και τα Click και Scroll; Η απάντηση είναι ότι αυτό το γεγονός είναι το σημαντικό, ενώ τα άλλα απλά βολεύουν ορισμένες φορές όπου η χρήση τους είναι για να αλλάζουμε κατάσταση σε άλλα στοιχεία, πριν γίνει η όποια "σημαντική" επιλογή.

Όρισε Φόρμα1 Φόρμα
Όρισε Λίστ1 Λίστα Φόρμα Φόρμα1
Μέθοδος Λίστ1, "move", 2000,1000,4000,3000
Με Λίστ1, "ShowAlways",Αληθές,"text",{Αθήνα
                                    Θεσσαλονίκη
                                    Πάτρα
                                    }
Με Λιστ1, "Listindex" ως Επιλεγμένο, "List" ως Λιστ1$()
Συνάρτηση Λιστ1.DblClick {
      Τύπωσε Επιλεγμένο, Λιστ1$(Επιλεγμένο), "Διπλό κλικ"
      Ανανέωση
}
Συνάρτηση Λιστ1.Click {
      Τύπωσε Επιλεγμένο, Λιστ1$(Επιλεγμένο)
      Ανανέωση
}
Συνάρτηση Λιστ1.Scroll {
      Τύπωσε Επιλεγμένο, Λιστ1$(Επιλεγμένο), "Ολίσθηση"
      Ανανέωση
}
Συνάρτηση Φόρμα1.Click {
      Επιλεγμένο=2
      Κάλεσε Τοπικά Λιστ1.DblClick()
}
Επιλεγμένο=1
Μέθοδος Φόρμα1,"Show", 1
Όρισε Φόρμα1 Τίποτα


 Στο παρακάτω παράδειγμα θα δούμε πώς γίνεται με απλό τρόπο να φτιάξουμε μια λίστα πολλαπλών επιλογών (θα επιλέγουμε πόλεις), με χρήση μιας λίστας και με σύμβολο το τικ. Επίσης δείχνει πως έχουμε και μια φόρμα με αλλαγή μεγέθους (ώστε να αλλάζουμε μέγεθος και να αλλάζει θέση μια φράση πίσω από τη λίστα, την οποία έχουμε διάφανη).

Όρισε Φόρμα1 Φόρμα
Με Φόρμα1, "Title" Ως ο_Τίτλος_μου$
Επίπεδο Φόρμα1 {
      Διάστιχο 60
      Γραμματοσειρά "Arial Black"
      Παράθυρο 16, 8000,6000
      Οθόνη 1,0
      Δρομέας 0, Ύψος δια 2
      Αναφορά 2,"Γειά σου Κόσμε"
}
Όρισε Λίστ1 Λίστα Φόρμα Φόρμα1
Μέθοδος Λίστ1, "move", 1000,1000,6000,4000
Με Λίστ1,"Text",{London
                                    Paris
                                    Athens
                                    Rome
                                    Tirana
                                    Nicosia
                                    Brussels
                                    Copenhagen
                                    Berlin
                                    Dublin
                                    Luxembourg
                                    }
Με Λίστ1, "transparent", Αληθές , "ListIndex" Ως Που
Με Λίστ1, "Find" Ως Βρες()
Με Λίστ1, "List" Ως Λίστα$()
Μέθοδος Φόρμα1, "Show"
Με Φόρμα1,"Sizable", Αληθές, "SizerWidth", 90
Συνάρτηση Λιστ1.Color {
      Διάβασε Νέο &rgb
            rgb=#FF7700
}
Συνάρτηση Λιστ1.DblClick {
            Διάβασε Τι
            Αν Δεξί$(Λίστα$(Τι),1)="✓" Τότε {
                  Λίστα$(Τι)=ΑριστερόΜέρος$(Λίστα$(Τι)+" "," ")
            } Αλλιώς {
                  Λίστα$(Τι)=ΑριστερόΜέρος$(Λίστα$(Τι)+" "," ")+" ✓"
            }
            Μέθοδος Λίστ1,"Refresh"
            ο_Τίτλος_μου$= Λίστα$(Τι)
}
Συνάρτηση Φόρμα1.click {
            Αν Που>=0 Τότε {
                  local K$=Λίστα$(Που), i
                  Μέθοδος Λίστ1,"Sort"
                  Που=Βρες(K$)
                  Επίπεδο {
                        Τύπωσε ">>", φορμα$
                        Ανανέωση
                  }
            } Αλλιώς Μέθοδος Λίστ1,"Sort"
}
Συνάρτηση Φόρμα1.Resize {
      Επίπεδο Φόρμα1 {
            Τύπος 16
            Οθόνη 1,0
            Δρομέας 0, Ύψος δια 2
            Αναφορά 2,"Γειά σου Κόσμε"
            Μέθοδος Λίστ1,"Refresh"
      }
}
Μέθοδος Φόρμα1, "Show", 1
Όρισε Φόρμα1 Τίποτα



Στο παράδειγμα παρακάτω χρησιμοποιούμε μια Κατάσταση και έχουμε ορίσει ότι θα έχει η λίστα 1000 στοιχεία. Κάθε στοιχείο μπορεί να υπάρχει ή όχι στην Κατάσταση (λίστα με κλειδί και τιμή). Αν δεν υπάρχει εμφανίζει κενή γραμμή. Με το Enter, ή με σπρώξιμο της γραμμής δεξιά, αλλάζει σε λίστα εισαγωγής και το ανάποδο, σε λίστα που προβάλει τα στοιχεία. Κάθε φορά που μετακινείται ο δρομέας της λίστας εμφανίζεται η τιμή (η γραμμή) στον τίτλο της φόρμας. Δείτε ότι η λίστα είναι σε κατάσταση διόρθωσης, τα πλήκτρα Home και End δουλεύουν για τη γραμμή, ενώ όταν γυρίσουμε σε προβολή για τη λίστα (με το End πάμε στο τελευταίο στοιχείο άμεσα). Η ιδιότητα HideCaret μπήκε πριν μερικές αναθεωρήσεις. Επειδή η ιδιότητα Edit αλλάζει την προβολή της Caret, με αληθές βγάζει επιλογή της γραμμής και βάζει την κάθετη γραμμή του δρομέα εισαγωγής, και στην αλλαγή σε ψευδές απλά αφαιρεί την κάθετη γραμμή, χρειάζεται να δώσουμε στην HideCaret τιμή Ψευδές, οπότε ανοίγει την επιλογή με χρωματισμό όλης της γραμμής.

Όρισε Φόρμα1 Φόρμα
Όρισε Λιστ1 Λίστα Φόρμα Φόρμα1
Κατάσταση Α=999:="Τέλος"
Προσθήκη Α, 0:="Πρώτο",3:="στο 3", 4:="στο 4"
Μ=Αληθές
Με Φόρμα1, "Title" ως Τιτλος$
Με Λιστ1, "Edit" ως Διόρθωση, "HideCaret" ως ΚρύψεΕπιλογή, "Listindex" ως Ποιο
Συνάρτηση Λιστ1.Scroll {
      Αν Υπάρχει(Α, Ποιο) Τότε {
             Τιτλος$=Μορφή$("{0::-4}:{1}",Ποιο, Εκφρ$(Α))
      } Αλλιώς Τιτλος$=Μορφή$("{0::-4}:",Ποιο)
}
Συνάρτηση Λιστ1.Click {
      Αν Υπάρχει(Α, Ποιο) Τότε {
             Τιτλος$=Μορφή$("{0::-4}:{1}",Ποιο, Εκφρ$(Α))
      } Αλλιώς Τιτλος$=Μορφή$("{0::-4}:",Ποιο)
}
Συνάρτηση Λιστ1.DblClick {
       Διόρθωση=Μ
       Αν Μ Αλλιώς ΚρύψεΕπιλογή=Μ
       Μ~

}
Συνάρτηση Λιστ1.ListCount {
      Διάβασε Νέο &πόσα
      πόσα=1000
}
Συνάρτηση Λιστ1.External {
      Διάβασε Νέο Που, &τι$
      Αν Υπάρχει(Α, Που) Τότε {
            τι$=Εκφρ$(Α)
      } Αλλιώς τι$=""
}
Συνάρτηση Λιστ1.ValidList {
       Διάβασε Νέο &περιεχ$, &θεσηΧ, &στοιχειο
      Αν Υπάρχει(Α, στοιχειο) Τότε {
            Επιστροφή Α, στοιχειο:=περιεχ$
      } Αλλιώς.Αν περιεχ$<>"" Τότε Προσθήκη Α, στοιχειο:=περιεχ$
    
}
Με Λιστ1, "External", Αληθές, "DisplayLines", 5
Μέθοδος Λίστ1, "move", 2000,1000,4000,3000
Μέθοδος Φόρμα1,"Show", 1
Όρισε Λιστ1 Τίποτα
Όρισε Φόρμα1 Τίποτα




Δείτε επίσης το πρόγραμμα - παράδειγμα εδώ  όπου συνδέουμε δυο λίστες, η μια δουλεύει με εξωτετικό πίνακα, και λειτουργούν ως εξής: Όταν μετακινούμε την επιλογή στη μια, μετακινείται και στην άλλη, είτε η μετακίνηση γίνει με τα βελάκια, είτε με το ροδελάκι, είτε με την μπάρα ολίσθησης (εμφανίζεται αυτόματα όταν πάμε το δείκτη του ποντικού πάνω από την περιοχή της). Για να το πετύχουμε αυτό χρειάζεται να παίρνουμε ένα γεγονός Move που δίνει την νέα πάνω γραμμή (από εκεί που ξεκινάει και εμφανίζει τις γραμμές η Λίστα). Επειδή μπορεί να μην συμβεί αυτό το γεγονός, δηλαδή να μην χρειαστεί να αλλάξει η πάνω γραμμή, χειριζόμαστε και άλλα γεγονότα όπως το Click και το Scroll. Ένα ακόμα πράγμα χρειαζόμαστε, να μπορούμε να επιλέγουμε στο δίπλα στοιχείο χωρίς να παίρνει εντολή για επανασχεδιασμό, επειδή θα το δώσουμε με την εντολή τοποθέτησης νέας πάνω γραμμής. Υπάρχει λοιπόν το ListIndex2 το οποίο μόνο διαβάζει, και κάνει νέα επιλογή στη λίστα "αθόρυβα". Στα στοιχεία είναι χρήσιμο να εκτελούμε διαδοχικές εντολές σε αυτά χωρίς να γίνεται άμεσα ανανέωση, για δυο λόγους. Ένας λόγος γιατί κάθε ανανέωση συχρονίζεται με την ανανέωση της φόρμας άρα μπαίνει καθυστέρηση, που μπορεί να φθάσει το μέγιστο του διαστήματος αυτόματης ανανέωσης, και ο δεύτερος γιατί θα δείχνουμε κάτι που δεν έχει ολοκληρωθεί, και θα προκαλεί γρήγορες εναλλαγές, σαν τρεμόπαιγμα (flickering), το οποίο δεν είναι καλαίσθητο.