Newsgroup: it.comp.lang.visual-basic
Titolo: [!] Barra avanzamento con visualizzazione tempo residuo (Lungo)

Oggi ho scritto una routinetta per visualizzare il tempo residuo stimato di
una operazione insieme alla classica barra di avanzamento. Ovviamente ci
arriva per approssimazioni successive, ma dopo un po' di iterazioni comincia
ad azzeccarci abbastanza.
Siccome magari interessa anche altri, la posto qui.
Bisogna creare un nuovo progetto, e nella Form1 inserire i seguenti
controlli:
Pulsante Command1
Timer Timer1
PictureBox Picture1 che contenga:
    Shape Shape1
    Label Label1
Non importano le posizioni e le dimensioni dei controlli. Ho appositamente
mantenuto i nomi di default cosě non c'č da fare una gran fatica.
Creato tutto il necessario, copiate dentro il codice seguente, mandate in
esecuzione e premete il pulsante Command1.
Nel caso il ciclo di esempio fosse troppo lento o troppo veloce per il
vostro PC, modificare il valore di GLO_MaxPosizioneFlood nella
Command1_Click.
Buon divertimento (ovviamente sono ben accetti commenti e correzioni)
----- Inizio -----
Option Explicit
Dim GLO_PosizioneFlood As Long
Dim GLO_MaxPosizioneFlood As Long
Dim GLO_LarghezzaFloodAttuale As Long
Dim GLO_dDataInizioOperazione As Date
Dim GLO_lSecondiResidui As Long
Private Sub Command1_Click()
   Dim r As Long
   GLO_PosizioneFlood = 0
   GLO_MaxPosizioneFlood = 5000000
   AggiornaPosizione True
   For r = 0 To GLO_MaxPosizioneFlood
      AvanzaFlood
      DoEvents
   Next
End Sub
Private Sub Form_Load()
   Shape1.BackStyle = 1
   Shape1.BackColor = vbBlue
   Label1.AutoSize = True
   Label1.ForeColor = vbRed
   Label1.BackStyle = vbTransparent
   Timer1.Interval = 1000
   Timer1.Enabled = False
   Me.WindowState = vbMaximized
End Sub
Private Sub Form_Resize()
   Picture1.Move 0, _
            Me.ScaleHeight - 30 * _
            Screen.TwipsPerPixelY, _
            Me.ScaleWidth, _
            30 * Screen.TwipsPerPixelY
   Command1.Move Int((Me.ScaleWidth - Command1.Width) / 2), 0
   RidisegnaTutto
End Sub
Private Sub RidisegnaTutto()
   Shape1.Move Screen.TwipsPerPixelX, _
               Screen.TwipsPerPixelY, _
               GLO_LarghezzaFloodAttuale, _
               Picture1.ScaleHeight - Screen.TwipsPerPixelY * 2
    Label1.Move Int((Picture1.ScaleWidth - Label1.Width) / 2), _
               Int((Picture1.ScaleHeight - Label1.Height) / 2)
End Sub
Sub RicalcolaTempoResiduoEAggiornaCaption(ByVal lSecondiResidui As Long, _
                        Optional ByVal iPosFlood As Integer = -1)
   Static OldiPosFlood As Long
   Dim lMinutiResidui As Long
   Dim lOreResidue As Long
   If iPosFlood = -1 Then
      iPosFlood = OldiPosFlood
   Else
      OldiPosFlood = iPosFlood
   End If
   lOreResidue = Int(lSecondiResidui / 3600)
   lMinutiResidui = Int((lSecondiResidui - lOreResidue * 3600) / 60)
   lSecondiResidui = lSecondiResidui Mod 60
   Label1.Caption = iPosFlood & "% - Tempo residuo stimato: " & _
         lOreResidue & IIf(lOreResidue = 1, " ora ", " ore ") & _
         lMinutiResidui & _
         IIf(lMinutiResidui = 1, " minuto e ", " minuti e ") & _
         lSecondiResidui & _
         IIf(lSecondiResidui = 1, " secondo.", " secondi.")
