Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Eleкtro

#2931
Si a todo esto también necesitas una solución completa para implementar ya sea un cronómetro o una cuenta atrás, aquí tienes una solución que ideé hace tiempo (nuevamente sacada de mi librería de clases ElektroKit):

Código (vbnet) [Seleccionar]
' ***********************************************************************
' Author   : Elektro
' Modified : 12-December-2015
' ***********************************************************************

#Region " Public Members Summary "

#Region " Constructors "

' New()

#End Region

#Region " Events "

' TimeUpdated(Object, TimeMeasurerUpdatedEventArgs)

#End Region

#Region " Properties "

' MaxValue As Double
' State As TimeMeasurerState
' UpdateInterval As Integer

#End Region

#Region " Methods "

' Start(Double)
' Start(Date, Date)
' Start(TimeSpan)
' Pause()
' Resume()
' Stop()
' Dispose()

#End Region

#End Region

#Region " Usage Examples "

#End Region

#Region " Option Statements "

Option Strict On
Option Explicit On
Option Infer Off

#End Region

#Region " Imports "

Imports System.ComponentModel
Imports System.Windows.Forms

' Imports Elektro.Core.DateAndTime.Enums
' Imports Elektro.Core.DateAndTime.Types.EventArgs
' Imports Elektro.Core.Types

#End Region

#Region " Time Measurer "

Namespace DateAndTime.Types

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Measures the elapsed and/or remaining time of a time interval.
   ''' The time measurer can be used as a chronometer or a countdown.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   <ImmutableObject(False)>
   Public NotInheritable Class TimeMeasurer :  Implements IDisposable ': Inherits AestheticObject

#Region " Private Fields "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' An <see cref="Stopwatch"/> instance to retrieve the elapsed time. (a chronometer)
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private timeElapsed As Stopwatch

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' A <see cref="TimeSpan"/> instance to retrieve the remaining time. (a countdown)
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private timeRemaining As TimeSpan

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' A <see cref="Timer"/> instance that updates the elapsed and remaining time,
       ''' and also raise <see cref="TimeMeasurer"/> events.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private WithEvents measureTimer As Timer

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Flag that indicates wheter this <see cref="TimeMeasurer"/> instance has finished to measure time interval.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private isFinished As Boolean

#End Region

#Region " Properties "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets the maximum time that the <see cref="TimeMeasurer"/> can measure, in milliseconds.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The maximum time that the <see cref="TimeMeasurer"/> can measure, in milliseconds.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Shared ReadOnly Property MaxValue As Double
           <DebuggerStepThrough>
           Get
               Return (TimeSpan.MaxValue.TotalMilliseconds - 1001.0R)
           End Get
       End Property

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets the current state of this <see cref="TimeMeasurer"/> instance.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The current state of this <see cref="TimeMeasurer"/> instance.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public ReadOnly Property State As TimeMeasurerState
           <DebuggerStepThrough>
           Get
               If (Me.timeElapsed Is Nothing) OrElse (Me.isFinished) Then
                   Return TimeMeasurerState.Disabled

               ElseIf Not Me.timeElapsed.IsRunning Then
                   Return TimeMeasurerState.Paused

               Else
                   Return TimeMeasurerState.Enabled

               End If
           End Get
       End Property

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the update interval.
       ''' Maximum value is 1000 (1 second).
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The update interval.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <exception cref="ArgumentException">
       ''' A value smaller than 1000 is required.;value
       ''' </exception>
       Public Property UpdateInterval As Integer
           <DebuggerStepThrough>
           Get
               Return Me.updateIntervalB
           End Get
           <DebuggerStepThrough>
           Set(ByVal value As Integer)
               If (value > 1000) Then
                   Throw New ArgumentException(message:="A value smaller than 1000 is required.", paramName:="value")
               Else
                   Me.updateIntervalB = value
                   If (Me.measureTimer IsNot Nothing) Then
                       Me.measureTimer.Interval = value
                   End If
               End If
           End Set
       End Property
       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' ( Backing field )
       ''' The update interval.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private updateIntervalB As Integer = 100I

