Πέμπτη, 22 Φεβρουαρίου 2018

Ανανεωμένο Παράδειγμα Παραθύρων

Κατά την αναθεώρηση του Μικρού Εγχειριδίου (θα βγει κάποια στιγμή με ημερομηνία >= 22-2-2018), έκανα ανανέωση στο παρακάτω πρόγραμμα.

Αν την Τίτλος "Παράδειγμα", 0 την έχουμε σε εκτελέσιμη γραμμή (τώρα είναι στην Σημείωση), θα αφαιρέσει την κοσνόλα και θα ξεκινήσουμε με τρία παράθυρα.

Αν η ΘέασηΓεγονότων γίνει αληθής τότε τα μηνύματα από τα γεγονότα θα έρχονται πρώτα σε μια συνάρτηση Φορμα100() θα μας τα εμφανίζει στην κονσόλα και θα τα καλεί μετά. (Εξαιρούνται μηνύματα που επιστρέφουν τιμές, όπως το unload)

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

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

Παράλληλα εμφανίζουμε την ώρα στην κονσόλα κάθε δευτερόλεπτο (Κάθε 1000 σημαίνει κάθε 1000 χιλιοστά του δευτερολέπτου).

Στη φόρμα με την "ζωγραφική γραμμών" τα δυο πλήκτρα ελέγχουν το νήμα για την ώρα. Το ένα το σταματάει και το άλλο το εκκινεί.

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

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

Η πρώτη εντολή Οθόνη,0 καθαρίζει τη οθόνη της κονσόλας και θέτει στην πρώτη γραμμή την "χωριστή οθόνη" ή "split screen". Η κοσνόλα έχει ένα σταθερό μέρος και ένα που ολισθαίνει στο κάτω μέρος. Αυτό καθορίζεται από μια γραμμή και έτσι με το 0 λέμε όλη η οθόνη να ολισθαίνει. Αυτό ισχύει και σε κάθε φόρμα, γιατί κάθε φόρμα έχει μια "οθόνη". Η διαφορά της οθόνης στη φόρμα είναι ότι δεν δέχεται εντολές εισαγωγής, πρέπει να χρησιμοποιήσουμε τα στοιχεία ελέγχου.

Όπως γίνεται φανερό στη Μ2000 μπορούμε να έχουμε ταυτόχρονα Κονσόλα και Παράθυρα. Αυτό συμβαίνει γιατί η κονσόλα είναι και αυτή ένα παράθυρο αλλά έχει διαφορετικό χειρισμό (δεν έχει γεγονότα)

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

Η εντολή Επίπεδο στέλνει εντολές οθόνης στο επιλεγμένο επίπεδο (οθόνη στην ουσία). Κάθε φόρμα έχει δικό της επίπεδο και εκεί δίνουμε τις εντολές για γραφικά. Όταν φτιάχνουμε ένα νήμα τότε το νήμα κρατάει το επίπεδο στο οποίο φτιάχτηκε και έτσι όλες οι εντολές προς την οθόνη πάνε σε αυτό το επίπεδο. Αν θέλουμε να αλλάξουμε πρόσκαιρα επίπεδο μπορούμε να βάλουμε την εντολή Επίπεδο. Αν σε αυτήν δεν δώσουμε το επίπεδο που θέλουμε τότε εννοείται ότι είναι η κονσόλα. Η εντολή ανανέωση χρειάζεται για να ανανεώνει τις αλλαγές της οθόνης όταν η συγκεκριμένη οθόνη (ή επίπεδο) δεν βρίσκεται στο προσκήνιο (είναι μια πίσω φόρμα μη επιλεγμένη). Ουσιαστικά το σύστημα των παραθύρων έχει διπλή μνήμη, μια που εμφανίζεται άμεσα και μια που παίρνει τις αλλαγές μέχρι να γίνει αυτόματα ή μη η ανανέωση. Οι ανανεώσεις είναι "χρονοβόρες" και ο έλεγχός τους είναι καλός για να ετοιμάζουμε κάτι γρήγορα και μετά να το δείχνουμε. Μπορούμε πρόσκαιρα να αλλάξουμε τον χρόνο επόμενης ανανέωσης με μια Ανανέωση 5000 (βάζουμε την επόμενη σε 5 δευτερόλεπτα) και αφού κάνουμε ότι θέλουμε (χωρίς να φανεί) σε ένα επίπεδο καλούμε την Ανανέωση 100 για να εμφανίσει τα γραφικά, μέχρι την επόμενη φορά που θα χειριστούμε πάλι την ανανέωση. Εδώ δεν χρειάζεται κάτι τέτοιο και απλά η Ανανέωση καλείται χωρίς αριθμό.






