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

#501
ConsoleRectangle

Esto es el equivalente a la clase System.Drawing.Rectangle, para representar la posición y tamaño de un rectángulo (dibujable) en el búfer de salida de una consola.





Decisiones (o limitaciones) de diseño:

  • Las propiedades son de solo lectura (para quitarme de lios). Es decir, para hacer cambios en el tamaño o posición del rectángulo, hay que crear una nueva instancia. - ya no lo son
  • No permite la asignación de coordenadas negativas (puesto que tampoco lo permite el método Console.SetCursorPos()), ni un tamaño (anchura ni altura) igual a cero, aunque esto último no se tiene en cuenta si se usa el constructor por defecto.

EDITO: implementación extendida.
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Stores a set of four integers that represent the location and size of a (printable) rectangle on a console output buffer.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
<ComVisible(True)>
<Serializable>
Public Structure ConsoleRectangle

#Region " Properties "

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets or sets the location of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The location of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(False)>
    Public Property Location As Point
        Get
            Return Me.location_
        End Get
        Set(value As Point)
            Me.UpdateLocation(value)
        End Set
    End Property
    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' ( Backing field of <see cref="ConsoleRectangle.Location"/> property. )
    ''' <para></para>
    ''' The location of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    Private location_ As Point

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets the x-coordinate of the upper-left corner of this <see cref="ConsoleRectangle"/>.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The x-coordinate of the upper-left corner of this <see cref="ConsoleRectangle"/>.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(True)>
    Public ReadOnly Property X As Integer
        Get
            Return Me.Location.X
        End Get
    End Property

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets the y-coordinate of the upper-left corner of this <see cref="ConsoleRectangle"/>.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The y-coordinate of the upper-left corner of this <see cref="ConsoleRectangle"/>.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(True)>
    Public ReadOnly Property Y As Integer
        Get
            Return Me.Location.Y
        End Get
    End Property

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets the y-coordinate of the top edge of this <see cref="ConsoleRectangle"/>.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The y-coordinate of the top edge of this <see cref="ConsoleRectangle"/>.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(False)>
    Public ReadOnly Property Top As Integer
        Get
            Return Me.Y
        End Get
    End Property

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets the x-coordinate of the left edge of this <see cref="ConsoleRectangle"/>.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The x-coordinate of the left edge of this <see cref="ConsoleRectangle"/>.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(False)>
    Public ReadOnly Property Left As Integer
        Get
            Return Me.X
        End Get
    End Property

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets the y-coordinate that is the sum of the <see cref="ConsoleRectangle.Y"/>
    ''' and <see cref="ConsoleRectangle.Height"/> property values of this <see cref="ConsoleRectangle"/>.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The y-coordinate that is the sum of the <see cref="ConsoleRectangle.Y"/>
    ''' and <see cref="ConsoleRectangle.Height"/> property values of this <see cref="ConsoleRectangle"/>.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(False)>
    Public ReadOnly Property Bottom As Integer
        Get
            Return (Me.Y + Me.Height)
        End Get
    End Property

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets the x-coordinate that is the sum of <see cref="ConsoleRectangle.X"/>
    ''' and <see cref="ConsoleRectangle.Width"/> property values of this <see cref="ConsoleRectangle"/>.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The x-coordinate that is the sum of <see cref="ConsoleRectangle.X"/>
    ''' and <see cref="ConsoleRectangle.Width"/> property values of this <see cref="ConsoleRectangle"/>.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(False)>
    Public ReadOnly Property Right As Integer
        Get
            Return (Me.X + Me.Width)
        End Get
    End Property

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets or sets the size of this <see cref="ConsoleRectangle"/>.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The size of this <see cref="ConsoleRectangle"/>.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(False)>
    Public Property Size As Size
        Get
            Return Me.size_
        End Get
        Set(value As Size)
            Me.UpdateSize(value)
        End Set
    End Property
    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' ( Backing field of <see cref="ConsoleRectangle.Size"/> property. )
    ''' <para></para>
    ''' The size of this <see cref="ConsoleRectangle"/>.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    Private size_ As Size

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets the width of this <see cref="ConsoleRectangle"/>.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The width of this <see cref="ConsoleRectangle"/>.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(True)>
    Public ReadOnly Property Width As Integer
        Get
            Return Me.Size.Width
        End Get
    End Property

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets the height of this <see cref="ConsoleRectangle"/>.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The height of this <see cref="ConsoleRectangle"/>.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(True)>
    Public ReadOnly Property Height As Integer
        Get
            Return Me.Size.Height
        End Get
    End Property

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets or sets the character to print the left border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The character to print the left border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(True)>
    Public Property CharLeft As Char

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets or sets the character to print the top border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The character to print the top border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(True)>
    Public Property CharTop As Char

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets or sets the character to print the right border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The character to print the right border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(True)>
    Public Property CharRight As Char

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Gets or sets the character to print the bottom border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' The character to print the bottom border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(True)>
    Public Property CharBottom As Char

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Tests whether all numeric properties of this System.Drawing.Rectangle have values of zero.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <value>
    ''' This property returns <see langword="True"/> if the
    ''' <see cref="ConsoleRectangle.Width"/>, <see cref="ConsoleRectangle.Height"/>,
    ''' <see cref="ConsoleRectangle.X"/>, and <see cref="ConsoleRectangle.Y"/> properties
    ''' of this <see cref="ConsoleRectangle"/> all have values of zero;
    ''' otherwise, <see langword="False"/>
    ''' </value>
    ''' ----------------------------------------------------------------------------------------------------
    <Browsable(False)>
    Public ReadOnly Property IsEmpty As Boolean
        Get
            Return (Me.Location = Point.Empty) AndAlso (Me.Size = Size.Empty)
        End Get
    End Property

#End Region

#Region " Constructors "

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Initializes a new instance of the <see cref="ConsoleRectangle"/> structure.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="rect">
    ''' A <see cref="Rectangle"/> that contains the location and size for this <see cref="ConsoleRectangle"/>.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Sub New(ByVal rect As Rectangle)
        Me.New(rect.Location, rect.Size, "▌"c, "▀"c, "▐"c, "▄"c)
    End Sub

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Initializes a new instance of the <see cref="ConsoleRectangle"/> structure.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="rect">
    ''' A <see cref="Rectangle"/> that contains the location and size for this <see cref="ConsoleRectangle"/>.
    ''' </param>
    '''
    ''' <param name="charLeft">
    ''' The character to print the left border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </param>
    '''
    ''' <param name="charTop">
    ''' The character to print the top border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </param>
    '''
    ''' <param name="charRight">
    ''' The character to print the right border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </param>
    '''
    ''' <param name="charBottom">
    ''' The character to print the bottom border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Sub New(ByVal rect As Rectangle,
                   ByVal charLeft As Char, ByVal charTop As Char,
                   ByVal charRight As Char, ByVal charBottom As Char)

        Me.New(rect.Location, rect.Size, charLeft, charTop, charRight, charBottom)

    End Sub

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Initializes a new instance of the <see cref="ConsoleRectangle"/> structure.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="location">
    ''' The location for this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </param>
    '''
    ''' <param name="size">
    ''' The size for this <see cref="ConsoleRectangle"/>.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Sub New(ByVal location As Point, ByVal size As Size)
        Me.New(location, size, "▌"c, "▀"c, "▐"c, "▄"c)
    End Sub

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Initializes a new instance of the <see cref="ConsoleRectangle"/> structure.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="location">
    ''' The location for this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </param>
    '''
    ''' <param name="size">
    ''' The size for this <see cref="ConsoleRectangle"/>.
    ''' </param>
    '''
    ''' <param name="charLeft">
    ''' The character to print the left border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </param>
    '''
    ''' <param name="charTop">
    ''' The character to print the top border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </param>
    '''
    ''' <param name="charRight">
    ''' The character to print the right border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </param>
    '''
    ''' <param name="charBottom">
    ''' The character to print the bottom border of this <see cref="ConsoleRectangle"/> on a console output buffer.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <exception cref="ArgumentNullException">
    ''' </exception>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Sub New(ByVal location As Point, ByVal size As Size,
                   ByVal charLeft As Char, ByVal charTop As Char,
                   ByVal charRight As Char, ByVal charBottom As Char)

        Me.UpdateLocation(location)
        Me.UpdateSize(size)

        Me.CharLeft = charLeft
        Me.CharTop = charTop
        Me.CharRight = charRight
        Me.CharBottom = charBottom

    End Sub