#End Region

#Region " Events "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Occurs when the elapsed/remaining time updates.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Public Event TimeUpdated(ByVal sender As Object, ByVal e As TimeMeasurerUpdatedEventArgs)

#End Region

#Region " Constructors "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Initializes a new instance of the <see cref="TimeMeasurer"/> class.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Public Sub New()
       End Sub

#End Region

#Region " Public Methods "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Starts the time interval measurement.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="milliseconds">
       ''' The time interval to measure, in milliseconds.
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <exception cref="ArgumentOutOfRangeException">
       ''' milliseconds;A value smaller than <see cref="TimeMeasurer.MaxValue"/> is required.
       ''' </exception>
       '''
       ''' <exception cref="ArgumentOutOfRangeException">
       ''' milliseconds;A value greater than 0 is required.
       ''' </exception>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Public Sub Start(ByVal milliseconds As Double)

           If (milliseconds > TimeMeasurer.MaxValue) Then
               Throw New ArgumentOutOfRangeException(paramName:="milliseconds",
                                                     message:=String.Format("A value smaller than {0} is required.", TimeMeasurer.MaxValue))

           ElseIf (milliseconds <= 0) Then
               Throw New ArgumentOutOfRangeException(paramName:="milliseconds",
                                                     message:="A value greater than 0 is required.")

           Else
               Me.timeElapsed = New Stopwatch
               Me.timeRemaining = TimeSpan.FromMilliseconds(milliseconds)
               Me.measureTimer = New Timer With
                  {
                    .Tag = milliseconds,
                    .Interval = Me.updateIntervalB,
                    .Enabled = True
                  }

               Me.isFinished = False
               Me.timeElapsed.Start()
               Me.measureTimer.Start()

           End If

       End Sub

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Starts a time interval measurement given a difference between two dates.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="startDate">
       ''' The starting date.
       ''' </param>
       '''
       ''' <param name="endDate">
       ''' The ending date.
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Public Sub Start(ByVal startDate As Date,
                        ByVal endDate As Date)

           Me.Start(endDate.Subtract(startDate).TotalMilliseconds)

       End Sub

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Starts a time interval measurement given a <see cref="TimeSpan"/>.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="time">
       ''' A <see cref="TimeSpan"/> instance that contains the time interval.
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Public Sub Start(ByVal time As TimeSpan)

           Me.Start(time.TotalMilliseconds)

       End Sub

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Pauses the time interval measurement.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <exception cref="Exception">
       ''' TimeMeasurer is not running.
       ''' </exception>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Public Sub Pause()

           If (Me.State <> TimeMeasurerState.Enabled) Then
               Throw New Exception("TimeMeasurer is not running.")

           Else
               Me.measureTimer.Stop()
               Me.timeElapsed.Stop()

           End If

       End Sub

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Resumes the time interval measurement.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <exception cref="Exception">
       ''' TimeMeasurer is not paused.
       ''' </exception>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Public Sub [Resume]()

           If (Me.State <> TimeMeasurerState.Paused) Then
               Throw New Exception("TimeMeasurer is not paused.")

           Else
               Me.measureTimer.Start()
               Me.timeElapsed.Start()

           End If

       End Sub

       ''' <summary>
       ''' Stops the time interval measurement.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <exception cref="Exception">
       ''' TimeMeasurer is not running.
       ''' </exception>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Public Sub [Stop]()

           If (Me.State = TimeMeasurerState.Disabled) Then
               Throw New Exception("TimeMeasurer is not running.")

           Else
               Me.Reset()
               Me.isFinished = True

               Me.measureTimer.Stop()
               Me.timeElapsed.Stop()

           End If

       End Sub

#End Region

#Region " Private Methods "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Stops Time intervals and resets the elapsed and remaining time to zero.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Private Sub Reset()

           Me.measureTimer.Stop()
           Me.timeElapsed.Reset()

       End Sub

#End Region

#Region " Event Handlers "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Handles the <see cref="Timer.Tick"/> event of the <see cref="MeasureTimer"/> timer.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="sender">
       ''' The source of the event.
       ''' </param>
       '''
       ''' <param name="e">
       ''' The <see cref="EventArgs"/> instance containing the event data.
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Private Sub MeasureTimer_Tick(ByVal sender As Object, ByVal e As Global.System.EventArgs) _
       Handles measureTimer.Tick

           Dim timeDiff As TimeSpan = (Me.timeRemaining - Me.timeElapsed.Elapsed)

           ' If finished...
           If (timeDiff.TotalMilliseconds <= 0.0R) _
           OrElse (Me.timeElapsed.ElapsedMilliseconds > DirectCast(Me.measureTimer.Tag, Double)) Then

               Me.Reset()
               Me.isFinished = True

               If (Me.TimeUpdatedEvent IsNot Nothing) Then
                   Dim goal As TimeSpan = TimeSpan.FromMilliseconds(DirectCast(Me.measureTimer.Tag, Double))
                   RaiseEvent TimeUpdated(sender, New TimeMeasurerUpdatedEventArgs(goal, TimeSpan.FromMilliseconds(0.0R), goal))
               End If

           Else ' If not finished...
               If (Me.TimeUpdatedEvent IsNot Nothing) Then
                   RaiseEvent TimeUpdated(sender, New TimeMeasurerUpdatedEventArgs(Me.timeElapsed.Elapsed,
                                                                                   timeDiff,
                                                                                   TimeSpan.FromMilliseconds(DirectCast(Me.measureTimer.Tag, Double))))
               End If

           End If

       End Sub