Οθόνη,0
\\ αν δεν θέλουμε να βλέπουμε τη κονσόλα, μπορούμε να την κρύψουμε!
\\ αν ξεκινήσουμε το πρόγραμμα από gsb αρχείο, τότε η κονσόλα δεν ανοίγει
\\ χωρίς της εντολή Άναψε
\\ Μετά το Σημ 1 : πατήστε Enter για να μπει η Τίτλος σε εκτελέσιμη γραμμή!
Σημ 1 : Τίτλος "Παράδειγμα", 0
Ν=3
ΘέασηΓεγονότων= Ψευδές \\Αληθές
\\ Με την ΘέασηΓεγονότων=Αληθές το σύστημα στέλνει μηνύματα στο γεγονός Βασικό
\\ το οποίο δημιουργεί στον ορισμό της φόρμας.
\\ Σε αυτό συνδέουμε μια συνάρτηση (στην ουσία ένα μέρος του τμήματος)
\\ που καλείται κάθε φορά που συμβαίνει ένα γεγονός.
\\ Γεγονότα που ζητούν επιστροφή τιμής (όπως το unload) δεν στέλνονται σε αυτό.

Αν ΘέασηΓεγονότων Τότε {
      Όρισε Φόρμα1(Ν) Φόρμα Γεγονός Βασικό
} Αλλιώς Όρισε Φόρμα1(Ν) Φόρμα
Κλάση Πλήκτρα {
      Πίνακας Πληκτρο()
}
Πίνακας Στοιχεία(Ν)=Πλήκτρα()

Για ι=0 Έως Ν-1 {
      Για Στοιχεία(ι) {
            Όρισε Πλήκτρο1(2) Πλήκτρο Φόρμα Φόρμα1(ι)
            Για j=0 Έως 1 {
                  Μέθοδος Πλήκτρο1(j), "move", 1000+4000*j, 2000,3000,1000
            }
            .Πληκτρο()=Πλήκτρο1()
      }
     Επίπεδο Φόρμα1(ι) {
            Φόντο 1,4
            Δρομέας 0,2
            Αναφορά 2, "Γεια χαρά"
            Κίνηση.Π 2000+ι*3000, 2000+ι*3000
     }
      Μέθοδος Φόρμα1(ι), "Show"
}

Φόρμα1_1=Αληθές
Για Στοιχεία(0) {
      Με .Πληκτρο(0), "Caption","Έξοδος"
      Με .Πληκτρο(1), "Caption","Έξοδος"
}
Για Στοιχεία(1) {
      Με .Πληκτρο(0), "Caption","Σταμάτησε Εμφάνιση"
      Με .Πληκτρο(1), "Caption","Εμφάνιση Ώρας"
}
Για Στοιχεία(2) {
      Με .Πληκτρο(0), "Caption","Δείξει το πλήκτρο"
      Με .Πληκτρο(1), "Caption","Άνοίγμα Ελέγχου"
}
Με Φόρμα1(0), "visible" Ως θεατό

