Τετάρτη, 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