L 'orologio analogico e il calendario perpetuo |
Ho voluto terminare questa
guida di base con un esempio forse un pò troppo complesso, che però fa
vedere quanto potente possa essere il VB6: la creazione di un orologio
analogico e di un calendario perpetuo. L'esempio è stato realizzato
unendo alle funzioni data/ora e ai metodi delle picture anche un pò di
matematica. Dividiamo la trattazione in due parti:
1) Orologio analogico 2) Calendario perpetuo |
Orologio analogico |
Per prima cosa aggiungiamo i controlli Picture1, label 1, Timer1 al nuovo progetto, tralasciamo per ora i pulsanti di regolazione dell' orologio |
Cominciamo con il load del form |
Private Sub
Form_Load() 'valori iniziali per angolatura secondi,minuti,ore secondi = Second(Now()) minuti = Minute(Now()) ore = Hour(Now()) * 5 angolosecondi = 90 - secondi * 6 angolominuti = 90 - minuti * 6 angoloore = 90 - ore * 6 - 30 * minuti / 60 End Sub |
Le prime funzioni già le conosciamo; ci restituiscono secondi ,minuti, ore attuali. Le lancette di minuti e secondi hanno però un angolo iniziale; quando sono a zero formano un angolo di 90° con l'asse delle x, ed ogni secondo decrementano di 6° (infatti 360° corrispondono a 60 secondi o minuti). Differente è il discorso per per le ore; se ci pensate un pò su capirete la corrispondenza nella formula descritta. Ora per aggiornare la posizione delle lancette, usiamo l'evento timer che scatta ad ogni secondo: |
Private Sub Timer1_Timer() Label1.Caption = Format(Now(), "hh.mm.ss")'qui visualizziamo l'ora nella label If angolosecondi = -270 Then angolosecondi = 90 angolominuti = angolominuti - 6 End If angolosecondi = angolosecondi - 6 ' ad ogni secondo l'angolo diminuisce di 6° minuti = Minute(Now()) ore = Hour(Now()) * 5 angoloore = 90 - ore * 6 - 30 * minuti / 60 Call disegna(angolosecondi, angolominuti, angoloore) Picture1.Visible = True End Sub |
l' angolo secondi
decrementa di 6° ad ogni secondo; differente è il discorso per i
minuti che scattano di 6° ogniqualvolta la lancetta compie un giro
completo, cioè parte da 90° e arriva a -270°. Adesso non basta che
disegnare le lancette, usando la funzione Call
disegna(angolosecondi, angolominuti, angoloore) che come vedete
accetta in ingresso i tre angoli delle tre lancette. Per disegnare le
lancette usiamo il metodo line del controllo picture che disegna
una retta:
Picture1.Line (X1, Y1)-(X2, Y2), colore dove x1,y1 - x2,y2 sono le coordinate dei due punti della retta, nel sistema di coordinate che ha come origine l'angolo superiore sinistro della Picture. Attenzione: le x vanno da sinistra verso destra, mentre le y vanno dall'alto verso il basso. Disegniamo ora le tre lancette: |
Public Function disegna(gradi, minuti, ore) Picture1.Cls disegnaorologio 'disegna la parte fissa dell'orologio Dim a, b, c, d, e, f As Double pgreco = 3.14 a = 1200 * Sin(gradi * pgreco / 180) b = 1200 * Cos(gradi * pgreco / 180) Picture1.DrawWidth = 1 Picture1.Line (1250, 1250)-(1250 + b, 1250 - a), vbBlack 'lancetta secondi c = 1150 * Sin(angolominuti * pgreco / 180) d = 1150 * Cos(angolominuti * pgreco / 180) Picture1.DrawWidth = 3 Picture1.Line (1250, 1250)-(1250 + d, 1250 - c), &H808000 'lancetta minuti e = 850 * Sin(angoloore * pgreco / 180) f = 850 * Cos(angoloore * pgreco / 180) Picture1.DrawWidth = 5 Picture1.Line (1250, 1250)-(1250 + f, 1250 - e), &H808000 ' lancetta ore Picture1.DrawWidth = 8 Picture1.PSet (1250, 1250), vbBlack End Function |
Tralasciamo per ora la funzione disegna orologio che disegna le tacche dell'orologio, e soffermiamo la nostra attenzione sul disegno delle lancette |
Usiamo le funzioni sin e cos (seno e coseno) del Vb che però devono avere l'argomento in radianti: per questo usiamo la conversione * pgreco / 180 ; La proprietà DrawWidth ci permette invece di dare dimensione diversa alle lancette dove abbiamo anche specificato colori differenti. Per ultimo la funzione Picture1.PSet ci permette di disegnare un punto per il centro dell' orologio. Dobbiamo inoltre con il metodo Picture1.Cls cancellare la posizione precedente delle lancette. Analizziamo anche la funzione disegnaorologio: |
Public Sub disegnaorologio() Dim i Dim x As Double Dim y As Double Dim r For i = 1 To 360 Step 6 x = 1250 * Cos(i * pgreco / 180) y = 1250 * Sin(i * pgreco / 180) r = i Mod 5 If r = 1 Then Picture1.DrawWidth = 4 'dimensione del punto Picture1.PSet (1250 + x, 1250 - y), &H808000 'verde chiaro Else Picture1.DrawWidth = 2 'dimensione del punto Picture1.PSet (1250 + x, 1250 - y), vbWhite 'Bianco End If Next i End Sub |
Qui usiamo anche la funzione i Mod 5 che mi restituisce 1 ogni 5 minuti per disegnare di verde le tacche dei minuti (è il resto della divisione per 5) |
Regolazione
dell 'ora
La funzione time che restituisce l'ora di sistema, funziona anche all'incontrario, cioè serve anche per l'assegnazione. Per incrementare i secondi usiamo allora un pulsante con il seguente codice: |
Dim s As Integer Dim t t = Time s = Second(Time) Time = Hour(t) & "." & Minute(t) & "." & (s + 1) Mod 60 Label1.Caption = Format(Now(), "hh.mm.ss") secondi = Second(Now()) angolosecondi = 90 - secondi * 6 |
Come vedete leggiamo i secondi e li incrementiamo ad ogni click del pulsante, mantenendo costanti ore e minuti. Passiamo inoltre il nuovo angolo per la lancetta. Analogamente procediamo per modificare minuti e ore |
Private Sub Command4_Click() Dim m As Integer Dim t t = Time m = Minute(Time) Time = Hour(t) & "." & (m + 1) Mod 60 & "." & Second(Time) Label1.Caption = Format(Now(), "hh.mm.ss") minuti = Minute(Now()) angolominuti = 90 - minuti * 6 End Sub '-------------------------------------------------- Private Sub Command5_Click() Dim h As Integer Dim t t = Time h = Hour(Time) Time = (h + 1) Mod 24 & "." & Minute(t) & "." & Second(t) Label1.Caption = Format(Now(), "hh.mm.ss") secondi = Second(Now()) ore = Hour(Now()) * 5 minuti = Minute(Time) angoloore = 90 - ore * 6 - 30 * minuti / 60 End Sub |
2) Calendario perpetuo |
Per creare il calendario usiamo un concetto molto interessante, che è quello della matrice di controlli. Ormai sappiamo disegnare una label in ambiente di progettazione, ma come disegnare tutti i quadratini del calendario in esecuzione? E' infatti impensabile stare lì a disegnare decine e decine di quadratini. Creiamo allora una label di nome label e nella proprietà index scriviamo 0; abbiamo così creato una matrice di label (label(i)) ora le carichiamo all' avvio del programma, mettendo nel load del form la seguente funzione: |
Public Sub caricacalendario() Dim i As Integer Dim r As Integer Dim stpx As Integer stpx = 300 r = 1 Dim IND As Integer For r = 1 To 7 For i = 1 To 7 IND = i + (r - 1) * 7 Load Label(IND) With Label(IND) .Left = (i + 1) * stpx + 20 .Top = Label(0).Top * r + 20 .Visible = True .BorderStyle = 1 .Caption = "" End With Next i Next r For i = 1 To 7 Label(i).BackColor = &H808080 Label(i).ForeColor = vbWhite Next i Label(1).Caption = "L" Label(2).Caption = "M" Label(3).Caption = "M" Label(4).Caption = "G" Label(5).Caption = "V" Label(6).Caption = "S" Label(7).Caption = "D" For i = 8 To 49 Label(i).BackColor = vbWhite Next i End Sub |
La funzione
Load Label(IND) carica nel
form la label di indice IND ; ora possiamo modificare proprietà
e caption delle label accedendovi semplicemente con dei cicli for sull
'indice: per esempio nel ciclo for:
For i = 1 To 7 cambiamo il colore dei giorni della settimana facendoli apparire bianchi su sfondo grigio scuro. Una volta caricato il calendario, bisogna disegnarlo inserendo i giorni nel giusto posto della settimana: |
Public Sub disegnacalendario(data_i As Date) Dim g Dim m Dim a Dim data As Date If Month(data_i) < "10" Then m = "0" & Month(Date) Else m = Month(data_i) End If Dim giornoattuale As Integer giornoattuale = Day(data_i) data = "01/" & m & "/" & Year(data_i) Dim t t = Weekday(data) 'trova il giorno della settimana Select Case t Case 1 'domenica g = 7 Case 2 ' lunedì g = 1 Case 3 'martedì g = 2 Case 4 'mercoledì g = 3 Case 5 ' giovedì g = 4 Case 6 'venerdì g = 5 Case 7 'sabato g = 6 End Select Dim i For i = 8 To 49 Label(i).Caption = "" Label(i).ForeColor = vbBlack Label(i).BackColor = vbWhite Next i For i = 1 To numerogiorni(data) Label(i + 8 + g - 2).Caption = i If i = giornoattuale Then Label(i + 8 + g - 2).BackColor = &HC00000 Label(i + 8 + g - 2).ForeColor = vbWhite Else Label(i + 8 + g - 2).BackColor = vbWhite Label(i + 8 + g - 2).ForeColor = vbBlack End If Next i End Sub |
La funzione Weekday(data) restituisce il giorno della settimana (lunedì, martedi, ecc) sotto forma numerica; nella istruzione select vediamo la corrispondenza, e riusciamo a scrivere nella posizione giusta il primo giorno del mese; per sapere quanti giorni ha un mese usiamo la funzione numerogiorni(data): |
Public Function numerogiorni(data) As Integer Dim giorno As Date Dim f As Integer Dim m As Integer m = Month(data) f = 0 Do giorno = data + f If Month(giorno) <> m Then numerogiorni = f Exit Do End If f = f + 1 Loop End Function |
Partendo
dal primo giorno del mese incrementiamo il giorno finché non cambia
anche il mese; in f troviamo il numero di giorni e la assegniamo
alla funzione; Con l'istruzione condizionale::
If i = giornoattuale Then assegniamo al giorno attuale (giornoattuale = Day(data_i)) il colore Blue |
Consiglio di scaricare l'esempio analogico.zip per approfondire meglio. |
Torna all' indice |