ΚλείσεΑυτήΤηΦόρμα=0
Συνάρτηση ΚλείσεΜετά {
      Αν Ρώτα("Να κλείσω τη Φόρμα?")=1 Τότε {
      Αν ΚλείσεΑυτήΤηΦόρμα=1 Τότε Φόρμα1_1=Ψευδές
      Μέθοδος Φόρμα1(ΚλείσεΑυτήΤηΦόρμα), "CloseNow"
      }
}

\\ το γεγονός Unload έχει κάτι ιδιαίτερο
\\ παίρνει πίσω την τιμή του άκυρο
\\ αυτό δεν έρχεται από το Γεγονός Βασικό (αν ορίσαμε να υπάρχει)
\\ αλλά απευθείας καλείται από τη φόρμα, για να πάρει "απόκριση"
Συνάρτηση Φόρμα1.Unload {
      Διάβασε Νέο ποιο, &άκυρο
      άκυρο=Αληθές \\ ακυρώνουμε το Unload
      ΚλείσεΑυτήΤηΦόρμα=ποιο
      \\ και καλούμε μετά 50 χιλιοστά του δευτερολέπτου
      \\ άλλη ρουτίνα ασύγχρονα - γιατί θα έχει πια τερματίσει το γεγονός
      \\ Η Μετά φτιάχνει ένα αυτόματο νήμα που εκτελείται μια φορά και σβήνει
      Μετά 50 { Κάλεσε Τοπικά ΚλείσεΜετά() }
}
Συνάρτηση Πλήκτρο1.Click {
      Διάβασε Κ, Λ
      Τύπωσε "Φόρμα:";Λ,"Πλήκτρο:";Κ
      Αν Ενημέρωση=0 τότε εξοδος
      Για Στοιχεία(Λ) {
           Με .Πληκτρο(Κ), "Caption"  Ως ονομα$
           Τύπωσε ονομα$
           Αν Κ=1 και Λ=2 Τότε {
                 Δοκιμή "Δες Κώδικα" \\ ανοίγει η φόρμα δοκιμής
                 Ανανέωση \\ αυτό για την κοσνόλα
          } Αλλιώς.αν Λ=1 τότε {
              Αν Κ=0 τότε {
                νήμα Ενημέρωση κράτα
                Τύπωσε "Η εμφάνιση ώρας σταμάτησε"
                Ανανέωση
                } Αλλιώς {
                Τύπωσε "Ξεκινώ την εμφάνιση ώρας"
                νήμα Ενημέρωση ξεκίνα
                  }
         } Αλλιώς.αν Λ=0 τότε {
               Δες {
                   \\ εκτελούμε την εντολή μέσα στο νήμα
                   \\ αν δεν υπάρχει βγάζει λάθος
                   \\ Δεν παίζει το Νήμα Ενημέρωση Σβήσε
                   \\ γιατί το νήμα  βρίσκεται σε άλλο αντικείμενο εκτέλεσης
                   \\ και όχι σε αυτό του γεγονότος
                   \\ το νήμα αυτό σβήσε ..καλεί άμεσα το νήμα και το σβήνει!
                   \\ μέσω του Task Manager της Μ2000
                   νήμα Ενημέρωση Εκτέλεση νήμα αυτό σβήσε
                   \\ όταν σβήσει το νήμα τότε το Κύριο Έργο θα τερματίσει υποχρεωτικά!
                  }
         }
     }
}
Συνάρτηση Φόρμα1.MouseMove {
      Διάβασε Κ, Πλήκτρο, πλ_shift, Χ, Υ
      Αν Πλήκτρο=1 Τότε {
           Επίπεδο Φόρμα1(Κ) {
                  Θέση Χ, Υ
                  Κύκλος 500, 1, 14-Κ
            }
      }
}
Συνάρτηση Φόρμα1.MouseDown {
      Διάβασε Κ, Πλήκτρο, Shift, Χ, Υ
      \\ εδώ θα μπούμε στα εσωτερικά της φόρμας
      \\ για να αφαιρέσουμε τον τίτλο
      \\ το πρώτο στοιχείο (0) είναι μια κουκίδα για την αλλαγή μεγέθους
      \\ το δεύτερο (1) είναι ο τίτλος και από εκεί συνεχίζουν όλα τα άλλα
      \\ και όλα είναι ίδια (εκτός της κουκίδας), το βασικό "εσωτερικό στοιχείο"
      \\ το πλήκτρο 2 είναι το δεξί πλήκτρο του ποντικιού
      Αν Πλήκτρο=2 Τότε {
                  Μέθοδος Φόρμα1(Κ), "Control", 1 Ως ΕσωτερικόΣτοιχείο
                  Με ΕσωτερικόΣτοιχείο, "visible" Ως εΘεατό
                  \\ δεν μπορούμε να χρησιμοποιήσουμε το εΘεατό~
                  \\ το εΘεατό δεν είναι μεταβλητή αλλά αντικείμενο proReference
                  \\ το βλέπουμε με το τυπος$(εΘεατό)
                  εΘεατό=όχι εΘεατό
      }
}
Συνάρτηση Φόρμα100 {
     Διάβασε ΚλήσηΓεγονότος$
    Τύπωσε ΚλήσηΓεγονότος$
     Δες { Κάλεσε Τοπικά ΚλήσηΓεγονότος$ }
}