End Sub
Private Sub AggiornaPosizione(Optional bForzaRiscrittura As Boolean = False)
   Dim iPctFlood As Integer
   Dim lTempoPassatoInSecondi As Long
   Dim lTempoTotaleInSecondi As Long
   On Error Resume Next
   iPctFlood = Int((GLO_PosizioneFlood / GLO_MaxPosizioneFlood) * 100)
   On Error GoTo 0
   If iPctFlood > 100 Then
       iPctFlood = 100
       GLO_PosizioneFlood = GLO_MaxPosizioneFlood
   ElseIf iPctFlood < 0 Then
       iPctFlood = 0
       GLO_PosizioneFlood = 0
   End If
   GLO_LarghezzaFloodAttuale = _
         Int((Picture1.ScaleWidth * iPctFlood) / 100)
   If GLO_LarghezzaFloodAttuale > Shape1.Width Or bForzaRiscrittura Then
      If iPctFlood > 0 Then
         Timer1.Enabled = False
         On Error Resume Next
         lTempoPassatoInSecondi = _
               DateDiff("s", GLO_dDataInizioOperazione, Now)
         If Err > 0 Then
            On Error GoTo 0
            GLO_dDataInizioOperazione = Now
            lTempoPassatoInSecondi = _
                  DateDiff("s", GLO_dDataInizioOperazione, Now)
         End If
         lTempoTotaleInSecondi = _
               (lTempoPassatoInSecondi * 100) \ iPctFlood
         GLO_lSecondiResidui = _
               lTempoTotaleInSecondi - lTempoPassatoInSecondi
         RicalcolaTempoResiduoEAggiornaCaption GLO_lSecondiResidui, _
                                               iPctFlood
         If iPctFlood < 100 Then
            Timer1.Enabled = True
         End If
      Else
         Label1.Caption = iPctFlood & "%"
      End If
      RidisegnaTutto
   Else
      Timer1.Enabled = (iPctFlood > 0)
   End If
End Sub
Private Sub AvanzaFlood()
   If GLO_PosizioneFlood = 0 Then
      GLO_dDataInizioOperazione = Now
   End If
   GLO_PosizioneFlood = GLO_PosizioneFlood + 1
   AggiornaPosizione
End Sub
Private Sub Timer1_Timer()
   If GLO_lSecondiResidui > 0 Then
      GLO_lSecondiResidui = GLO_lSecondiResidui - 1
      RicalcolaTempoResiduoEAggiornaCaption GLO_lSecondiResidui
   End If
End Sub
----- Fine -----
Ciao
*Roby*

Siccome magari interessa anche altri, la posto qui.
Siccome interessa anche ad altri, perché non la pubblichi sul SC? :-)
Grazie, bel lavoro!
Ciao,
Moreno
-- 
#sirri#@#
morenosoft.com#
(togliete "#" dall'indirizzo)
Moreno Sirri VB Site - 
http://www.msvbsite.net
---------------------------------------------------------------------------
Le risposte alle tue domande le trovi sul Sito Comune di questo NewsGroup:
 
http://www.it-lang-vb.net
---------------------------------------------------------------------------

 
Occhio che se chiudi il form il programma non si chiude perché il ciclo
è ancora in esecuzione (questo è normale). Però non si chiude nemmeno
dopo che il ciclo è finito perché richiama il timer ricaricando il form.
-- 
Samuele Battarra
prova il mio newsreader:
http://digilander.iol.it/battarsa/programmi/news/

 dopo che il ciclo è finito perché richiama il timer ricaricando il form.
Vero. Per brevità non ho postato la parte dell'unload.
In realtà il tutto è un OCX autocontenuto, ma era troppo lungo per postarlo
qui.
Sto riflettendo sull'ipotesi di risistemarlo e metterlo sul sito comune.
Vedremo...
Ciao
*Roby*