#End Region

#Region " Public Methods "

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Writes the bounds of this <see cref="ConsoleRectangle"/> on the current console output buffer.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Sub Write()
        For row As Integer = 0 To (Me.Height - 1)
            For column As Integer = 0 To (Me.Width - 1)
                If (row = 0) Then
                    Console.SetCursorPosition((Me.X + column), (Me.Y + row))
                    Console.Write(Me.CharTop)

                ElseIf (row = (Me.Height - 1)) Then
                    Console.SetCursorPosition((Me.X + column), (Me.Y + row))
                    Console.Write(Me.CharBottom)

                End If
            Next column

            Console.SetCursorPosition(Me.X, (Me.Y + row))
            Console.Write(Me.CharLeft)
            Console.SetCursorPosition(Me.X + (Me.Width - 1), (Me.Y + row))
            Console.Write(Me.CharRight)
        Next row
    End Sub

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Enlarges this <see cref="ConsoleRectangle"/> by the specified amount.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="width">
    ''' The amount to inflate this <see cref="ConsoleRectangle"/> horizontally.
    ''' </param>
    '''
    ''' <param name="height">
    ''' The amount to inflate this <see cref="ConsoleRectangle"/> vertically.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Sub Inflate(ByVal width As Integer, ByVal height As Integer)
        Dim rc As Rectangle = Me
        rc.Inflate(width, height)
        Me.Size = rc.Size
    End Sub

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Enlarges this <see cref="ConsoleRectangle"/> by the specified amount.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="size">
    ''' The amount to inflate this <see cref="ConsoleRectangle"/>.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Sub Inflate(ByVal size As Size)
        Me.Inflate(size.Width, size.Height)
    End Sub

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Adjusts the location of this <see cref="ConsoleRectangle"/> by the specified amount.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="x">
    ''' The horizontal offset.
    ''' </param>
    '''
    ''' <param name="y">
    ''' The vertical offset.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Sub Offset(ByVal x As Integer, ByVal y As Integer)
        Dim rc As Rectangle = Me
        rc.Offset(x, y)
        Me.Location = rc.Location
    End Sub

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Adjusts the location of this <see cref="ConsoleRectangle"/> by the specified amount.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="location">
    ''' The amount to offset the location.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Sub Offset(ByVal location As Point)
        Me.Offset(location.X, location.Y)
    End Sub

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Returns a <see cref="String"/> that represents this <see cref="ConsoleRectangle"/>.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <returns>
    ''' A <see cref="String"/> that represents this <see cref="ConsoleRectangle"/>.
    ''' </returns>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Overrides Function ToString() As String

        If (Me.Width = 1) AndAlso (Me.Height = 1) Then
            Return Me.CharLeft

        ElseIf (Me.Height = 1) Then
            Dim sb As New StringBuilder()
            Dim lastColumnIndex As Integer = (Me.Width - 1)
            For column As Integer = 0 To lastColumnIndex
                Select Case column
                    Case 0
                        sb.Append(Me.CharLeft)
                    Case lastColumnIndex
                        sb.Append(Me.CharRight)
                    Case Else
                        sb.Append(Me.CharTop)
                End Select
            Next column
            Return sb.ToString()

        ElseIf (Me.Width = 1) Then
            Dim sb As New StringBuilder()
            For row As Integer = 0 To (Me.Height - 1)
                sb.Append(Me.CharLeft)
                sb.AppendLine()
            Next row
            Return sb.ToString()

        Else
            Dim sb As New StringBuilder()
            Dim lastRowIndex As Integer = (Me.Height - 1)
            For row As Integer = 0 To lastRowIndex
                Select Case row
                    Case 0
                        sb.Append(Me.CharLeft)
                        sb.Append(New String(Me.CharTop, Math.Max((Me.Width - 2), 1)))
                        sb.Append(Me.CharRight)
                    Case lastRowIndex
                        sb.Append(Me.CharLeft)
                        sb.Append(New String(Me.CharBottom, Math.Max((Me.Width - 2), 1)))
                        sb.Append(Me.CharRight)
                    Case Else
                        sb.Append(Me.CharLeft)
                        sb.Append(New String(" "c, Math.Max((Me.Width - 2), 1)))
                        sb.Append(Me.CharRight)
                End Select
                sb.AppendLine()
            Next row
            Return sb.ToString()

        End If

    End Function

#End Region