\\\ εδώ ορίζουμε το γεγονός Βασικό να στέλνει την έξοδο σε μια συνάρτηση
\\ την βάζουμε με Οκν$() για να τρέχει σαν να είναι κώδικας του τμήματος
\\ ώστε να βρίσκει άλλες συναρτήσεις.
Αν ΘέασηΓεγονότων Τότε Γεγονός Βασικό Νέο Οκν$(&Φόρμα100())
Νήμα {
      Τύπωσε Γραφή$(Τώρα,"hh:mm:ss")
      Ανανέωση
} Ως Ενημέρωση Κάθε 1000

\\ εδώ είναι η κεντρική επανάληψη, η οποία είναι νήμα!
\\ ουσιαστικά δεν τρέχει κάτι εκτός νήματος
\\ εκτός το Φόρμα100 (που έχει το όνομα τμήματος - και όχι το ψεύτικο όνομα Φόρμα100)
\\ το οποίο εκτελεί τις παραγγελίες των γεγονότων (που δεν έχουν επιστροφή όπως το unload)
\\ Για να δουλέψει το Κύριο.Έργο χρειάζεται ένα τουλάχιστον νήμα εκτός από αυτό
\\ και έτσι έχουμε φτιάξει το Ενημέρωση (αυτή είναι μεταβλητή που κρατάει το νούμερο του νήματος)

Κύριο.Έργο 100 {

      Σημ 2 : Τύπωσε Τύπος$(θεατό), Τύπος$(Φόρμα1_1)
      Αν Όχι θεατό Τότε Έξοδος
  
      Αν Φόρμα1_1 Τότε {
             Επίπεδο Φόρμα1(1) {
                        Χάραξε Έως τυχαίος(χ.σημεία), τυχαίος(υ.σημεία)
            }
      }
}
\\ στην έξοδο το κύριο έργο σταματάει τα νήματα (αλλά όχι νήματα που ξεκίνησαν από νήματα)
\\ Μπορούμε να τα σβήσουμε όλα μαζί με την παρακάτω εντολή:
Νήματα Σβήσε
\\ το κύριο έργο βγαίνει εκτός αν σταματήσει το νήμα
\\  Καθαρισμός (ακόμα και αν τον ξεχάσουμε θα γίνει αυτόματα στην έξοδο από το τμήμα)
Για ι=0 Έως Ν-1 {
      Για Στοιχεία(ι) {
            Πίνακας .Πληκτρο()
      }
}
Όρισε Φόρμα1() Τίποτα
Τίτλος "Τέλος Παραδείγματος"
Άναψε  \\ επιστρέφει την Εστίαση στη κονσόλα