PDA

View Full Version : [Vb6]Creare una specie di orologio


Alby2691
21-04-2009, 20:06
Ciao a tutti, sto provando a creare un programma in visual basic 6 che da quando viene cliccato il pulsante "Start" comincia a contare il tempo (hh-mm-ss) e in contemporanea, partendo da 14m e 59s, mi scali quel tempo fino a 0m e 0s dove, a quel punto, aumenta di uno un contatore, e ricomincia a scalare il tempo da 0. Sono riuscito a scrivere una gran parte di codice e gira tutto bene......per i primi 5/6 minuti, dopodichè il conteggio del tempo incomincia ad avere 2 secondi in meno, e il contdown dei 15m ad essere 2 secondi sopra il normale(ho usato un cronometro per controllare). Ho cercato un paio di soluzioni ma il codice mi sembra giusto cosi. Quindi chiedo a voi esperti se sapete risolvere questo problema. Oppure se conosciete un altro metodo per costruire questo programma ^^

Metto in spiler il codice che ho scritto :

Dim th As Long 'tempo in ore per ogni sessione
Dim tm As Long 'tempo in minuti per ogni sessione
Dim ts As Long 'tempo in secondi per ogni sessione
Dim sc As Long 'contatore degli scatti
Dim tm2 As Long 'tempo in minuti per contare gli scatti
Dim ts2 As Long 'tempo in secondi per contare gli scatti
Dim tm3 As Long 'tempo in minuti per calcolare tempo residuo
Dim ts3 As Long 'tempo in secondi per calcolare tempo residuo

Private Sub cmdstart_Click()
Timer1.Enabled = True
Timer2.Enabled = True
Timer3.Enabled = True
End Sub

Private Sub cmdstop_Click()
Timer1.Enabled = False
Timer2.Enabled = False
Timer3.Enabled = False
End Sub


Private Sub Form_Load()
Timer1.Enabled = False
Timer2.Enabled = False
Timer3.Enabled = False
th = 0
tm = 0
ts = 0
tm2 = 0
ts2 = 0
tm3 = 14
ts3 = 60
sc = 1
End Sub


Private Sub timer1_timer()

ts = ts + 1
If ts = 59 Then
tm = tm + 1
ts = 0
End If
If tm = 59 Then
th = th + 1
tm = 0
End If

lbltempom.Caption = tm & "m"
lbltempos.Caption = ts & "s"
lbltempoh.Caption = th & "h"

End Sub
Private Sub Timer2_Timer()
ts2 = ts2 + 1
If ts2 = 60 Then
tm2 = tm2 + 1
ts2 = 0
If tm2 = 15 Or tm2 = 30 Or tm2 = 45 Or tm2 = 60 Then
sc = sc + 1
End If
End If
If tm2 = 60 Then
tm2 = 0
End If
lblscatti.Caption = sc
End Sub

Private Sub Timer3_Timer()
lbltemporimm.Caption = tm3 & "m"
lbltemporims.Caption = ts3 & "s"

ts3 = ts3 - 1
If ts3 = 0 Then
lbltemporims = ts3 & "s"
tm3 = tm3 - 1
If tm3 = -1 Then
tm3 = 2
End If
ts3 = 60
End If
If tm3 = 0 And Not ts3 = 0 Then
lbltemporimm.Caption = 0
End If

lbltemporimm.Caption = tm3 & "m"
lbltemporims.Caption = ts3 & "s"

End Sub

wingman87
21-04-2009, 20:12
Ciao, il problema penso sia dovuto al fatto che i timer non sono perfetti, nel senso che se metti un timer che scatta ogni secondo in realtà questo scatterà a volte dopo 1000 ms, a volte dopo 1002 ms, e così via. C'è un margine di errore. Per un programma del genere dovresti sincronizzarti con l'orologio di sistema. Non so come si fa in VB6, comunque dovresti cercare informazioni in questo senso.

MarcoGG
22-04-2009, 08:39
Piccolo esempio : poniamo di avere una semplice Form con questo codice :

Private startDate As Date
Private secAuto As Integer
Private secSys As Integer

Private Sub cmd_start_Click()
secAuto = 0
secSys = 0
startDate = Now
Timer_auto.Enabled = True
Timer_sys.Enabled = True
End Sub

Private Sub Timer_auto_Timer()
secAuto = secAuto + 1
lbl_auto.Caption = secAuto
End Sub

Private Sub Timer_sys_Timer()
secSys = DateDiff("s", startDate, Now)
lbl_sys.Caption = secSys
End Sub

Timer_auto segna il tempo "per conto suo", mentre Timer_sys lo segna interrogando ogni secondo la data di sistema. Entro i primi 3 minuti i due timer hanno già una differenza di 1 secondo.
Se vuoi essere sempre sincronizzato col sistema usa il secondo metodo ( Timer_sys ). Inoltre non è necessario tenere a 1000 l'intervallo del Timer_sys, ma dal momento che l'incremento viene sempre fatto sul confronto con il Timer di sistema, si possono usare intervalli più precisi ( 50 ... ). ;)

Alby2691
22-04-2009, 14:01
ah, grazie mille ho capito ^^

Però non ho mai usato la funziona DateDiff, infatti se faccio un form come quello che riporti tu mi da errore. Non è che devo mettere qualche API per usare DateDiff ?

MarcoGG
22-04-2009, 14:48
ah, grazie mille ho capito ^^