#Region " Operators "

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Performs an implicit conversion from <see cref="ConsoleRectangle"/> to <see cref="Rectangle"/>.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="rect">
    ''' The source <see cref="ConsoleRectangle"/>.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <returns>
    ''' The resulting <see cref="Rectangle"/>.
    ''' </returns>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Shared Widening Operator CType(ByVal rect As ConsoleRectangle) As Rectangle
        Return New Rectangle(rect.Location, rect.Size)
    End Operator

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Performs an implicit conversion from <see cref="Rectangle"/> to <see cref="ConsoleRectangle"/>.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="rect">
    ''' The source <see cref="Rectangle"/>.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <returns>
    ''' The resulting <see cref="ConsoleRectangle"/>.
    ''' </returns>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Shared Widening Operator CType(rect As Rectangle) As ConsoleRectangle
        Return New ConsoleRectangle(rect)
    End Operator

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Tests whether two <see cref="Rectangle"/> and <see cref="ConsoleRectangle"/> structures have equal location and size.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="rect">
    ''' The <see cref="Rectangle"/> to compare with the <see cref="ConsoleRectangle"/> structure.
    ''' </param>
    '''
    ''' <param name="consoleRect">
    ''' The <see cref="ConsoleRectangle"/> to compare with the <see cref="Rectangle"/> structure.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <returns>
    ''' <see langword="True"/> if the two <see cref="Rectangle"/> and <see cref="ConsoleRectangle"/> structures have equal location and size;
    ''' otherwise, <see langword="False"/>.
    ''' </returns>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Shared Operator =(rect As Rectangle, consoleRect As ConsoleRectangle) As Boolean
        Return (rect.Location = consoleRect.Location) AndAlso (rect.Size = consoleRect.Size)
    End Operator

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Determine whether two <see cref="Rectangle"/> and <see cref="ConsoleRectangle"/> structures differ in location or size.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="rect">
    ''' The <see cref="Rectangle"/> to compare with the <see cref="ConsoleRectangle"/> structure.
    ''' </param>
    '''
    ''' <param name="consoleRect">
    ''' The <see cref="ConsoleRectangle"/> to compare with the <see cref="Rectangle"/> structure.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <returns>
    ''' <see langword="True"/> if the two <see cref="Rectangle"/> and <see cref="ConsoleRectangle"/> structures differ in location or size;
    ''' otherwise, <see langword="False"/>.
    ''' </returns>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Shared Operator <>(rect As Rectangle, consoleRect As ConsoleRectangle) As Boolean
        Return Not (rect = consoleRect)
    End Operator

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Tests whether two <see cref="ConsoleRectangle"/> structures have equal location, size and characters.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="left">
    ''' The <see cref="ConsoleRectangle"/> structure that is to the left of the equality operator.
    ''' </param>
    '''
    ''' <param name="right">
    ''' The <see cref="ConsoleRectangle"/> structure that is to the right of the equality operator.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <returns>
    ''' <see langword="True"/> if the two <see cref="ConsoleRectangle"/> structures have equal location, size and characters;
    ''' otherwise, <see langword="False"/>.
    ''' </returns>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Shared Operator =(left As ConsoleRectangle, right As ConsoleRectangle) As Boolean
        Return (left.Location = right.Location) AndAlso
               (left.Size = right.Size) AndAlso
               (left.CharLeft = right.CharLeft) AndAlso
               (left.CharTop = right.CharTop) AndAlso
               (left.CharRight = right.CharRight) AndAlso
               (left.CharBottom = right.CharBottom)
    End Operator

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Tests whether two <see cref="ConsoleRectangle"/> structures differ in location, size or characters.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="left">
    ''' The <see cref="ConsoleRectangle"/> structure that is to the left of the equality operator.
    ''' </param>
    '''
    ''' <param name="right">
    ''' The <see cref="ConsoleRectangle"/> structure that is to the right of the equality operator.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <returns>
    ''' <see langword="True"/> if if any of the two <see cref="ConsoleRectangle"/> structures differ in location, size or characters;
    ''' otherwise, <see langword="False"/>.
    ''' </returns>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Public Shared Operator <>(left As ConsoleRectangle, right As ConsoleRectangle) As Boolean
        Return Not (left = right)
    End Operator

#End Region

#Region " Private Methods "

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Updates the location value specified in <see cref="ConsoleRectangle.Location"/> property.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="newLocation">
    ''' The new location.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <exception cref="ArgumentException">
    ''' Positive value is required for coordinate.
    ''' </exception>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Private Sub UpdateLocation(ByVal newLocation As Point)
        If (Me.location_ = newLocation) Then
            Exit Sub
        End If

        If (newLocation.X < 0) Then
            Throw New ArgumentException(paramName:=NameOf(newLocation),
                                        message:=String.Format("Positive value is required for '{0}' coordinate.", NameOf(newLocation.X)))

        ElseIf (newLocation.Y < 0) Then
            Throw New ArgumentException(paramName:=NameOf(newLocation),
                                        message:=String.Format("Positive value is required for '{0}' coordinate.", NameOf(newLocation.Y)))

        End If

        Me.location_ = newLocation
    End Sub

    ''' ----------------------------------------------------------------------------------------------------
    ''' <summary>
    ''' Updates the size value specified in <see cref="ConsoleRectangle.Size"/> property.
    ''' </summary>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <param name="newSize">
    ''' The new size.
    ''' </param>
    ''' ----------------------------------------------------------------------------------------------------
    ''' <exception cref="ArgumentException">
    ''' Value greather than zero is required.
    ''' </exception>
    ''' ----------------------------------------------------------------------------------------------------
    <DebuggerStepThrough>
    Private Sub UpdateSize(ByVal newSize As Size)
        If (Me.size_ = newSize) Then
            Exit Sub
        End If

        If (newSize.Width <= 0) Then
            Throw New ArgumentException(paramName:=NameOf(Size),
                                        message:=String.Format("Value greather than zero is required for '{0}'", NameOf(newSize.Width)))

        ElseIf (newSize.Height <= 0) Then
            Throw New ArgumentException(paramName:=NameOf(Size),
                                        message:=String.Format("Value greather than zero is required for '{0}'", NameOf(newSize.Height)))

        End If

        Me.size_ = newSize
    End Sub

#End Region

End Structure


Ejemplo de uso:
Public Module Module1

   Public Sub Main()
       Dim rc1Pos As New Point(2, Console.CursorTop + 2)
       Dim rc1 As New ConsoleRectangle(rc1Pos, New Size(32, 4), "▌"c, "▀"c, "▐"c, "▄"c)
       rc1.Write()

       Dim rc2Pos As New Point(2, Console.CursorTop + 2)
       Dim rc2 As New ConsoleRectangle(rc2Pos, New Size(32, 4), "X"c, "X"c, "X"c, "X"c)
       rc2.Write()

       Dim rc3Pos As New Point(2, Console.CursorTop + 2)
       Dim rc3 As New ConsoleRectangle(rc3Pos, New Size(11, 5), "▌"c, "▀"c, "▐"c, "▄"c)
       rc3.Write()

       Dim rc4Pos As New Point(rc3Pos.X + (rc3.Width \ 2), rc3Pos.Y + +(rc3.Height \ 2))
       Dim rc4 As New ConsoleRectangle(rc4Pos, rc3.Size, "X"c, "X"c, "X"c, "X"c)
       rc4.Write()

       Console.SetCursorPosition(rc1.X + 9, rc1.Y)
       Console.Write(" Hello World ")
       Console.SetCursorPosition(rc1.X + 6, rc1.Y + 2)
       Console.Write(" By ElektroStudios ")

       Console.CursorVisible = False
       Console.ReadKey(intercept:=True)
   End Sub

End Module
#502
Cita de: Meta en  1 Marzo 2019, 05:48 AM
¿Algún programa para capturar imágenes a gif como he visto por aquí?

El que yo uso: https://www.screentogif.com/
#503
Si es que...

Aquí publicaste un tema relacionado en el año 2016:

Y aquí otro en el 2017:

...

A ver, yo soy el primero en reconocer que soy malísimo con las matemáticas, pero si te han estado explicando como calcular un porcentaje durante años y todavía sigues preguntando lo mismo y no te da para repasar las respuestas que te ofrecieron a esos temas que creaste en el foro, pues yo ya no se que nombre tiene eso...