#End Region

#Region " IDisposable Implementation "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Flag to detect redundant calls when disposing.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private isDisposed As Boolean = False

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Releases all the resources used by this instance.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Public Sub Dispose() Implements IDisposable.Dispose
           Me.Dispose(isDisposing:=True)
           GC.SuppressFinalize(obj:=Me)
       End Sub

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
       ''' Releases unmanaged and, optionally, managed resources.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="isDisposing">
       ''' <see langword="True"/>  to release both managed and unmanaged resources;
       ''' <see langword="False"/> to release only unmanaged resources.
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Private Sub Dispose(ByVal isDisposing As Boolean)

           If (Not Me.isDisposed) AndAlso (isDisposing) Then

               If (Me.measureTimer IsNot Nothing) Then
                   Me.measureTimer.Stop()
                   Me.measureTimer.Dispose()
                   Me.measureTimer = Nothing
               End If

               If (Me.TimeUpdatedEvent IsNot Nothing) Then
                   RemoveHandler Me.TimeUpdated, Me.TimeUpdatedEvent
               End If

           End If

           Me.isDisposed = True

       End Sub

#End Region

   End Class

End Namespace

#End Region


+

Código (vbnet) [Seleccionar]
' ***********************************************************************
' Author   : Elektro
' Modified : 12-December-2015
' ***********************************************************************

#Region " Option Statements "

Option Strict On
Option Explicit On
Option Infer Off

#End Region

#Region " TimeMeasurer State "

Namespace DateAndTime.Enums

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Specifies the current state of a <see cref="Types.TimeMeasurer"/> instance.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   Public Enum TimeMeasurerState As Integer

       ''' <summary>
       ''' The <see cref="Types.TimeMeasurer"/> is running.
       ''' </summary>
       Enabled = &H0I

       ''' <summary>
       ''' The <see cref="Types.TimeMeasurer"/> is paused.
       ''' </summary>
       Paused = &H1I

       ''' <summary>
       ''' The <see cref="Types.TimeMeasurer"/> is fully stopped, it cannot be resumed.
       ''' </summary>
       Disabled = &H2I

   End Enum

End Namespace

#End Region