Però non ho mai usato la funziona DateDiff, infatti se faccio un form come quello che riporti tu mi da errore. Non è che devo mettere qualche API per usare DateDiff ?

No, DateDiff è proprio una funzione VB6 standard. Molto strano come errore...
Sicuro di aver fatto tutto come nell'esempio ?

Alby2691
22-04-2009, 20:02
Si ho fatto tutto uguale, ovvimante ho fatto anche le rinominazioni adeguate.

L'errore che mi da è Run-time error:"6" owerflow, evidenziando di giallo questa riga di codice secSys = DateDiff("s", startDate, Now)

ho provato a cambiare secSys da Integer a Long, Date, Variant, Double e Single:mc: . Con alcuni di questi tipi di dati non da errore ma nella label appaiono numeri senza senso che non sembra centrino con data o ora. ( almeno a un inesperto come me sembrano senza senso :D )

Ho visto nella guida online di MSDN la descrizione sulla funzione DataDiff() ma non ci ho capito molto. Forse se riuscissi a far girare il codice che hai scritto potrei capire molto meglio :help: :help:

MarcoGG
22-04-2009, 21:40
Si ho fatto tutto uguale, ovvimante ho fatto anche le rinominazioni adeguate.


Prova il mio codice così com'è in un nuovo progetto, senza fare rinominazioni o modifiche e vedrai che gira. Forse nelle rinominazioni hai combinato qualcosa...
Inoltre la funzione da dare in pasto alla DateDiff è Now, che prende tutta la data di sistema corrente comprese H, min e sec.
Se ad esempio usi Date ( che ottiene solo la data senza orario ), ovviamente il metodo va in Overflow.
Successivamente lo puoi adattare, ma rispettando sempre la condizione DateDiff ( "s", dataDiPartenza, dataAttuale ), ove "s" = differenza tra date espressa in secondi / dataDiPartenza e dataAttuale sono date pure, complete della parte oraria, perciò niente formattazioni.

Alby2691
23-04-2009, 16:14
Certo cose proprio nn le capisco. Avevo già compilato il tuo codice in un progetto nuovo e fino a ieri non andava. Oggi lo avvio senza modificare nulla e funziona :confused: :confused: .

Comunque grazie, ora dovrei essere in grado di compilare il programma. Però se ho problemi torno subito qui :D :D :D :D

Grazie ancora ;)

P.S Conosci mica l'API per ridurre il programma nella barra delle attività ? su internet non ho trovato nulla :muro:

P.S.2 Sai mica se c'è una qualche funzione o API (più probabilmente) per far riconoscere al programma quando una connessione a internet viene stabilita o viceversa ? :)

MarcoGG
23-04-2009, 17:03
P.S Conosci mica l'API per ridurre il programma nella barra delle attività ? su internet non ho trovato nulla :muro:


Avevo già risposto su questo argomento a qualcuno, ma al momento non ricordo il Thread... Intanto guarda qui, c'è un tutorial :
http://www.trap17.com/index.php/tutorial-visual-basic-6-minimize-tray_t6940.html


P.S.2 Sai mica se c'è una qualche funzione o API (più probabilmente) per far riconoscere al programma quando una connessione a internet viene stabilita o viceversa ? :)


Dovrebbe essere questa se non sbaglio :
Private Declare Function InternetGetConnectedState Lib "wininet" (ByRef dwflags As Long, ByVal dwReserved As Long) As Long
Tu che dici ? :D

Alby2691
23-04-2009, 17:28
Grandissimo !!! :D :D :D
Sei un genio =P

Però i problemi ci sono sempre, ora sto riguardando bene il codice per minimizzare nella try perchè fino ad ora mi da un errore (Compile error : ByRef argument type mismatch) e mi evidenzia "Sub minimize_to_tray()" e anche "Shell_NotifyIcon NIM_ADD, nid"

Per la API della connessione....non so come inserirla in una IF. Ho provato a fare "If InternetGetConnectedState = true then" ma immagino che sia una gran castroneria.

Grazie ancora, ora vedo di gaurdare per bene la "guida"

EDIT : come immaginavo. L'errore della try non si ripresenta in un progetto nuovo >.<
EDIT2: Grazie mille. Ho quasi terminato il programma col tuo aiuto, mi manca solo una piccola parte. Al posto del tasto Start e dello Stop vorrei usare l'API della connessione. Mi spiego meglio : vorrei mettere un timer2 con intervallo 1(per essere il più preciso possibile) nel quale scrivo una condizione dove controllo se la connessione a internet è attiva. Se è attiva il timer1 parte. Se si disattiva il timer1 viene disabilitato. Solo che non so come scrivere in codice questa condizione. :help::help::help::help:

MarcoGG
23-04-2009, 22:39
vorrei mettere un timer2 con intervallo 1(per essere il più preciso possibile) nel quale scrivo una condizione dove controllo se la connessione a internet è attiva. Se è attiva il timer1 parte. Se si disattiva il timer1 viene disabilitato. Solo che non so come scrivere in codice questa condizione. :help::help::help::help:


1. Fossi in te non lo farei. Un Timer che esegue codice non banale ( e interrogare il sistema sullo stato della connessione attraverso API Call non lo è ) con Interval=1 rischia di disfunzionare... Secondo me 1 msec non ti serve, vanno benissimo ad es. 100 msec.

2. Dai senz'altro un'occhiata a questa implementazione della InternetGetConnectedState, valida e completa :
http://vbnet.mvps.org/index.html?code/network/internetgetconnectedstate.htm