Muchas veces pienso que estas dudas son un trolleo y que es una pérdida de tiempo escribir respuestas largas en tus temas precisamente por eso... y por que el tiempo y los años demuestra que no lees lo que te dicen, por que sigues preguntando exactamente lo mismo que hace 3 años (en este y otros temas distintos, siempre ocurre lo mismo contigo).













Vamos a ver... hace unos años desarrollé esta barra de progreso reutilizable para aplicaciones de consola...



partiendo de esta idea en C# que tomé como base e inspiración:

El código (el cual no está muy optimizado, todo hay que decirlo) lo puedes pegar en un nuevo proyecto de VB.NET para generar un archivo dll, o lo puedes convertir a C# si prefieres. O también puedes usar el código original en C#, aunque no es tan personalizable como este de aquí abajo.

Si despues de esto sigues teniendo dudas y necesitas ayuda con la utilización de barras de progreso y cálculo de porcentajes, yo me daré por vencido para siempre...

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

#Region " Imports "

Imports System.Drawing
Imports System.Text
Imports System.Threading

' Imports DevCase.Core.Application.UserInterface.Tools.Console
' Imports DevCase.Core.Design

#End Region

#Region " Console ProgressBar "

'Namespace DevCase.Core.Application.UserInterface

'#If Not NET40 Then