+

Código (vbnet) [Seleccionar]
' ***********************************************************************
' Author   : Elektro
' Modified : 12-December-2015
' ***********************************************************************

#Region " Public Members Summary "

#Region " Constructors "

' New(TimeSpan, TimeSpan, TimeSpan)

#End Region

#Region " Properties "

' Elapsed As TimeSpan
' Remaining As TimeSpan
' Goal As TimeSpan

#End Region

#End Region

#Region " Option Statements "

Option Strict On
Option Explicit On
Option Infer Off

#End Region

#Region " Imports "

Imports System.ComponentModel
' Imports Elektro.Core.Types

#End Region

#Region " TimeMeasurerUpdated EventArgs "

Namespace DateAndTime.Types.EventArgs

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Contains the event-data of a <see cref="TimeMeasurer"/> event.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   <ImmutableObject(True)>
   Public NotInheritable Class TimeMeasurerUpdatedEventArgs ' : Inherits AestheticEventArgs

#Region " Properties "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets the elapsed time.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The elapsed time.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public ReadOnly Property Elapsed As TimeSpan
           <DebuggerStepThrough>
           Get
               Return Me.elapsedB
           End Get
       End Property
       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' ( Baking Field )
       ''' The elapsed time.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private ReadOnly elapsedB As TimeSpan

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets the remaining time.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The remaining time.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public ReadOnly Property Remaining As TimeSpan
           <DebuggerStepThrough>
           Get
               Return Me.remainingB
           End Get
       End Property
       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' ( Baking Field )
       ''' The remaining time.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private ReadOnly remainingB As TimeSpan

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets the goal time.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The goal time.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public ReadOnly Property Goal As TimeSpan
           <DebuggerStepThrough>
           Get
               Return Me.goalB
           End Get
       End Property
       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' ( Baking Field )
       ''' The goal time.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private ReadOnly goalB As TimeSpan

#End Region

#Region " Constructors "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Prevents a default instance of the <see cref="TimeMeasurerUpdatedEventArgs"/> class from being created.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerNonUserCode>
       Private Sub New()
       End Sub

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Initializes a new instance of the <see cref="TimeMeasurerUpdatedEventArgs"/> class.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="elapsed">
       ''' The elapsed time.
       ''' </param>
       '''
       ''' <param name="remaining">
       ''' The remaining time.
       ''' </param>
       '''
       ''' <param name="goal">
       ''' The goal time.
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       <DebuggerStepThrough>
       Public Sub New(ByVal elapsed As TimeSpan,
                      ByVal remaining As TimeSpan,
                      ByVal goal As TimeSpan)

           Me.elapsedB = elapsed
           Me.remainingB = remaining
           Me.goalB = goal

       End Sub

#End Region

   End Class

End Namespace

#End Region


Tendrías que editar las classes de arribas un poquito para eliminarle el código sobrante, es decir los espacios de nombres y los imports de la librería y creo que nada más.

El modo de empleo para implementarlo a modo de cuenta atrás, sería más o menos el siguiente:

Código (vbnet) [Seleccionar]
Public Class Form1 : Inherits Form

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' The <see cref="TimeMeasurer"/> instance that measure time intervals.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   Private WithEvents countdown As New TimeMeasurer With {.UpdateInterval = 100}

   ' Label used to display the remaining time.
   Private lblCountdown As Label

   Private Sub Shown() Handles MyBase.Shown
       Me.lblCountdown = Me.Label2
       Me.countdown.Start(TimeSpan.FromMinutes(1.0R))
   End Sub

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Handles the <see cref="TimeMeasurer.TimeUpdated"/> event of the countdown instance.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <param name="sender">
   ''' The source of the event.
   ''' </param>
   '''
   ''' <param name="e">
   ''' The <see cref="TimeMeasurerUpdatedEventArgs"/> instance containing the event data.
   ''' </param>
   ''' ----------------------------------------------------------------------------------------------------
   Private Sub Countdown_TimeUpdated(ByVal sender As Object, ByVal e As TimeMeasurerUpdatedEventArgs) _
   Handles countdown.TimeUpdated

       ' Measure H:M:S:MS
       Me.lblCountdown.Text = String.Format("{0:00}:{1:00}:{2:00}:{3:000}",
                                            e.Remaining.Hours, e.Remaining.Minutes, e.Remaining.Seconds, e.Remaining.Milliseconds)

       If (e.Elapsed.Subtract(e.Remaining) <= e.Goal) Then
           Me.lblCountdown.Text = "Countdown Done!"
       End If

   End Sub

End Class


Si tienes cualquier duda al respecto del código, tan solo pregunta.

Saludos!.
#2933
Hola.

Para continuar/proseguir por donde lo dejaste con el tiempo de la cuenta atrás despues de haber terminado la ejecución de tu aplicación, tienes varias opciones, la más sencilla y cómoda sería utilizar la infraestructura My.Settings para almacenar un valor de tipo Double donde le asignarías un valor de inicialización negativo de -1 la primera vez que inicies tu app (a modo de flag/señal), y al finalizar la ejecución de la app le asignarías los milisegundos actuales, entonces, al iniciar de nuevo la app simplemente leerías el último valor establecido y continuarías la cuenta atrás desde ahí.

Esto que acabo de explicar, en un código se vería reflejado más o menos de la siguiente manera:



Código (vbnet) [Seleccionar]
Public NotInheritable Class Form1 : Inherits Form

   Private time As TimeSpan = TimeSpan.FromMinutes(60)

   Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) _
   Handles MyBase.Load

       Select Case My.Settings.CurrentCountDownMs

           Case Is = -1.0R
               ' Esta es la primera vez que se inicia la aplicación, así que lo ignoramos.

           Case Is = 0R
               ' El tiempo se acabó.
               Environment.FailFast("Tiempo agotado.")

           Case Else
               ' Le asignamos el tiempo guardado al objeto de tipo TimeSpan.
               Me.time = TimeSpan.FromMilliseconds(My.Settings.CurrentCountDownMs)

       End Select

   End Sub

   Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) _
   Handles MyBase.FormClosing

       ' Guardamos el tiempo actual al finalizar la aplicación.
       My.Settings.CurrentCountDownMs = Me.time.TotalMilliseconds

   End Sub

End Class


Nota: Evidéntemente el ejemplo de arriba no incluye la lógica/algoritmo que estés usando para la cuenta atrás, tan solo demuestra la manera en que podrías guardar y leer el valor de la cuenta atrás.

La segunda manera de llevar a cabo esto, la manera que Microsoft recomienda exprésamente en sus directrices de diseño, sería almacenar cualquier valor de la aplicación en una clave de registro. Esto puedes hacerlo de manera sencilla mediante la class Microsoft.Win32.Registry, en Google y MSDN encontrarás toda la información necesaria. Esto en realidad no aporta ninguna ventaja admirable y por eso lo propongo como 2ª opción, puesto que un valor del registro se puede eliminar facilmente, sin embargo, en otras circunstancias podrías tener tus valores estructurados en el registro de Windows facilitando así el acceso y la edición a dichos valores.

La tercera y última forma de hacer esto, la más rudimentaria y por ello también la ménos ventajosa, sería escribir un archivo de texto donde almacenar el valor de "tiempo" y administrar su escritura y lectura por ti mismo, en un archivo de texto plano sin formato, o en un archivo CSV, o con formato Xml, o en un archivo portable de inicialización (archivo.ini)... hay varias formas también.

PD: Nótese que la primera solución con My.Settings, también escribe un archivo de texto plano (Xml), pero siguiendo un patrón de directorios estructurado y todo el embrollo de escritura y lectura es administrado y controlado por .NET Framework.




Respecto a la obtención de la IP, bueno, hay varios aspectos a tener en cuenta así que tu pregunta se podría interpretar de varias formas.

Si quieres obtener la IP pública, entonces creo que algo que te daría un resultado satisfactorio sería establecer una conexión a cualquier servicio gratuito para comprobar la IP, como por ejemplo http://checkip.dyndns.org/

El siguiente código lo he sacado de mi framework de pago ElektroKit para .NET (si te interesa, puedes encontrarlo a la venta de forma exclusiva en Envato)

Código (vbnet) [Seleccionar]
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets the public IP address of the current machine.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Dim ip As String = GetPublicIp()
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The IP address.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Function GetPublicIp() As String

   Dim req As WebRequest = WebRequest.Create("http://checkip.dyndns.org/")

   Using resp As WebResponse = req.GetResponse()

       Using sr As New StreamReader(resp.GetResponseStream())
           Dim html As XDocument = XDocument.Parse(sr.ReadToEnd())
           Dim body As String = html.<html>.<body>.Value
           Return body.Substring(body.LastIndexOf(" ")).Trim()
       End Using

   End Using

End Function


Modo de empleo:
Código (vbnet) [Seleccionar]
Dim ip As String = GetPublicIp()

Un saludo!
#2934
Cita de: Orubatosu en 16 Enero 2017, 09:30 AM
No puede ser una ventana abierta

Lo de los folios de papel tiene una explicación muy lógica y razonable, es el espíritu del gran mago y psíquico James Hydrick.



BONUS:
[youtube=640,360]https://www.youtube.com/watch?v=QlfMsZwr8rc[/youtube]
#2935
Cita de: calaomar17 en 15 Enero 2017, 17:30 PMcreo que la sintaxis esta bien

Hola.

No, la sintaxis que has empleado no es correcta, el comando Copy no copia archivos de forma recursiva, los moificadores /S y /C pertenecen al comando XCopy, no Copy, Aparte de eso, deberías encerrar los argumentos/rutas entre comillas dobles, y el último asterisco o wildcard en la extensión del archivo no debes ponerlo.

Escribe en consola:
Copy /?
XCopy /?

Saludos!
#2936
Cita de: selohu en 15 Enero 2017, 18:09 PM
Alguien a preguntado al cocacola como se hace la cocacola?. Yo creo que el que lo haga recibirá un no rotundo, pues eso igual.

Hombre, yo creo que no es lo mismo intentar preguntarle a una empresa multimillonaria que te digan cual es su ingrediente secreto, que ir a preguntarle al dueño de una tienda informática que narices le van a a hacer a tu PC, de hecho tienes el derecho de saberlo... pero bueno, solo era una idea.

Saludos!
#2937
Dudas Generales / Re: Software Catalogo
15 Enero 2017, 15:36 PM
Cita de: XKC en 14 Enero 2017, 19:28 PM¿Como puedes hacer eso sobre codigo, en c++, java o similares?
Hola.

Como ya te han comentado, puede haber múltiples metodologías para elaborar distintas soluciones.

Las combinaciones estándar de teclas globales (o system-wide hotkeys) se registran y desregistran mediante las funciones Win32 RegisterHotKey y UnregisterHotKey, y el mensaje de ventana WM_HOTKEY se envia a la cola de mensajes de la ventana que deba procesar dicha combinación;
partiendo de esta información, y tomando como ejemplo la combinación CTR+ALT+DEL, te puedo decir que dicha combinación la registra el proceso winlogon.exe al inicio de sesión.

En caso de que ya hayas leido en la MSDN la documentación de la función UnregisterHotKey (concretamente la descripción), te resultará evidentemente que no hay modo posible de desregistrar y/o suplantar las combinaciones globales que hayan sido registradas desde otro proceso distinto al tuyo, solo era para que tengas la información de esas definciiones en cuenta, así que descartamos esta opción, y nos quedarían otras tres alternativas (por lo menos), un api-hook en el proceso winlogon.exe (y los demás que registren las otras combinaciones) para interceptar el mensaje de ventana WM_HOTKEY que se recibe al presionar una combinación (y entonces obtener el identificador para saber que combinación es), o desarrollar un driver de keyboard, o implementar un hook de bajo nivel para el teclado.




Cita de: XKC en 14 Enero 2017, 19:28 PM¿Como puedes hacer eso sobre codigo, en c++, java o similares?

¿y si especificas "similares"?, podría mostrarte un ejemplo funcional de api-hooking en VB.NET/C# (en C++ podrías hacerlo con más libertad y de forma más sofisticada por la naturaleza del lenguaje, usando la librería Detours por ejemplo, nunca la he usado, pero siempre escuché que esa es la mejor opción para C++), y para el hook de bajo nivel podria mostrarte otro ejemplo en VB.NET/C# o en su defecto para C++ podría mencionarte el nombre de las definiciones Win32 implicadas pero no tengo ni idea de como se elaboraría el código usando la sintaxis de C++.

Prueba a analizar este ejemplo escrito en C++ que supuestamente demuestra como bloquear/interceptar la combinación CTRL+ALT+DEL. Advierto que no he descargado ni analizado el código fuente, desconozco que técnica usará:


Fuente:

En realidad solo te haría falta buscar 10 segundos en Google para encontrar todo tipo de información que explica las severas restricciones del S.O. ante este tipo de bloqueo/modificación de hotkeys globales del sistema, así que en un principio es algo dificil de realizar ya que Microsoft no proporciona una forma programática guiada para hacerlo debido a motivos de seguridad, pero poder se puede por vías más complejas (como las mencionadas arriba).




Cita de: XKC en 14 Enero 2017, 19:28 PMComo pregunta general, ¿no pensais que es algo demasido inseguro?, el que cualquiera pueda manipular un ordenador que va a ser vendido, y despues utilizara alguien.

No se puede considerar inseguro siempre y cuando se tenga en cuenta que ciertas modificaciones realizadas al sistema (como estas) son temporales, su tiempo de vida es el mismo que la duración de la aplicación, o en otras circunstancias que la duración de la sesión actual del usuario que inició sesión.

Eso si, poco ético es un rato, e intrusivo... bastante, pero a pesar de eso hay aplicaiones conocidas y nada peligrosas/inseguras que que lo hacen, como el software de VmWare, o supuestamente la aplicación "Process Explorer" de SysInternals (Microsoft Team).

Cita de: XKC en 14 Enero 2017, 19:28 PM¿para un ciberdelincuente no seria una buena jugada instalar malware en esos dispositivos y esperar a que se vendan, o se formatena antes de ser vendidos?

Siendo relistas... ¿has pensado qué empleado va a jugársela de ese modo?, vale que locos y ciberdelincuentes hay muchos en el mundo, pero por ello es que también existe la policía de delitos informáticos especializada en criminología cibernética.

Saludos!
#2938
Foro Libre / Re: Campaña por la BIOS Libre
15 Enero 2017, 13:33 PM
Joder, Hason, vas a llegar a anciano y aun estarás buscando y comparando una placa base libre de "rootkits de fábrica" que comprar por Internet... ¿qué no te decides ya de una vez? xD.

( MODE COMENTARIO LIBRE EN FORO LIBRE ON )

Saludos!
#2939
Solo mencionaré lo siguiente con respecto a .NET: SharpDX + Opcionálmente buscar en google images demostraciones de juegos desarrollados con SharpDX.
#2940
Cita de: selohu en 14 Enero 2017, 15:30 PMuna tienda de informática donde me comentaron que optimizar un equipo para que funcione como tiene que funcionar, tardaría unas 12 horas en optimizarlo.

Alguien tiene idea de esto y si sabe como hacerlo?.

Disculpa la pregunta, pero... ¿has intentado preguntarle al encargado/a de la tienda para que te explique eso mismo que estás preguntando aquí en un foro de Internet? -.-

Un saludo!