''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' A personalizable colorful ASCII progress bar for console applications.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' Based on: <see href="https://gist.github.com/DanielSWolf/0ab6a96899cc5377bf54"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Public Module Module1
'''
'''     Public Sub Main()
'''         Console.CursorVisible = False
'''         Console.Write("Performing some task... ")
'''
'''         Using progress As New ConsoleProgressBar(blockCount:=20) With {
'''             .Animation = "||//--\\".ToCharArray(),
'''             .AnimationSpeed = TimeSpan.FromMilliseconds(125),
'''             .AnimationBackColor = Console.BackgroundColor,
'''             .AnimationForeColor = ConsoleColor.Yellow,
'''             .BlockActiveChar = "█"c,
'''             .BlockInactiveChar = "·"c,
'''             .BlockActiveBackColor = Console.BackgroundColor,
'''             .BlockActiveForeColor = ConsoleColor.Green,
'''             .BlockInactiveBackColor = Console.BackgroundColor,
'''             .BlockInactiveForeColor = ConsoleColor.DarkGray,
'''             .BorderBackColor = Console.BackgroundColor,
'''             .BorderForeColor = ConsoleColor.White,
'''             .ProgressTextFormat = "{1} of {2} ({0}%)",
'''             .ProgressTextBackColor = Console.BackgroundColor,
'''             .ProgressTextForeColor = ConsoleColor.Gray
'''         }
'''
'''             For i As Integer = 0 To 100
'''                 progress.Report(i / 100)
'''                 Thread.Sleep(100)
'''             Next i
'''         End Using
'''
'''         Console.WriteLine()
'''         Console.WriteLine("Done.")
'''         Console.ReadKey()
'''     End Sub
'''
''' End Module
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
Public NotInheritable Class ConsoleProgressBar : Implements IDisposable : Implements IProgress(Of Double)

#Region " Properties "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets the current progress value. From 0.0 to 1.0
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The current progress value. From 0.0 to 1.0
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public ReadOnly Property CurrentProgress As Double
           Get
               Return Me.currentProgressB
           End Get
       End Property
       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' The current progress value. From 0.0 to 1.0
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private currentProgressB As Double

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets the amount of blocks to display in the progress bar.
       ''' <para></para>
       ''' Default value is: 20
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The amount of blocks to display in the progress bar.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public ReadOnly Property BlockCount As Integer

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets the character used to draw an active progress bar block.
       ''' <para></para>
       ''' Default value is: "#"
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The character used to draw an active progress bar block.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property BlockActiveChar As Char

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets the character used to draw an inactive progress bar block.
       ''' <para></para>
       ''' Default value is: "·"
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The character used to draw an inactive progress bar block.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property BlockInactiveChar As Char

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the <see cref="ConsoleColor"/> used to paint the background of an active progress bar block.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The <see cref="ConsoleColor"/> used to paint the background of an active progress bar block.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property BlockActiveBackColor As ConsoleColor

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the <see cref="ConsoleColor"/> used to paint the foreground of an active progress bar block.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The <see cref="ConsoleColor"/> used to paint the foreground of an active progress bar block.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property BlockActiveForeColor As ConsoleColor

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the <see cref="ConsoleColor"/> used to paint the background of a inactive progress bar block.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The <see cref="ConsoleColor"/> used to paint the background of a inactive progress bar block.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property BlockInactiveBackColor As ConsoleColor

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the <see cref="ConsoleColor"/> used to paint the foreground of a inactive progress bar block.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The <see cref="ConsoleColor"/> used to paint the foreground of a inactive progress bar block.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property BlockInactiveForeColor As ConsoleColor

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the <see cref="ConsoleColor"/> used to paint the background of the borders of the progress bar.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The <see cref="ConsoleColor"/> used to paint the background of the borders of the progress bar.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property BorderBackColor As ConsoleColor

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the <see cref="ConsoleColor"/> used to paint the foreground of the borders of the progress bar.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The <see cref="ConsoleColor"/> used to paint the foreground of the borders of the progress bar.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property BorderForeColor As ConsoleColor

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the format of the progress text, where:
       ''' <para></para> {0} = Percentage Value
       ''' <para></para> {1} = Current Value
       ''' <para></para> {2} = Maximum Value
       ''' <para></para>
       ''' Default value is: "{0}%"
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The format of the percentage string.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property ProgressTextFormat As String

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the <see cref="ConsoleColor"/> used to paint the background of the progress text.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The <see cref="ConsoleColor"/> used to paint the background of the borders of the progress text.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property ProgressTextBackColor As ConsoleColor

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the <see cref="ConsoleColor"/> used to paint the foreground of the borders of the progress text.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The <see cref="ConsoleColor"/> used to paint the foreground of the borders of the progress text.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property ProgressTextForeColor As ConsoleColor

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the characters used to draw the animation secuence at the very end of the progress bar.
       ''' <para></para>
       ''' Default value is: {"|"c, "|"c, "/"c, "/"c, "-"c, "-"c, "\"c, "\"c}  ( that is: "||//--\\" )
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The characters used to draw the animation secuence at the very end of the progress bar.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property Animation As Char()

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the speed (framerate) of the animation secuence defined in <see cref="ConsoleProgressBar.Animation"/>.
       ''' <para></para>
       ''' Default value is: 125 milliseconds.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The speed (framerate) of the animation secuence defined in <see cref="ConsoleProgressBar.Animation"/>.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property AnimationSpeed As TimeSpan

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the <see cref="ConsoleColor"/> used to paint the background of the animation secuence.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The <see cref="ConsoleColor"/> used to paint the background of the borders of the animation secuence.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property AnimationBackColor As ConsoleColor

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets the <see cref="ConsoleColor"/> used to paint the foreground of the borders of the animation secuence.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' The <see cref="ConsoleColor"/> used to paint the foreground of the borders of the animation secuence.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property AnimationForeColor As ConsoleColor

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Gets or sets a value indicating whether the animation secuence is visible in the progress bar.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <value>
       ''' A value indicating whether the animation secuence is visible in the progress bar.
       ''' </value>
       ''' ----------------------------------------------------------------------------------------------------
       Public Property AnimationVisible As Boolean

#End Region

#Region " Private Fields "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' The timer.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private ReadOnly timer As Threading.Timer

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' The current animation index.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private animationIndex As Integer

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' The cursor position in the console buffer when instancing the <see cref="ConsoleProgressBar"/> class.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private cursorPos As Point

#End Region

#Region " Constructors "

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

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Initializes a new instance of the <see cref="ConsoleProgressBar"/> class.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="blockCount">
       ''' The amount of blocks to display in the progress bar. Default value is: 20
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       Public Sub New(Optional ByVal blockCount As Integer = 10)

           If (blockCount < 2) Then
               Throw New ArgumentException(message:="Block count must be a value greater than 1.", paramName:=NameOf(blockCount))
           End If

           Me.BlockCount = blockCount
           Me.BlockActiveChar = "#"c
           Me.BlockInactiveChar = "·"c

           Me.BlockActiveBackColor = Console.BackgroundColor
           Me.BlockActiveForeColor = Console.ForegroundColor
           Me.BlockInactiveBackColor = Console.BackgroundColor
           Me.BlockInactiveForeColor = Console.ForegroundColor
           Me.BorderBackColor = Console.BackgroundColor
           Me.BorderForeColor = Console.ForegroundColor

           Me.Animation = "||//--\\".ToCharArray()
           Me.AnimationSpeed = TimeSpan.FromMilliseconds(100)
           Me.AnimationVisible = True
           Me.AnimationBackColor = Console.BackgroundColor
           Me.AnimationForeColor = Console.ForegroundColor

           Me.ProgressTextFormat = "{0}%"
           Me.ProgressTextBackColor = Console.BackgroundColor
           Me.ProgressTextForeColor = Console.ForegroundColor

           Me.timer = New Timer(AddressOf Me.TimerCallback)

           Me.cursorPos = New Point(Console.CursorLeft, Console.CursorTop)

           ' A progress bar is only for temporary display in a console window.
           ' If the console output is redirected to a text file, draw nothing.
           ' Otherwise, we will end up with a lot of garbage in the target text file.
           If Not Console.IsOutputRedirected Then
               Me.ResetTimer()
           End If

       End Sub

#End Region

#Region " Public Methods "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Reports a progress update.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="value">
       ''' The value of the updated progress.
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       Public Sub Report(ByVal value As Double) Implements IProgress(Of Double).Report
           ' Make sure value is in [0..1] range
           value = Math.Max(0, Math.Min(1, value))
           Interlocked.Exchange(Me.currentProgressB, value)
       End Sub

#End Region

#Region " Private Methods "

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Handles the calls from <see cref="ConsoleProgressBar.timer"/>.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       ''' <param name="state">
       ''' An object containing application-specific information relevant to the
       ''' method invoked by this delegate, or <see langword="Nothing"/>.
       ''' </param>
       ''' ----------------------------------------------------------------------------------------------------
       Private Sub TimerCallback(ByVal state As Object)

           SyncLock Me.timer
               If (Me.isDisposed) Then
                   Exit Sub
               End If

               Me.UpdateText()
               Me.ResetTimer()
           End SyncLock

       End Sub

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Resets the timer.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private Sub ResetTimer()
           Me.timer.Change(Me.AnimationSpeed, TimeSpan.FromMilliseconds(-1))
       End Sub

       ''' ----------------------------------------------------------------------------------------------------
       ''' <summary>
       ''' Updates the progress bar text.
       ''' </summary>
       ''' ----------------------------------------------------------------------------------------------------
       Private Sub UpdateText()

           Dim currentBlockCount As Integer = CInt(Me.currentProgressB * Me.BlockCount)
           Dim percent As Integer = CInt(Me.currentProgressB * 100)

           Dim text As String =
                   String.Format("[{0}{1}] {2} {3}",
                                 New String(Me.BlockActiveChar, currentBlockCount),
                                 New String(Me.BlockInactiveChar, Me.BlockCount - currentBlockCount),
                                 String.Format(Me.ProgressTextFormat, percent, (Me.currentProgressB * 100), 100),
                                 Me.Animation(Math.Max(Interlocked.Increment(Me.animationIndex), Me.animationIndex - 1) Mod Me.Animation.Length))
           Dim textLen As Integer = text.Length

           Dim coloredText As New StringBuilder()
           With coloredText
               .AppendFormat("*B{0}**F{1}*{2}*-B**-F*", CInt(Me.BorderBackColor), CInt(Me.BorderForeColor),
                                 "[")

               .AppendFormat("*B{0}**F{1}*{2}*-B**-F*", CInt(Me.BlockActiveBackColor), CInt(Me.BlockActiveForeColor),
                                 New String(Me.BlockActiveChar, currentBlockCount))

               .AppendFormat("*B{0}**F{1}*{2}*-B**-F*", CInt(Me.BlockInactiveBackColor), CInt(Me.BlockInactiveForeColor),
                                 New String(Me.BlockInactiveChar, Me.BlockCount - currentBlockCount))

               .AppendFormat("*B{0}**F{1}*{2}*-B**-F*", CInt(Me.BorderBackColor), CInt(Me.BorderForeColor),
                                 "]")
               .Append(" ")
               .AppendFormat("*B{0}**F{1}*{2}*-B**-F*", CInt(Me.ProgressTextBackColor), CInt(Me.ProgressTextForeColor),
                                 String.Format(Me.ProgressTextFormat, percent, (Me.currentProgressB * 100), 100))

               .Append(" ")
               If Me.AnimationVisible Then
                   .AppendFormat("*B{0}**F{1}*{2}*-B**-F*", CInt(Me.AnimationBackColor), CInt(Me.AnimationForeColor),
                                     Me.Animation(Math.Max(Interlocked.Increment(Me.animationIndex), Me.animationIndex - 1) Mod Me.Animation.Length))
               End If
           End With

           ' Lazy error handling when the console window is resized by the end-user.
           Try
               If (Console.BufferWidth > textLen) Then
                   coloredText.Append(" "c, Console.BufferWidth - text.Length)
               End If
               Console.SetCursorPosition(Me.cursorPos.X, Me.cursorPos.Y)
               ConsoleUtil.WriteColorText(coloredText.ToString(), {"*"c})

           Catch ex As Exception
               ' Do nothing.
           End Try

       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)
       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>
       Protected Sub Dispose(ByVal isDisposing As Boolean)

           If (Not Me.isDisposed) AndAlso (isDisposing) Then
               SyncLock Me.timer
                   Me.UpdateText()
               End SyncLock
               If (Me.timer IsNot Nothing) Then
                   Me.timer.Dispose()
               End If
           End If

           Me.isDisposed = True

       End Sub

#End Region

   End Class

'#End If

'End Namespace

#End Region

'Namespace DevCase.Core.Application.UserInterface.Tools.Console

Public NotInheritable Class ConsoleUtil

#Region " Public Methods "

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Writes colored text to the console.
   ''' <para></para>
   ''' Use <c>*F##*</c> as the start delimiter of the ForeColor, use <c>*-F*</c> as the end delimiter of the ForeColor.
   ''' <para></para>
   ''' Use <c>*B##*</c> as the start delimiter of the BackColor, use <c>*-B*</c> as the end delimiter of the BackColor.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <example> This is a code example.
   ''' <code>
   ''' WriteColorText("*F10*Hello *F14*World!*-F*", {"*"c})
   ''' </code>
   ''' </example>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <param name="text">
   ''' The color-delimited text to write.
   ''' </param>
   '''
   ''' <param name="delimiters">
   ''' A set of 1 or 2 delimiters to parse the color-delimited string.
   ''' </param>
   ''' ----------------------------------------------------------------------------------------------------
   <DebuggerStepThrough>
   Public Shared Sub WriteColorText(ByVal text As String,
                                        ByVal delimiters As Char())

       ' Save the current console colors to later restore them.
       Dim oldForedColor As ConsoleColor = Console.ForegroundColor
       Dim oldBackColor As ConsoleColor = Console.BackgroundColor

       ' Split the string to retrieve and parse the color-delimited strings.
       Dim stringParts As String() =
                   text.Split(delimiters, StringSplitOptions.RemoveEmptyEntries)

       ' Parse the string parts.
       For Each part As String In stringParts

           If (part.ToUpper Like "F#") OrElse (part.ToUpper Like "F##") Then
               ' Use the new ForeColor.
               Console.ForegroundColor = DirectCast(CInt(part.Substring(1)), ConsoleColor)

           ElseIf (part.ToUpper Like "B#") OrElse (part.ToUpper Like "B##") Then
               ' Use the new BackgroundColor.
               Console.BackgroundColor = DirectCast(CInt(part.Substring(1)), ConsoleColor)

           ElseIf (part.ToUpper Like "-F") Then
               ' Use the saved Forecolor.
               Console.ForegroundColor = oldForedColor

           ElseIf (part.ToUpper Like "-B") Then
               ' Use the saved BackgroundColor.
               Console.BackgroundColor = oldBackColor

           Else ' String part is not a delimiter so we can print it.
               Console.Write(part)

           End If

       Next part

       ' Restore the saved console colors.
       Console.ForegroundColor = oldForedColor
       Console.BackgroundColor = oldBackColor

   End Sub

#End Region

   Private Sub New()
   End Sub

End Class

'End Namespace


Modo de empleo:
Código (vbnet) [Seleccionar]
Public Module Module1

   Public Sub Main()
       Console.CursorVisible = False
       Console.Write("Performing some task... ")

       Using progress As New ConsoleProgressBar(blockCount:=20) With {
           .Animation = "||//--\\".ToCharArray(),
           .AnimationSpeed = TimeSpan.FromMilliseconds(125),
           .AnimationBackColor = Console.BackgroundColor,
           .AnimationForeColor = ConsoleColor.Yellow,
           .BlockActiveChar = "█"c,
           .BlockInactiveChar = "·"c,
           .BlockActiveBackColor = Console.BackgroundColor,
           .BlockActiveForeColor = ConsoleColor.Green,
           .BlockInactiveBackColor = Console.BackgroundColor,
           .BlockInactiveForeColor = ConsoleColor.DarkGray,
           .BorderBackColor = Console.BackgroundColor,
           .BorderForeColor = ConsoleColor.White,
           .ProgressTextFormat = "{1} of {2} ({0}%)",
           .ProgressTextBackColor = Console.BackgroundColor,
           .ProgressTextForeColor = ConsoleColor.Gray
       }

           For i As Integer = 0 To 100
               progress.Report(i / 100)
               Thread.Sleep(100)
           Next i
       End Using

       Console.WriteLine()
       Console.WriteLine("Done.")
       Console.ReadKey()
   End Sub

End Module


Por cierto, ese código lo comparto de manera libre aunque lo cierto es que forma parte del código fuente del framework comercial DevCase for .NET Framework para desarrolladores .NET.

Saludos...
#504
Cita de: Meta en 27 Febrero 2019, 22:29 PM
Independientemente de la cantidad de █ haya para crear una barra de progreso, no llega al 100 %.

Citar
Código (csharp) [Seleccionar]
int barra = 49;
Citar
Código (csharp) [Seleccionar]
for (int i = 0; i <= barra; i++) { ... }

La longitud de caracteres de esa "barra de progreso" son 58, no 49...

Citar
Código (csharp) [Seleccionar]
porcentaje++; // Incrementa valor.

En ninguna parte del código estás calculando un porcentaje, tan solo incrementas un valor. Logicamente tal y como tienes ahora mismo ese código, la única manera de que ese "porcentaje" llegue a 100 sería incrementar el valor 100 veces.

Supongo que no necesitarás que te explique la fórmula para calcular un porcentaje...

Código (csharp) [Seleccionar]
int barra = 58;
double porcentaje = 0;

for (int i = 0; i < barra; i++) {
porcentaje = ((i + 1.0D) / (barra / 100.0));
}


Y el método ese "printCargando" sencillamente está mal planteado al tomar un valor de porcentaje como parámetro y usarlo tal cual en el método Console.SetCursorPosition()... no tiene sentido.

Saludos.
#505
Visual Studio ya provee herramientas de localización de idioma mediante los archivos de recurso (resources.resx) embedidos en la aplicación, por lo tanto no hay necesidad de reinventar la rueda ni tampoco usar metodologías rudimentarias como pudiera ser un Array de cadenas de texto, aunque, y ya puestos, antes que usar un string con formato Xml y andarse con substrings y splits para obtener un Array de strings, lo cual resulta tedioso o engorroso de hacer, sería mucho más simple y conveniente declarar una variable de tipo XElement y ahí especificar el contenido del documento Xml, y entonces tratarlo como tal mediante las funcionalidades built-in de .NET Framework para el tratamiento de documentos Xml, y con ello aportar mayor estabilidad y simplificación al análisis de datos (o parsing) si lo comparásemos con la manipulación de un string con formato Xml al que hacerle un String.Split().
Dicho de otra forma, la propuesta sería más o menos lo mismo que te ha explicado el compañero @NEBIRE, pero enfocado al uso del tipo XElement en lugar de String, y sin la carga de archivos locales (eso ya sería como prefieras hacerlo).

Un ejemplo muy, muy básico para declarar una cadena de texto Xml con cadenas de texto para distintos idiomas, obtener el idioma por defecto del thread en ejecución (esto se haría al inicío de tu aplicación), establecer un nuevo idioma, y escribir las cadenas de texto del idioma actual establecido:

Código (csharp) [Seleccionar]
using System;
using System.Globalization;
using System.Threading;
using System.Xml.Linq;

namespace ConsoleApp1 {

   class Program {

       private static readonly XElement languages =
           XElement.Parse(@"<languages>
                                <en-US>
                                    <Options>
                                        <Option1>Option 1</Option1>
                                        <Option2>Option 2</Option2>
                                        <Option3>Option 3</Option3>
                                    </Options>
                                    <ExitMessage>Press any key to exit...</ExitMessage>
                                </en-US>
                                <es-ES>
                                    <Options>
                                        <Option1>Opción 1</Option1>
                                        <Option2>Opción 2</Option2>
                                        <Option3>Opción 3</Option3>
                                    </Options>
                                    <ExitMessage>Pulse cualquier tecla para salir...</ExitMessage>
                                </es-ES>
                            </languages>");

       static void Main(string[] args) {      

           // Obtener configuración de idioma actual.
           CultureInfo currentCi = Thread.CurrentThread.CurrentUICulture;
           XElement currenLangXml = languages.Element(currentCi.Name);
           // Si no se encuentra un elemento Xml para el idioma actual, establecer idioma favorito por defecto (Inglés).
           if (currenLangXml == null) {
               currenLangXml = languages.Element("en-US");
           }

           // --------------------------------------------------------------

           // Establecer nueva configuración de idioma.
           CultureInfo newCi = new CultureInfo("es-ES");
           XElement newLangXml = languages.Element(newCi.Name);

           // --------------------------------------------------------------

           // Obtener los campos de opciones del idioma actual establecido.
           string option1 = newLangXml.Element("Options").Element("Option1").Value;
           string option2 = newLangXml.Element("Options").Element("Option2").Value;
           string option3 = newLangXml.Element("Options").Element("Option3").Value;
           string exitMsg = newLangXml.Element("ExitMessage").Value;

           // --------------------------------------------------------------

           // Escribir las opciones en el idioma actual establecido.
           Console.WriteLine(option1);
           Console.WriteLine(option2);
           Console.WriteLine(option3);
           Console.WriteLine();
           Console.WriteLine(exitMsg);

           Console.ReadKey(intercept: true);
       }
   }
}


Logicamente puedes escribir los nodos Xml que desees con cuantos elementos desees y elementos hijos cada uno.

Por cierto, cabría destacar que una de las ventajas o comodidades de VB.NET es simplificar (por no decir perfeccionar) al máximo el tratamiento de Xml en tiempo de diseño gracias a la inclusión directa de código Xml mediante la funcionalidad LINQ to XML incluyendo la declaración de literales Xml, por lo que el equivalente al código de arriba en C# sería más reducido e "interactivo", quedando así:

Código (vbnet) [Seleccionar]
Imports System
Imports System.Globalization
Imports System.Linq
Imports System.Threading
Imports System.Xml.Linq

Public Module Module1

   Private ReadOnly languages As XElement =
       <languages>
           <en-US>
               <Options>
                   <Option1>Option 1</Option1>
                   <Option2>Option 2</Option2>
                   <Option3>Option 3</Option3>
               </Options>
               <ExitMessage>Press any key to exit...</ExitMessage>
           </en-US>
           <es-ES>
               <Options>
                   <Option1>Opción 1</Option1>
                   <Option2>Opción 2</Option2>
                   <Option3>Opción 3</Option3>
               </Options>
               <ExitMessage>Pulse cualquier tecla para salir...</ExitMessage>
           </es-ES>
       </languages>

   Public Sub Main()

       ' Obtener configuración de idioma actual.
       Dim currentCi As CultureInfo = Thread.CurrentThread.CurrentUICulture
       Dim currenLangXml As XElement = languages.Element(currentCi.Name)
       ' Si no se encuentra un elemento Xml para el idioma actual, establecer idioma favorito por defecto (Inglés).
       If currenLangXml Is Nothing Then
           currenLangXml = languages.<en-US>.Single()
       End If

       ' --------------------------------------------------------------

       ' Establecer nueva configuración de idioma.
       Dim newCi As New CultureInfo("es-ES")
       Dim newLangXml As XElement = languages.Element(newCi.Name)

       ' --------------------------------------------------------------

       ' Obtener los campos de opciones del idioma actual establecido.
       Dim option1 As String = newLangXml.<Options>.<Option1>.Value
       Dim option2 As String = newLangXml.<Options>.<Option2>.Value
       Dim option3 As String = newLangXml.<Options>.<Option3>.Value
       Dim exitMsg As String = newLangXml.<ExitMessage>.Value

       ' --------------------------------------------------------------

       ' Escribir las opciones en el idioma actual establecido.
       Console.WriteLine(option1)
       Console.WriteLine(option2)
       Console.WriteLine(option3)
       Console.WriteLine()
       Console.WriteLine(exitMsg)

       Console.ReadKey(intercept:=True)
   End Sub

End Module







Pero esta solución del Xml solo sería si lo quieres hacer de forma muy rudimentaria, por que como ya he mencionado antes Visual Studio ya provee herramientas de localización de idioma, y eso es lo que deberías usar si buscas una solución sofisticada, no rudimentaria como el uso de un Xml / String.

Aquí lo tienes todo explicado de la A a la Z:

Si quieres un resumen o mejor dicho un tutorial en C#, lee esto:

Y por cierto, también puedes utilizar la extensión Jollans Multi-Language for Visual Studio para Visual Studio. Es una joya que ahorra mucho tiempo y ayuda a mantener un seguimiento de los idiomas, eso si, es un producto de pago (para quien no sepa encontrar la respectiva "medicina"). Supongo que habrá extensiones gratuitas igualmente especializadas en la localización de idiomas de aplicaciones .NET, pero tampoco lo voy a buscar yo todo por ti...

Saludos.
#506
Cita de: Meta en 25 Febrero 2019, 23:21 PMNo encuentro en referencia el Media.

Me resulta inverosimil que a estas alturas despues de años programando en C# necesites ayuda para resolver este tipo de duda tan básica...




También deberías añadir una referencia al ensamblado WindowsBase.dll y System.Windows.dll para así poder acceder al instrumental básico de la librería de clases de WPF.




Cita de: Meta en 25 Febrero 2019, 23:21 PM
Código (csharp) [Seleccionar]

// Pongo pocos bytes para no agrandar el tema en el foro.

           byte[] rawData = {
   0x4D, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x08
};

¿Esos bytes se supone que son los bytes raw de un archivo de sonido, o que cosa sinó?. En cualqueir caso, la clase System.Windows.Media.MediaPlayer no te va a servir para eso, ya que no acepta un array de bytes o stream, así que primero debes volcar los bytes a un archivo local, y entonces especificar la ruta de dicho archivo en la propiedad MediaPlayer.Source.
Ahora no me vayas a decir que no sabes como crear un archivo con esos bytes, deberías saberlo ya, pero bueno, por si acaso: File.WriteAllBytes(String, Byte[]) - Microsoft Docs o también: FileStream Class (System.IO) | Microsoft Docs.

Como alternativa puedes usar la clase System.Media.SoundPlayer, la cual provee una propiedad SoundPlayer.Stream que te permitirá asignar un objeto de tipo MemoryStream (donde puedes escribir ese array de bytes que tienes), es decir sin necesidad de volcar esos bytes a un archivo local, pero esta clase está limitada a reproducir archivos de sonido WAV (no MP3 ni ningún otro formato).

EDITO:
Acabo de recordar que con la API nativa de MCI (Media Control Interface) también puedes repoducir archivos de audio MP3 (y WAV y MIDI)...
pero esto requiere escribir muchos P/Invokes para luego escribir un wrapper, y creo que dicha API no soporta la reproducción desde un bloque de memoria...

Ahí tienes dos tres opciones. Saludos.
#507
¿Es un ejercicio y te han pedido hacerlo así mediante un búcle while para iterar los elementos del array?, ya que de lo contrario puedes simplificar mucho realizando una sola llamada a la función Array.IndexOf(), la cual te servirá tanto para obtener el índice de un elemento en ese array, como para determinar si un elemento existe o no (en tal caso, Array.IndexOf() devuelve el valor negativo '-1' indicando así que el elemento no existe / no se encontró).

Saludos.
#508
La función InternalConsoleTextBlink que compartí arriba quedaría obsoleta, ya que llamando a la función nativa FillConsoleOutputCharacter se puede simplificar y mejorar mucho su rendimiento y también eliminar algunas imperfecciones visuales que había con el cursor de texto de la consola...

Código (vbnet) [Seleccionar]
<DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Public Shared Function FillConsoleOutputCharacter(ByVal hConsoleOutput As IntPtr,
                                                 ByVal character As Char,
                                                 ByVal length As UInteger,
                                                 ByVal writeCoord As ConsoleCoordinate,
                                         <[Out]> ByRef refNumberOfCharsWritten As UInteger
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

<DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Public Shared Function FillConsoleOutputAttribute(ByVal hConsoleOutput As IntPtr,
                                                 ByVal attribute As CharInfoAttributes,
                                                 ByVal length As UInteger,
                                                 ByVal writeCoord As ConsoleCoordinate,
                                         <[Out]> ByRef refNumberOfAttrsWritten As UInteger
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function


El algoritmo final sería este:
Código (vbnet) [Seleccionar]
<DebuggerStepThrough>
Private Function InternalConsoleTextBlink(ByVal position As System.Drawing.Point, ByVal length As Integer, ByVal interval As TimeSpan, ByVal count As Integer) As CancellationTokenSource

   If (count <= 0) Then
       Throw New ArgumentException(paramName:=NameOf(count), message:="Value greater than 0 is required.")
   End If

   If (interval.TotalMilliseconds <= 0) Then
       Throw New ArgumentException(paramName:=NameOf(interval), message:="Value greater than 0 is required.")
   End If

   Dim cts As New CancellationTokenSource()

   Dim t As New Task(
       Sub()
           Dim x As Short = CShort(position.X)
           Dim y As Short = CShort(position.Y)
           Dim width As Short = CShort(length)
           Dim height As Short = 1S
           Dim buffer As IntPtr = Marshal.AllocHGlobal(width * height * Marshal.SizeOf(GetType(CharInfo)))
           Dim blinkCount As Integer

           Try
               Dim bufferCoord As New ConsoleCoordinate()
               Dim bufferSize As New ConsoleCoordinate With {
                   .X = width,
                   .Y = height
               }

               Dim rc As New NativeRectangleSmall With {
                   .Left = x,
                   .Top = y,
                   .Right = (x + width - 1S),
                   .Bottom = (y + height - 1S)
               }

               Dim stdOutHandle As IntPtr = NativeMethods.GetStdHandle(ConsoleStd.StandardOutput)
               If Not NativeMethods.ReadConsoleOutput(stdOutHandle, buffer, bufferSize, bufferCoord, rc) Then
                   ' Not enough storage is available to process this command' may be raised for buffer size > 64K (see ReadConsoleOutput doc.)
                   Throw New Win32Exception(Marshal.GetLastWin32Error())
               End If

               Dim charDict As New Dictionary(Of CharInfo, ConsoleCoordinate)

               Dim ptr As IntPtr = buffer
               For heightIndex As Integer = 0 To (height - 1)
                   For widthIndex As Integer = 0 To (width - 1)
                       Dim ci As CharInfo = DirectCast(Marshal.PtrToStructure(ptr, GetType(CharInfo)), CharInfo)
                        charDict.Add(ci, New ConsoleCoordinate() With {
                                 .X = CShort(position.X + widthIndex),
                                 .Y = CShort(position.Y + heightIndex)})
                       ptr += Marshal.SizeOf(GetType(CharInfo))
                   Next widthIndex
               Next heightIndex

               Do Until cts.Token.IsCancellationRequested
                   ' Remove text.
                   NativeMethods.FillConsoleOutputCharacter(stdOutHandle, " "c, CUInt(length), charDict.Values(0), Nothing)
                   Thread.Sleep(interval)

                   ' Write Text.
                   For Each kv As KeyValuePair(Of CharInfo, ConsoleCoordinate) In charDict
                       Dim c As Char = System.Console.OutputEncoding.GetChars(kv.Key.CharData)(0)
                       NativeMethods.FillConsoleOutputAttribute(stdOutHandle, kv.Key.Attributes, 1, kv.Value, Nothing)
                       NativeMethods.FillConsoleOutputCharacter(stdOutHandle, c, 1, kv.Value, Nothing)
                   Next kv

                   If Interlocked.Increment(blinkCount) = count Then
                       If (cts.Token.CanBeCanceled) Then
                           cts.Cancel()
                       End If
                       Exit Do
                   End If
                   Thread.Sleep(interval)
               Loop

           Finally
               Marshal.FreeHGlobal(buffer)

           End Try

       End Sub, cts.Token)

   t.Start()
   Return cts

End Function


EDITO: código actualizado.

Saludos.
#509
Entonces busca ejemplos para C++ o java. En los enlaces de arriba creo que puse uno para C++. Saludos.
#510
Cita de: programatrix en 16 Febrero 2019, 23:55 PMun partido legítimamente democrático como VOX

Si... bueno... yo no se demasiado de política así que no me tireis a la yugular, pero todos hemos vivido hace unos años esa época en la que "Podemos" al pincipio era muy democrático, era la supuesta salvación de España, y luego mira lo que ha resultado ser... una panda de izquierdistas RADICALES hipocritas y maleducados que de democráticos no tienen nada, pero que consiguieron embaucar casi a la mitad de la población en aquella época con sus promesas vacías y las ganas de destronar al PP... así que mucho cuidado con VOX por que podrían ser exactamente igual, o incluso peores.

El tiempo lo dirá con VOX, pero yo estoy convencido de que al final todo es más de la misma m1erd@ por muy democráticos que sean (o parezcan ser) al principio. La ida de Pedro Sanchez siempre será algo positivo para el país, pero no se yo hasta que punto compensará que puedan gobernar otros...

Un saludo.