elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (Moderadores: Novlucker, seba123neo, kub0x, Eleкtro)
| | | |-+  Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 ... 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 [51] Ir Abajo Respuesta Imprimir
Autor Tema: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)  (Leído 166,722 veces)
Eleкtro
Novato Astral y
Moderador Global
***
Conectado Conectado

Mensajes: 8.848


El sentido común es el menos común de los sentidos


Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #500 en: 14 Marzo 2017, 21:29 »

No importa la versión de Visual Studio

En realidad si que importa. Cada nueva versión de Visual Studio añade modificaciones mejoradas en el empleo de sintaxis de C#/VB.NET. Dichas mejores evidentemente son incompatibles en versiones anteriores de Visual Studio.

Por ejemplo en VB.NET 14.0 (Visual Studio 2015) se pueden especificar strings multi linea lieterales, mientras que en las versioens anteriores de VB.NET, no.

VB.NET 14.0:
Código
  1.        Dim json = "{
  2.  'Name': 'Bad Boys',
  3.  'ReleaseDate': '1995-4-7T00:00:00',
  4.  'Genres': ['Action','Comedy']
  5. }"

El codigo de arriba daria error de compilación en versiones anteriores de VB.NET/VS. Habría que hacerlo más o menos así:
Código
  1.        Dim json = "{" & Environment.NewLine &
  2. "  'Name': 'Bad Boys'," & Environment.NewLine &
  3. "  'ReleaseDate': '1995-4-7T00:00:00'," & Environment.NewLine &
  4. "  'Genres': ['Action','Comedy']" & Environment.NewLine &
  5. "}"

Los snippets que compartí en este hilo fueron desarrollados bajo VS2013, y algunos en VS2015.

PD: Como ya dije, C# también tiene sus mejoras.

¡Saludos!


« Última modificación: 14 Marzo 2017, 21:35 por Eleкtro » En línea


Eleкtro
Novato Astral y
Moderador Global
***
Conectado Conectado

Mensajes: 8.848


El sentido común es el menos común de los sentidos


Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #501 en: 1 Abril 2017, 16:22 »

Hace mucho tiempo que no publico nada aquí...

Vamos allá:



¿Cómo validar el número de una tarjeta de crédito?

Para ello podemos implementar el algoritmo Luhn.

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Uses the Luhn algorithm to determines whether the specified credit card number is valid.
  4. ''' <para></para>
  5. ''' Please de aware that not all valid credit cards can be verified with the Luhn algorithm because
  6. ''' it not covers all range of card numbers, however the Luhn algorithm does work for many, if not most, major credit cards.
  7. ''' <para></para>
  8. ''' The Luhn algorithm is simply used to prevent transpositional errors,
  9. ''' it is useful as a sanity check prior to submitting card numbers to a payment gateway,
  10. ''' but not suitable to absolutely validate whether a number is a valid card number.
  11. ''' <para></para>
  12. ''' The only way to absolutely verify a credit card number is to validate it via a payment gateway.
  13. ''' </summary>
  14. ''' ----------------------------------------------------------------------------------------------------
  15. ''' <remarks>
  16. ''' Luhn algorithm: <see href="https://en.wikipedia.org/wiki/Luhn_algorithm"/>
  17. ''' <para></para>
  18. ''' Microsoft's Luhn algorithm implementation: <see href="http://referencesource.microsoft.com/#System.ComponentModel.DataAnnotations/DataAnnotations/CreditCardAttribute.cs"/>
  19. ''' <para></para>
  20. ''' Credits to: <see href="http://www.vcskicks.com/credit-card-verification.php"/>
  21. ''' </remarks>
  22. ''' ----------------------------------------------------------------------------------------------------
  23. ''' <example> This is a code example.
  24. ''' <code>
  25. ''' Dim visaNumber As String = "4012888888881881"
  26. ''' Dim isValid As Boolean = ValidateCreditCardNumber(visaNumber)
  27. ''' </code>
  28. ''' </example>
  29. ''' ----------------------------------------------------------------------------------------------------
  30. ''' <param name="cardNumber">
  31. ''' The credit card number.
  32. ''' </param>
  33. ''' ----------------------------------------------------------------------------------------------------
  34. ''' <returns>
  35. ''' <see langword="True"/> if the specified card number is a valid card number; otherwise, <see langword="False"/>.
  36. ''' </returns>
  37. ''' ----------------------------------------------------------------------------------------------------
  38. Public Shared Function ValidateCreditCardNumber(ByVal cardNumber As String) As Boolean
  39.  
  40.    cardNumber = cardNumber.Replace(" ", "").Replace("-", "").Trim()
  41.  
  42.    ' FIRST STEP: Double each digit starting from the right
  43.    Dim doubledDigits As Integer() = New Integer(cardNumber.Length / 2 - 1) {}
  44.    Dim k As Integer = 0
  45.    For i As Integer = cardNumber.Length - 2 To 0 Step -2
  46.        Dim digit As Integer
  47.        If Not Integer.TryParse(cardNumber(i), digit) Then
  48.            Return False
  49.        End If
  50.        doubledDigits(k) = digit * 2
  51.        k += 1
  52.    Next i
  53.  
  54.    ' SECOND STEP: Add up separate digits
  55.    Dim total As Integer = 0
  56.    For Each i As Integer In doubledDigits
  57.        Dim number As String = i.ToString()
  58.        For j As Integer = 0 To (number.Length - 1)
  59.            total += Integer.Parse(number(j).ToString())
  60.        Next j
  61.    Next i
  62.  
  63.    ' THIRD STEP: Add up other digits
  64.    Dim total2 As Integer = 0
  65.    For i As Integer = cardNumber.Length - 1 To 0 Step -2
  66.        Dim digit As Integer = Integer.Parse(cardNumber(i).ToString())
  67.        total2 += digit
  68.    Next i
  69.  
  70.    ' FOURTH STEP: Total
  71.    Dim final As Integer = (total + total2)
  72.  
  73.    Return (final Mod 10 = 0) ' Well formed will divide evenly by 10.
  74.  
  75. End Function

Modo de empleo:
Código
  1. ' http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
  2. Dim visaNumber As String = "4012888888881881"
  3. Dim isValid As Boolean = ValidateCreditCardNumber(visaNumber)

Aquí les dejo unos números de tarjetas de crédito para testear:
Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Contains a collection of credit card numbers for testing purposes.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <remarks>
  7. ''' <see href="http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm"/>
  8. ''' </remarks>
  9. ''' ----------------------------------------------------------------------------------------------------
  10. ''' <example> This is a code example.
  11. ''' <code>
  12. ''' For Each card As KeyValuePair(Of String, String()) In CreditCardsTestNumbers
  13. '''     For Each cardnumber As String In card.Value
  14. '''         Dim isValidNumber As Boolean = ValidateCreditCardNumber(cardnumber)
  15. '''         Console.WriteLine("Card type: '{0}'; Number: '{1}'; Is Valid?: {2}", card.Key, cardnumber, isValidNumber)
  16. '''     Next cardnumber
  17. ''' Next card
  18. ''' </code>
  19. ''' </example>
  20. ''' ----------------------------------------------------------------------------------------------------
  21. Public Shared ReadOnly CreditCardsTestNumbers As New Dictionary(Of String, String())(StringComparison.OrdinalIgnoreCase) From {
  22.    {"American Express", {"378282246310005", "371449635398431"}},
  23.    {"American Express Corporate", {"378734493671000"}},
  24.    {"Australian BankCard", {"5610591081018250"}},
  25.    {"Dankort (PBS)", {"5019717010103742", "76009244561"}},
  26.    {"Diners Club", {"30569309025904", "38520000023237"}},
  27.    {"Discover", {"6011111111111117", "6011000990139424"}},
  28.    {"JCB", {"3530111333300000", "3566002020360505"}},
  29.    {"Mastercard", {"5555555555554444", "5105105105105100"}},
  30.    {"Switch/Solo (Paymentech)", {"6331101999990016"}},
  31.    {"VISA", {"4111111111111111", "4012888888881881", "4222222222222"}}
  32. }



¿Cómo auto-eliminar el executable de nuestra aplicación?

Para ello podemos escribir las instrucciones de eliminación en un archivo.bat externo, e iniciarlo.

¿Por qué Batch?, bueno, en un principio podriamos pensar en una solución usando puro código .NET por ejemplo compilando un código fuente en tiempo de ejecución para generar un executable de .NET temporal con las instrucciones de terminación del proceso y de eliminación del archivo, pero al hacer esto nos estaríamos metiendo en un círculo vicioso ya que el executable externo no se podría eliminar a si mismo, por ende, esta es una de las pocas ocasiones en las que Batch sirve para salvarnos de un apuro.

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Deletes the self application executable file.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. Public Shared Sub DeleteSelfApplication()
  7.    DeleteSelfApplication(TimeSpan.FromMilliseconds(0))
  8. End Sub
  9.  
  10. ''' ----------------------------------------------------------------------------------------------------
  11. ''' <summary>
  12. ''' Deletes the self application executable file.
  13. ''' </summary>
  14. ''' ----------------------------------------------------------------------------------------------------
  15. ''' <param name="delay">
  16. ''' A delay interval to wait (asynchronously) before proceeding to automatic deletion.
  17. ''' </param>
  18. ''' ----------------------------------------------------------------------------------------------------
  19. Public Shared Async Sub DeleteSelfApplication(ByVal delay As TimeSpan)
  20.  
  21.    If (delay.TotalMilliseconds > 0.0R) Then
  22.        Dim t As New Task(Sub() Thread.Sleep(delay))
  23.        t.Start()
  24.        Await t
  25.    End If
  26.  
  27.    Dim script As String = <a>
  28. @Echo OFF
  29.  
  30. Set "exeName=%~nx1"
  31. Set "exePath=%~f1"
  32.  
  33. :KillProcessAndDeleteExe
  34. (TaskKill.exe /F /IM "%exeName%")1>NUL 2>&amp;1
  35. If NOT Exist "%exePath%" (GoTo :SelfDelete)
  36. (DEL /Q /F "%exePath%") || (GoTo :KillProcessAndDeleteExe)
  37.  
  38. :SelfDelete
  39. (DEL /Q /F "%~f0")
  40. </a>.Value
  41.  
  42.    Dim tmpFile As New FileInfo(Path.Combine(Path.GetTempPath, Path.GetTempFileName))
  43.    tmpFile.MoveTo(Path.Combine(tmpFile.DirectoryName, tmpFile.Name & ".cmd"))
  44.    tmpFile.Refresh()
  45.    File.WriteAllText(tmpFile.FullName, script, Encoding.Default)
  46.  
  47.    Using p As New Process()
  48.        With p.StartInfo
  49.            .FileName = tmpFile.FullName
  50.            .Arguments = String.Format(" ""{0}"" ", Application.ExecutablePath)
  51.            .WindowStyle = ProcessWindowStyle.Hidden
  52.            .CreateNoWindow = True
  53.        End With
  54.        p.Start()
  55.        p.WaitForExit(0)
  56.    End Using
  57.  
  58.    Environment.Exit(0)
  59.  
  60. End Sub

Modo de empleo:
Código
  1. ' Auto destruir el executable al instante:
  2. DeleteSelfApplication()
  3.  
  4. ' Auto destruir el executable de forma asincrónica con un tiempo de espera de 5 segundos:
  5. DeleteSelfApplication(TimeSpan.FromSeconds(5))

El contenido del archivo.bat generado sería el siguiente:
Código
  1. @Echo OFF
  2.  
  3. Set "exeName=%~nx1"
  4. Set "exePath=%~f1"
  5.  
  6. :KillProcessAndDeleteExe
  7. (TaskKill.exe /F /IM "%exeName%")1>NUL 2>&amp;1
  8. If NOT Exist "%exePath%" (GoTo :SelfDelete)
  9. (DEL /Q /F "%exePath%") || (GoTo :KillProcessAndDeleteExe)
  10.  
  11. :SelfDelete
  12. (DEL /Q /F "%~f0")
...Lo primero que hará el script será entrar en un búcle infinito donde se intentará matar el proceso, y una vez conseguido se dispondrá a eliminar el archivo, y por último eliminarse a sí mismo.



¿Cómo guardar y restaurar el estado expandido/colapsado de los nodos de un TreeView?

Pongámonos en situación, imaginemos que tenemos un control de tipo TreeView en el que tenemos que crear y destruir algunos de sus nodos o todos ellos de forma dinámica, y al hacerlo perderiamos el estado expandido/colapsado de cada nodo al refrescar la lista de nodos.

U otra situación distinta, en la que simplemente quisieramos guardar el estado del TreeView al cerrar la aplicación, para cargar ese estado en el próximo inicio de la aplicación.

Bien, pues para solucionar ese tipo de problema primero crearíamos la siguiente función que nos devolverá una lista con todos los nodos y sus nodos hijos de un TreeView:

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Gets all the parent nodes and all its child nodes in the source <see cref="TreeView"/>.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <example> This is a code example.
  7. ''' <code>
  8. ''' Dim nodeList As List(Of TreeNode) = Me.TreeView1.GetAllNodesAndChildnodes()
  9. '''
  10. ''' For Each node As TreeNode In nodeList
  11. '''     ' ...
  12. ''' Next node
  13. ''' </code>
  14. ''' </example>
  15. ''' ----------------------------------------------------------------------------------------------------
  16. ''' <param name="sender">
  17. ''' The source <see cref="TreeView"/>.
  18. ''' </param>
  19. ''' ----------------------------------------------------------------------------------------------------
  20. ''' <returns>
  21. ''' A <see cref="List(Of TreeNode)"/> containing all the parent nodes and all its child nodes.
  22. ''' </returns>
  23. ''' ----------------------------------------------------------------------------------------------------
  24. Public Shared Function GetAllNodesAndChildnodes(ByVal sender As TreeView) As List(Of TreeNode)
  25.  
  26.    Dim nodes As New List(Of TreeNode)
  27.    Dim stack As New Stack(Of TreeNode)
  28.  
  29.    ' Bang all the top nodes into the queue.
  30.    For Each top As TreeNode In sender.Nodes
  31.        stack.Push(top)
  32.    Next
  33.  
  34.    While (stack.Count > 0)
  35.        Dim node As TreeNode = stack.Pop()
  36.        If (node IsNot Nothing) Then
  37.            ' Add the node to the list of nodes.
  38.            nodes.Add(node)
  39.  
  40.            If (node.Nodes IsNot Nothing) And (node.Nodes.Count > 0) Then
  41.                ' Enqueue the child nodes.
  42.                For Each child As TreeNode In node.Nodes
  43.                    stack.Push(child)
  44.                Next child
  45.            End If
  46.        End If
  47.    End While
  48.  
  49.    stack.Clear()
  50.    stack = Nothing
  51.    Return nodes
  52.  
  53. End Function

Ahora solo tenemos que crear una función para iterar los nodos obtenidos y así crear un "estado de guardado" (o save state), el cual consistitía en un diccionario que contendrá el código hash identificador de cada nodo, y un valor boolean indicando si el nodo está expandido o colapsado.

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Saves the state of the source <see cref="TreeView"/> into a <see cref="Dictionary(Of Integer, Boolean)"/>
  4. ''' containing the hash code of each node and its expansion state.
  5. ''' </summary>
  6. ''' ----------------------------------------------------------------------------------------------------
  7. ''' <example> This is a code example.
  8. ''' <code>
  9. ''' Dim saveState As Dictionary(Of Integer, Boolean) = Me.TreeView1.SaveTreeState()
  10. ''' </code>
  11. ''' </example>
  12. ''' ----------------------------------------------------------------------------------------------------
  13. ''' <param name="sender">
  14. ''' The source <see cref="TreeView"/>.
  15. ''' </param>
  16. ''' ---------------------------------------------------------------------------------------------------
  17. ''' <returns>
  18. ''' A <see cref="Dictionary(Of Integer, Boolean)"/> containing the hash code of each node and its expansion state.
  19. ''' </returns>
  20. ''' ----------------------------------------------------------------------------------------------------
  21. Public Shared Function SaveTreeState(ByVal sender As TreeView) As Dictionary(Of Integer, Boolean)
  22.  
  23.    Dim nodeList As List(Of TreeNode) = GetAllNodesAndChildnodes(sender)
  24.    Dim nodeStates As New Dictionary(Of Integer, Boolean)()
  25.  
  26.    For Each node As TreeNode In nodeList
  27.        nodeStates.Add(node.GetHashCode(), node.IsExpanded)
  28.    Next
  29.  
  30.    Return nodeStates
  31.  
  32. End Function

Y por último la función para restaurar un estado de guardado:
Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Restores a state of the source <see cref="TreeView"/> previously saved using the <see cref="SaveTreeState"/> function.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <example> This is a code example.
  7. ''' <code>
  8. ''' Dim saveState As Dictionary(Of Integer, Boolean)
  9. '''
  10. ''' Private Sub Button_SaveTreeState(sender As Object, e As EventArgs) Handles Button_SaveTreeState.Click
  11. '''     saveState = Me.TreeView1.SaveTreeState()
  12. ''' End Sub
  13. '''
  14. ''' Private Sub Button_RestoreTreeState(sender As Object, e As EventArgs) Handles Button_RestoreTreeState.Click
  15. '''     Me.TreeView1.RestoreTreeState(saveState)
  16. ''' End Sub
  17. ''' </code>
  18. ''' </example>
  19. ''' ----------------------------------------------------------------------------------------------------
  20. ''' <param name="sender">
  21. ''' The source <see cref="TreeView"/>.
  22. ''' </param>
  23. ''' ----------------------------------------------------------------------------------------------------
  24. ''' <param name="saveState">
  25. ''' A <see cref="Dictionary(Of Integer, Boolean)"/> containing the hash code of each node and its expansion state.
  26. ''' </param>
  27. ''' ----------------------------------------------------------------------------------------------------
  28. Public Shared Sub RestoreTreeState(ByVal sender As TreeView, ByVal saveState As Dictionary(Of Integer, Boolean))
  29.  
  30.    Dim nodeList As List(Of TreeNode) = GetAllNodesAndChildnodes(sender)
  31.  
  32.    For Each node As TreeNode In nodeList
  33.  
  34.        Dim hash As Integer = node.GetHashCode()
  35.  
  36.        If saveState.ContainsKey(hash) Then
  37.  
  38.            If saveState(hash) Then
  39.                node.Expand()
  40.            Else
  41.                node.Collapse()
  42.            End If
  43.  
  44.        End If
  45.  
  46.    Next
  47.  
  48. End Sub



Todas estas funcionalidades y muchísimas más las podrán encontrar en mi Framework de pago ElektroKit.


« Última modificación: 1 Abril 2017, 18:06 por Eleкtro » En línea


Eleкtro
Novato Astral y
Moderador Global
***
Conectado Conectado

Mensajes: 8.848


El sentido común es el menos común de los sentidos


Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #502 en: 1 Abril 2017, 17:55 »

¿Cómo determinar cual es la versión más reciente instalada de .NET Framework en la máquina actual?.

Aquí les dejo el código fuente completo:

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Determines which is the most recent version of the .NET Framework runtimes installed on the current machine.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <example> This is a code example.
  7. ''' <code>
  8. ''' Dim frameworkVersion As Version = GetMostRecentInstalledFrameworkVersion()
  9. ''' Console.WriteLine(frameworkVersion.ToString())
  10. ''' </code>
  11. ''' </example>
  12. ''' ----------------------------------------------------------------------------------------------------
  13. ''' <remarks>
  14. ''' Credits to Microsoft: <see href="http://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx"/>
  15. ''' </remarks>
  16. ''' ----------------------------------------------------------------------------------------------------
  17. ''' <returns>
  18. ''' The resulting .NET Framework <see cref="Version"/>.
  19. ''' </returns>
  20. ''' ----------------------------------------------------------------------------------------------------
  21. <DebuggerStepperBoundary>
  22. Private Shared Function GetMostRecentInstalledFrameworkVersion() As Version
  23.  
  24.    ' .NET 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1
  25.    Using ndpKey As RegistryKey =
  26.        RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).
  27.                    OpenSubKey("SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\", writable:=False)
  28.  
  29.        If (ndpKey IsNot Nothing) AndAlso (ndpKey.GetValue("Release") IsNot Nothing) Then
  30.            Dim releaseVersion As Integer = CInt(ndpKey.GetValue("Release"))
  31.            Select Case releaseVersion
  32.                Case >= 394254
  33.                    Return New Version(4, 6, 1)
  34.                Case >= 393295
  35.                    Return New Version(4, 6)
  36.                Case >= 379893
  37.                    Return New Version(4, 5, 2)
  38.                Case >= 378675
  39.                    Return New Version(4, 5, 1)
  40.                Case >= 378389
  41.                    Return New Version(4, 5)
  42.            End Select
  43.        End If
  44.    End Using
  45.  
  46.    ' .NET 1.0, 2.0, 3.0, 3.5, 4.0
  47.    Using ndpKey As RegistryKey =
  48.        RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
  49.                    OpenSubKey("SOFTWARE\Microsoft\NET Framework Setup\NDP\", writable:=False)
  50.  
  51.        For Each versionKeyName As String In ndpKey.GetSubKeyNames().OrderByDescending(Function(x As String) x)
  52.            If versionKeyName.ToLower().StartsWith("v") Then
  53.                Return New Version(versionKeyName.ToLower().TrimStart("v"c))
  54.            End If
  55.        Next versionKeyName
  56.    End Using
  57.  
  58.    Return New Version()
  59.  
  60. End Function

Personálmente recomiendo decorar esta funcionalidad mediante una propiedad de sólo lectura, tal que así:
Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Gets a value that determines which is the most recent version of the .NET Framework runtimes installed
  4. ''' on the current machine.
  5. ''' </summary>
  6. ''' ----------------------------------------------------------------------------------------------------
  7. ''' <value>
  8. ''' A value that determines which is the most recent version of the .NET Framework runtimes installed
  9. ''' on the current machine.
  10. ''' </value>
  11. ''' ----------------------------------------------------------------------------------------------------
  12. Public Shared ReadOnly Property MostRecentInstalledFrameworkVersion As Version
  13.    <DebuggerStepThrough>
  14.    Get
  15.        Return GetMostRecentInstalledFrameworkVersion()
  16.    End Get
  17. End Property

Modo de empleo:
Código
  1. Dim frameworkVersion As Version = GetMostRecentInstalledFrameworkVersion()
  2. Console.WriteLine(frameworkVersion.ToString())

Notas: Faltaría implementar la versión de .NET 4.6.2. Aparte de eso no he podio testear en profundidad el resultado obtenido en un equipo que tenga instalado .NET 1.0, 2.0, 3.0, 3.5 o 4.0, si encuentran algún error diganmelo.



Códigos de error Win32.

Esto que voy a compartir a continuación es una enumeración con todos los errores Win32 de la API de Windows, en total son +13.000 lineas de código, así que os dejo un enlace externo:


El propósito de gigantesca enumeración es proveer una manera sencilla, directa y eficiente de determinar que error nos devuelve en ocasiones una función de la API de Windows y cual es el significado de dicho código de error.

No confundir un código de error Win32 con un código de error H_RESULT, esto último define muchos errores Win32 pero con otros valores.

Recordad que la librería de clases de .NET Framework expone algunos miembros muy útiles para la evaluación de errores de funciones no administradas, Marshal.GetLastWin32Error(), Marshal.GetHRForLastWin32Error() y Marshal.ThrowExceptionForHR() así como el tipo excepción System.ComponentModel.Win32Exception que podemos invocar para informarle de un error Win32 específico al usuario.



¿Cómo prevenir el Flickering de un control Win32?.

Uno de los mayores problemas estéticos y también de lo más común al trabajar con los controles de la tecnología WindowsForms es el Flickering. El Flicker consiste en un desagradable parpadeo de la imagen en donde la imagen desaparece por un breve tiempo lapso de tiempo hasta que vuelve a aparecer, como un parpadeo. Es un problema visual que afecta a la estética del control, y suele producirse muy a menudo cuando el control necesita realizar operaciones de dibujo muy expensivas, o cuando estamos trabajando con transparencias.

Una descripción más detallada del flickering: https://en.wikipedia.org/wiki/Flicker_(screen)

¿Cómo se soluciona el Flickering?, pues lamentablemente no se puede solucionar completamente, pero si que podemos llegar a reducir el Flickering considerablemente y en el mejor de los casos hasta llegar a dejar de percibirlo del todo y poder decir que ya no hay Flickering en el control, ¿pero cómo se hace?, pues una solución cotidiana sería con un bufer doble de memoria, o double buffering.

Cuando el double buffering está activado, todas las operaciones de dibujado del control son renderizadas primero a un bufer de memoria en vez de ser renderizadas directamente a la superficie de dibujado en la pantalla. Cuando todas las operaciones de dibujado han sido completadas, el bufer de memoria es copiado directamente a la superficie de dibujado asociada a él.

Para tratar de solventar los problemas de Flickering cuando estamos desarrollando un control de usuario, he desarrollado una interfáz con nombre IBufferedControl, la cual implementariamos en nuestro control:

Código
  1. ' ***********************************************************************
  2. ' Author   : Elektro
  3. ' Modified : 20-March-2017
  4. ' ***********************************************************************
  5.  
  6. #Region " Public Members Summary "
  7.  
  8. #Region " Properties "
  9.  
  10. ' CreateParams As CreateParams
  11. ' DoubleBuffered As Boolean
  12. ' PreventFlickering As Boolean
  13.  
  14. #End Region
  15.  
  16. #End Region
  17.  
  18. #Region " Option Statements "
  19.  
  20. Option Strict On
  21. Option Explicit On
  22. Option Infer Off
  23.  
  24. #End Region
  25.  
  26. #Region " Imports "
  27.  
  28. Imports System.ComponentModel
  29. Imports System.Windows.Forms
  30.  
  31. #End Region
  32.  
  33. #Region " IBufferedControl "
  34.  
  35. Namespace Types
  36.  
  37.    ''' ----------------------------------------------------------------------------------------------------
  38.    ''' <summary>
  39.    ''' Provides simple double buffering (anti flickering) functionality for a Windows Forms <see cref="Control"/>,
  40.    ''' such for example a <see cref="TextBox"/>.
  41.    ''' </summary>
  42.    ''' ----------------------------------------------------------------------------------------------------
  43.    Public Interface IBufferedControl
  44.  
  45.        ''' ----------------------------------------------------------------------------------------------------
  46.        ''' <summary>
  47.        ''' Gets the required creation parameters when the control handle is created.
  48.        ''' </summary>
  49.        ''' ----------------------------------------------------------------------------------------------------
  50.        ''' <value>
  51.        ''' The creation parameters.
  52.        ''' </value>
  53.        ''' ----------------------------------------------------------------------------------------------------
  54.        <Browsable(False)>
  55.        <EditorBrowsable(EditorBrowsableState.Advanced)>
  56.        ReadOnly Property CreateParams As CreateParams
  57.        ' Implementation Exmple:
  58.        '
  59.        ' Protected Overrides ReadOnly Property CreateParams As CreateParams Implements IBufferedControl.CreateParams
  60.        '     Get
  61.        '         If (Me.preventFlickeringB) Then
  62.        '             Dim cp As CreateParams = MyBase.CreateParams
  63.        '             cp.ExStyle = (cp.ExStyle Or CInt(WindowStylesEx.Composited))
  64.        '             Return cp
  65.        '         Else
  66.        '             Return MyBase.CreateParams
  67.        '         End If
  68.        '     End Get
  69.        ' End Property
  70.  
  71.        ''' ----------------------------------------------------------------------------------------------------
  72.        ''' <summary>
  73.        ''' Gets or sets a value indicating whether this control should redraw its surface using a secondary buffer
  74.        ''' to reduce or prevent flicker.
  75.        ''' </summary>
  76.        ''' ----------------------------------------------------------------------------------------------------
  77.        ''' <value>
  78.        ''' <see langword="True"/> if the surface of the control should be drawn using double buffering;
  79.        ''' otherwise, <see langword="False"/>.
  80.        ''' </value>
  81.        ''' ----------------------------------------------------------------------------------------------------
  82.        <Browsable(True)>
  83.        <EditorBrowsable(EditorBrowsableState.Always)>
  84.        <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
  85.        <Localizable(True)>
  86.        <Category("Behavior")>
  87.        <Description("Indicates whether this control should redraw its surface using a secondary buffer to reduce or prevent flicker.")>
  88.        <DefaultValue(GetType(Boolean), "True")>
  89.        Property DoubleBuffered As Boolean
  90.        ' Implementation Exmple:
  91.        '
  92.        ' Public Overridable Shadows Property DoubleBuffered As Boolean Implements IBufferedControl.DoubleBuffered
  93.        '     Get
  94.        '         Return MyBase.DoubleBuffered
  95.        '     End Get
  96.        '     Set(ByVal value As Boolean)
  97.        '         Me.SetStyle(ControlStyles.DoubleBuffer, value)
  98.        '         MyBase.DoubleBuffered = value
  99.        '     End Set
  100.        ' End Property
  101.  
  102.        ''' ----------------------------------------------------------------------------------------------------
  103.        ''' <summary>
  104.        ''' Gets or sets a value that indicates whether the control should avoid unwanted flickering effects.
  105.        ''' <para></para>
  106.        ''' If <see langword="True"/>, this will avoid any flickering effect on the control, however,
  107.        ''' it will also have a negative impact by slowing down the responsiveness of the control about to 30% slower.
  108.        ''' <para></para>
  109.        ''' This negative impact doesn't affect to the performance of the application itself,
  110.        ''' just to the performance of this control.
  111.        ''' </summary>
  112.        ''' ----------------------------------------------------------------------------------------------------
  113.        ''' <value>
  114.        ''' A value that indicates whether the control should avoid unwanted flickering effects.
  115.        ''' </value>
  116.        ''' ----------------------------------------------------------------------------------------------------
  117.        <Browsable(True)>
  118.        <EditorBrowsable(EditorBrowsableState.Always)>
  119.        <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
  120.        <Localizable(True)>
  121.        <Category("Behavior")>
  122.        <Description("Indicates whether the control should avoid unwanted flickering effects. If True, this will avoid any flickering effect on the control, however, it will also have a negative impact by slowing down the responsiveness of the control about to 30% slower.")>
  123.        <DefaultValue(GetType(Boolean), "False")>
  124.        Property PreventFlickering As Boolean
  125.        ' Implementation Exmple:
  126.        '
  127.        ' Public Overridable Property PreventFlickering As Boolean Implements IBufferedControl.PreventFlickering
  128.        '     Get
  129.        '         Return Me.preventFlickeringB
  130.        '     End Get
  131.        '     Set(ByVal value As Boolean)
  132.        '         Me.preventFlickeringB = value
  133.        '     End Set
  134.        ' End Property
  135.        ' ''' ----------------------------------------------------------------------------------------------------
  136.        ' ''' <summary>
  137.        ' ''' ( Backing Field )
  138.        ' ''' A value that indicates whether the control should avoid unwanted flickering effects.
  139.        ' ''' </summary>
  140.        ' ''' ----------------------------------------------------------------------------------------------------
  141.        ' Private preventFlickeringB As Boolean
  142.  
  143.    End Interface
  144.  
  145. End Namespace
  146.  
  147. #End Region

Un ejemplo de implementación:
Código
  1. <DisplayName("MyControl")>
  2. <Description("A extended control.")>
  3. <DesignTimeVisible(True)>
  4. <DesignerCategory("UserControl")>
  5. <ToolboxBitmap(GetType(UserControl))>
  6. <ToolboxItemFilter("System.Windows.Forms", ToolboxItemFilterType.Require)>
  7. <PermissionSet(SecurityAction.Demand, Name:="FullTrust")>
  8. Public Class MyControl : Inherits UserControl : Implements IBufferedControl
  9.  
  10.    ''' ----------------------------------------------------------------------------------------------------
  11.    ''' <summary>
  12.    ''' Gets the required creation parameters when the control handle is created.
  13.    ''' <para></para>
  14.    ''' The information returned by the <see cref="CreateParams"/> property is used to pass information about the
  15.    ''' initial state and appearance of this control, at the time an instance of this class is being created.
  16.    ''' </summary>
  17.    ''' ----------------------------------------------------------------------------------------------------
  18.    ''' <value>
  19.    ''' The creation parameters.
  20.    ''' </value>
  21.    ''' ----------------------------------------------------------------------------------------------------
  22.    <Browsable(False)>
  23.    <EditorBrowsable(EditorBrowsableState.Advanced)>
  24.    <Description("The required creation parameters when the control handle is created.")>
  25.    Protected Overrides ReadOnly Property CreateParams As CreateParams Implements IBufferedControl.CreateParams
  26.        Get
  27.            If (Me.preventFlickeringB) Then
  28.                Dim cp As CreateParams = MyBase.CreateParams
  29.                cp.ExStyle = (cp.ExStyle Or CInt(WindowStylesEx.Composited))
  30.                Return cp
  31.            Else
  32.                Return MyBase.CreateParams
  33.            End If
  34.        End Get
  35.    End Property
  36.  
  37.    ''' ----------------------------------------------------------------------------------------------------
  38.    ''' <summary>
  39.    ''' Gets or sets a value indicating whether this control should redraw its surface using a secondary buffer
  40.    ''' to reduce or prevent flicker.
  41.    ''' </summary>
  42.    ''' ----------------------------------------------------------------------------------------------------
  43.    ''' <value>
  44.    ''' <see langword="True"/> if the surface of the control should be drawn using double buffering;
  45.    ''' otherwise, <see langword="False"/>.
  46.    ''' </value>
  47.    ''' ----------------------------------------------------------------------------------------------------
  48.    <Browsable(True)>
  49.    <EditorBrowsable(EditorBrowsableState.Always)>
  50.    <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
  51.    <Localizable(True)>
  52.    <Category("Behavior")>
  53.    <Description("Indicates whether this control should redraw its surface using a secondary buffer to reduce or prevent flicker.")>
  54.    <DefaultValue(GetType(Boolean), "False")>
  55.    Public Overridable Shadows Property DoubleBuffered As Boolean Implements IBufferedControl.DoubleBuffered
  56.        Get
  57.            Return MyBase.DoubleBuffered
  58.        End Get
  59.        Set(ByVal value As Boolean)
  60.            Me.SetStyle(ControlStyles.DoubleBuffer, value)
  61.            MyBase.DoubleBuffered = value
  62.        End Set
  63.    End Property
  64.  
  65.    ''' ----------------------------------------------------------------------------------------------------
  66.    ''' <summary>
  67.    ''' Gets or sets a value that indicates whether the control should avoid unwanted flickering effects.
  68.    ''' <para></para>
  69.    ''' If <see langword="True"/>, this will avoid any flickering effect on the control, however,
  70.    ''' it will also have a negative impact by slowing down the responsiveness of the control about to 30% slower.
  71.    ''' <para></para>
  72.    ''' This negative impact doesn't affect to the performance of the application itself,
  73.    ''' just to the performance of this control.
  74.    ''' </summary>
  75.    ''' ----------------------------------------------------------------------------------------------------
  76.    ''' <value>
  77.    ''' A value that indicates whether the control should avoid unwanted flickering effects.
  78.    ''' </value>
  79.    ''' ----------------------------------------------------------------------------------------------------
  80.    <Browsable(True)>
  81.    <EditorBrowsable(EditorBrowsableState.Always)>
  82.    <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
  83.    <Localizable(False)>
  84.    <Category("Behavior")>
  85.    <Description("Indicates whether the control should avoid unwanted flickering effects. If True, this will avoid any flickering effect on the control, however, it will also have a negative impact by slowing down the responsiveness of the control about to 30% slower.")>
  86.    <DefaultValue(GetType(Boolean), "False")>
  87.    Public Overridable Property PreventFlickering As Boolean Implements IBufferedControl.PreventFlickering
  88.        Get
  89.            Return Me.preventFlickeringB
  90.        End Get
  91.        Set(ByVal value As Boolean)
  92.            Me.preventFlickeringB = value
  93.        End Set
  94.    End Property
  95.    ''' ----------------------------------------------------------------------------------------------------
  96.    ''' <summary>
  97.    ''' ( Backing Field )
  98.    ''' A value that indicates whether the control should avoid unwanted flickering effects.
  99.    ''' </summary>
  100.    ''' ----------------------------------------------------------------------------------------------------
  101.    Private preventFlickeringB As Boolean
  102.  
  103.    Public Sub New()
  104.        MyBase.SuspendLayout()
  105.        ' MyBase.DoubleBuffered = True
  106.        ' Me.preventFlickeringB = True
  107.        MyBase.ResumeLayout(performLayout:=False)
  108.    End Sub
  109.  
  110. End Class



¿Cómo calcular la distancia (de 2 dimensiones) entre dos puntos?.

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Calculates the distance between two points in two dimensions in the coordinate system.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <remarks>
  7. ''' Pythagorean theorem: <see href="http://en.wikipedia.org/wiki/Pythagorean_theorem"/>
  8. ''' </remarks>
  9. ''' ----------------------------------------------------------------------------------------------------
  10. ''' <example> This is a code example.
  11. ''' <code>
  12. ''' Dim distance As Double = CalculateDistance2D(New PointF(1, 1), New PointF(2, 2))
  13. ''' </code>
  14. ''' </example>
  15. ''' ----------------------------------------------------------------------------------------------------
  16. ''' <param name="pointA">
  17. ''' The first point.
  18. ''' </param>
  19. '''
  20. ''' <param name="pointB">
  21. ''' The second point.
  22. ''' </param>
  23. ''' ----------------------------------------------------------------------------------------------------
  24. ''' <returns>
  25. ''' The resulting distance.
  26. ''' </returns>
  27. ''' ----------------------------------------------------------------------------------------------------
  28. Public Shared Function CalculateDistance2D(ByVal pointA As PointF, ByVal pointB As PointF) As Double
  29.  
  30.    ' Pythagoras theorem: c^2 = a^2 + b^2
  31.    ' thus c = square root(a^2 + b^2)
  32.    Dim a As Double = (pointB.X - pointA.X)
  33.    Dim b As Double = (pointB.Y - pointA.Y)
  34.  
  35.    Return Math.Sqrt(a * a + b * b)
  36.  
  37. End Function



¿Cómo subscribirnos a eventos del sistema?.

Microsoft Windows expone una infraestructura llamada WMI (Windows Management Instrumentation) mediante la que provee una serie de classes que podemos utilizar para subscribbirnos a eventos del sistema o dicho coloquiálmente "monitorizar eventos", como por ejemplo cambios de hardware, cambios de aplicaciones instaladas o desinstaladas, cambios en el nivel de batería de un portatil, cambios en el registro de Windows, y un largo etcétera.

La lista de classes podemos encontrarla en MSDN: https://msdn.microsoft.com/en-us/library/aa394554(v=vs.85).aspx

Hay varios tipos de classes, un tipo de classes serían representativas, es decir para representar información de consultas realizadas a WMI, y otro tipo serían las classes de eventos. Una class de evento la utilizariamos para subscribirnos al tipo de evento que provee.

Para subscribirnos a una clase de evento, la librería de clases de .NET Framework espone la clase ManagementEventWatcher. Yo he desarrollado la siguiente class que hereda de la class ManagementEventWatcher, con la intención de añadir algunos constructores específicos para facilitar todavía más su uso y abstraer en mayor medida el nivel de complejidad.

Código
  1. ' ***********************************************************************
  2. ' Author   : Elektro
  3. ' Modified : 21-March-2017
  4. ' ***********************************************************************
  5.  
  6. #Region " Public Members Summary "
  7.  
  8. #Region " Constructors "
  9.  
  10. ' New(String)
  11. ' New(String, Single)
  12. ' New(String, Timespan)
  13. ' New(String, String, Single)
  14. ' New(String, String, Timespan)
  15. ' New(String, String, String(), UInteger)
  16. ' New(String, String, String(), Timespan)
  17.  
  18. ' New(SelectQuery)
  19. ' New(SelectQuery, Single)
  20. ' New(SelectQuery, Timespan)
  21. ' New(SelectQuery, UInteger)
  22.  
  23. #End Region
  24.  
  25. #Region " Events "
  26.  
  27. ' EventArrived As EventArrivedEventHandler
  28.  
  29. #End Region
  30.  
  31. #Region " Methods "
  32.  
  33. ' Start()
  34. ' Stop()
  35. ' Dispose()
  36.  
  37. #End Region
  38.  
  39. #End Region
  40.  
  41. #Region " Option Statements "
  42.  
  43. Option Strict On
  44. Option Explicit On
  45. Option Infer Off
  46.  
  47. #End Region
  48.  
  49. #Region " Imports "
  50.  
  51. Imports System.ComponentModel
  52. Imports System.Management
  53.  
  54. #End Region
  55.  
  56. #Region " WMI Event Watcher "
  57.  
  58.    ''' ----------------------------------------------------------------------------------------------------
  59.    ''' <summary>
  60.    ''' A WMI event monitor that notifies about event arrivals for the subscribed event class.
  61.    ''' </summary>
  62.    ''' ----------------------------------------------------------------------------------------------------
  63.    <DesignerCategory("code")>
  64.    <ImmutableObject(False)>
  65.    Public Class WMIEventWatcher : Inherits ManagementEventWatcher
  66.  
  67. #Region " Constructors "
  68.  
  69.        ''' ----------------------------------------------------------------------------------------------------
  70.        ''' <summary>
  71.        ''' Prevents a default instance of the <see cref="WMIEventWatcher"/> class from being created.
  72.        ''' </summary>
  73.        ''' ----------------------------------------------------------------------------------------------------
  74.        <DebuggerNonUserCode>
  75.        Private Sub New()
  76.        End Sub
  77.  
  78.        ''' ----------------------------------------------------------------------------------------------------
  79.        ''' <summary>
  80.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  81.        ''' </summary>
  82.        ''' ----------------------------------------------------------------------------------------------------
  83.        ''' <param name="eventClassName">
  84.        ''' The name of the WMI event class to subscribe for.
  85.        ''' </param>
  86.        ''' ----------------------------------------------------------------------------------------------------
  87.        <DebuggerStepThrough>
  88.        Public Sub New(ByVal eventClassName As String)
  89.  
  90.            Me.New(eventClassName, condition:=String.Empty, withinInterval:=1.0F)
  91.  
  92.        End Sub
  93.  
  94.        ''' ----------------------------------------------------------------------------------------------------
  95.        ''' <summary>
  96.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  97.        ''' </summary>
  98.        ''' ----------------------------------------------------------------------------------------------------
  99.        ''' <param name="eventClassName">
  100.        ''' The name of the WMI event class to subscribe for.
  101.        ''' </param>
  102.        '''
  103.        ''' <param name="withinInterval">
  104.        ''' The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
  105.        ''' specified class in the <paramref name="eventClassName"/> parameter.
  106.        ''' </param>
  107.        ''' ----------------------------------------------------------------------------------------------------
  108.        <DebuggerStepThrough>
  109.        Public Sub New(ByVal eventClassName As String,
  110.                       ByVal withinInterval As Single)
  111.  
  112.            Me.New(eventClassName, condition:=String.Empty, withinInterval:=withinInterval)
  113.  
  114.        End Sub
  115.  
  116.        ''' ----------------------------------------------------------------------------------------------------
  117.        ''' <summary>
  118.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  119.        ''' </summary>
  120.        ''' ----------------------------------------------------------------------------------------------------
  121.        ''' <param name="eventClassName">
  122.        ''' The name of the WMI event class to subscribe for.
  123.        ''' </param>
  124.        '''
  125.        ''' <param name="withinInterval">
  126.        ''' The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
  127.        ''' specified class in the <paramref name="eventClassName"/> parameter.
  128.        ''' </param>
  129.        ''' ----------------------------------------------------------------------------------------------------
  130.        <DebuggerStepThrough>
  131.        Public Sub New(ByVal eventClassName As String,
  132.                       ByVal withinInterval As TimeSpan)
  133.  
  134.            Me.New(eventClassName, condition:=String.Empty, withinInterval:=withinInterval)
  135.  
  136.        End Sub
  137.  
  138.        ''' ----------------------------------------------------------------------------------------------------
  139.        ''' <summary>
  140.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  141.        ''' </summary>
  142.        ''' ----------------------------------------------------------------------------------------------------
  143.        ''' <param name="eventClassName">
  144.        ''' The name of the WMI event class to subscribe for.
  145.        ''' </param>
  146.        '''
  147.        ''' <param name="condition">
  148.        ''' The condition to be applied to events of the specified class in the
  149.        ''' <paramref name="eventClassName"/> parameter.
  150.        ''' </param>
  151.        '''
  152.        ''' <param name="withinInterval">
  153.        ''' The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
  154.        ''' specified class in the <paramref name="eventClassName"/> parameter.
  155.        ''' </param>
  156.        ''' ----------------------------------------------------------------------------------------------------
  157.        <DebuggerStepThrough>
  158.        Public Sub New(ByVal eventClassName As String,
  159.                       ByVal condition As String,
  160.                       ByVal withinInterval As Single)
  161.  
  162.            Me.New(eventClassName, condition, TimeSpan.FromSeconds(withinInterval))
  163.  
  164.        End Sub
  165.  
  166.        ''' ----------------------------------------------------------------------------------------------------
  167.        ''' <summary>
  168.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  169.        ''' </summary>
  170.        ''' ----------------------------------------------------------------------------------------------------
  171.        ''' <param name="eventClassName">
  172.        ''' The name of the WMI event class to subscribe for.
  173.        ''' </param>
  174.        '''
  175.        ''' <param name="condition">
  176.        ''' The condition to be applied to events of the specified class in the
  177.        ''' <paramref name="eventClassName"/> parameter.
  178.        ''' </param>
  179.        '''
  180.        ''' <param name="withinInterval">
  181.        ''' The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
  182.        ''' specified class in the <paramref name="eventClassName"/> parameter.
  183.        ''' </param>
  184.        ''' ----------------------------------------------------------------------------------------------------
  185.        <DebuggerStepThrough>
  186.        Public Sub New(ByVal eventClassName As String,
  187.                       ByVal condition As String,
  188.                       ByVal withinInterval As TimeSpan)
  189.  
  190.            MyBase.Query = New WqlEventQuery(eventClassName:=eventClassName,
  191.                                             condition:=condition,
  192.                                             withinInterval:=withinInterval)
  193.  
  194.        End Sub
  195.  
  196.        ''' ----------------------------------------------------------------------------------------------------
  197.        ''' <summary>
  198.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  199.        ''' </summary>
  200.        ''' ----------------------------------------------------------------------------------------------------
  201.        ''' <param name="eventClassName">
  202.        ''' The name of the WMI event class to subscribe for.
  203.        ''' </param>
  204.        '''
  205.        ''' <param name="condition">
  206.        ''' The condition to be applied to events of the specified class in the
  207.        ''' <paramref name="eventClassName"/> parameter.
  208.        ''' </param>
  209.        '''
  210.        ''' <param name="groupByPropertyList">
  211.        ''' The properties in the event class by which the events should be grouped.
  212.        ''' </param>
  213.        '''
  214.        ''' <param name="groupWithinInterval">
  215.        ''' The interval, in seconds, of the specified interval at which WMI sends one aggregate event,
  216.        ''' rather than many events.
  217.        ''' </param>
  218.        ''' ----------------------------------------------------------------------------------------------------
  219.        <DebuggerStepThrough>
  220.        Public Sub New(ByVal eventClassName As String,
  221.                       ByVal condition As String,
  222.                       ByVal groupByPropertyList As String(),
  223.                       ByVal groupWithinInterval As UInteger)
  224.  
  225.            Me.New(eventClassName, condition, groupByPropertyList, TimeSpan.FromSeconds(groupWithinInterval))
  226.  
  227.        End Sub
  228.  
  229.        ''' ----------------------------------------------------------------------------------------------------
  230.        ''' <summary>
  231.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  232.        ''' </summary>
  233.        ''' ----------------------------------------------------------------------------------------------------
  234.        ''' <param name="eventClassName">
  235.        ''' The name of the WMI event class to subscribe for.
  236.        ''' </param>
  237.        '''
  238.        ''' <param name="condition">
  239.        ''' The condition to be applied to events of the specified class in the
  240.        ''' <paramref name="eventClassName"/> parameter.
  241.        ''' </param>
  242.        '''
  243.        ''' <param name="groupByPropertyList">
  244.        ''' The properties in the event class by which the events should be grouped.
  245.        ''' </param>
  246.        '''
  247.        ''' <param name="groupWithinInterval">
  248.        ''' The interval, in seconds, of the specified interval at which WMI sends one aggregate event,
  249.        ''' rather than many events.
  250.        ''' </param>
  251.        ''' ----------------------------------------------------------------------------------------------------
  252.        <DebuggerStepThrough>
  253.        Public Sub New(ByVal eventClassName As String,
  254.                       ByVal condition As String,
  255.                       ByVal groupByPropertyList As String(),
  256.                       ByVal groupWithinInterval As TimeSpan)
  257.  
  258.            MyBase.Query = New WqlEventQuery(eventClassName:=eventClassName,
  259.                                             condition:=condition,
  260.                                             groupWithinInterval:=groupWithinInterval,
  261.                                             groupByPropertyList:=groupByPropertyList)
  262.  
  263.        End Sub
  264.  
  265.        ''' ----------------------------------------------------------------------------------------------------
  266.        ''' <summary>
  267.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  268.        ''' </summary>
  269.        ''' ----------------------------------------------------------------------------------------------------
  270.        ''' <param name="query">
  271.        ''' The WMI select query of the event class to subscribe for.
  272.        ''' </param>
  273.        ''' ----------------------------------------------------------------------------------------------------
  274.        <DebuggerStepThrough>
  275.        Public Sub New(ByVal query As SelectQuery)
  276.  
  277.            Me.New(query.ClassName, condition:=query.Condition, withinInterval:=1.0F)
  278.  
  279.        End Sub
  280.  
  281.        ''' ----------------------------------------------------------------------------------------------------
  282.        ''' <summary>
  283.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  284.        ''' </summary>
  285.        ''' ----------------------------------------------------------------------------------------------------
  286.        ''' <param name="query">
  287.        ''' The WMI select query of the event class to subscribe for.
  288.        ''' </param>
  289.        '''
  290.        ''' <param name="withinInterval">
  291.        ''' The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
  292.        ''' specified class in the <paramref name="query"/> parameter.
  293.        ''' </param>
  294.        ''' ----------------------------------------------------------------------------------------------------
  295.        <DebuggerStepThrough>
  296.        Public Sub New(ByVal query As SelectQuery,
  297.                       ByVal withinInterval As Single)
  298.  
  299.            Me.New(query.ClassName, condition:=query.Condition, withinInterval:=TimeSpan.FromSeconds(withinInterval))
  300.  
  301.        End Sub
  302.  
  303.        ''' ----------------------------------------------------------------------------------------------------
  304.        ''' <summary>
  305.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  306.        ''' </summary>
  307.        ''' ----------------------------------------------------------------------------------------------------
  308.        ''' <param name="query">
  309.        ''' The WMI select query of the event class to subscribe for.
  310.        ''' </param>
  311.        '''
  312.        ''' <param name="withinInterval">
  313.        ''' The interval, in seconds, that WMI will check for changes that occur to instances of the events of the
  314.        ''' specified class in the <paramref name="query"/> parameter.
  315.        ''' </param>
  316.        ''' ----------------------------------------------------------------------------------------------------
  317.        <DebuggerStepThrough>
  318.        Public Sub New(ByVal query As SelectQuery,
  319.                       ByVal withinInterval As TimeSpan)
  320.  
  321.            Me.New(query.ClassName, condition:=query.Condition, withinInterval:=withinInterval)
  322.  
  323.        End Sub
  324.  
  325.        ''' ----------------------------------------------------------------------------------------------------
  326.        ''' <summary>
  327.        ''' Initializes a new instance of the <see cref="WMIEventWatcher"/> class.
  328.        ''' </summary>
  329.        ''' ----------------------------------------------------------------------------------------------------
  330.        ''' <param name="query">
  331.        ''' The WMI select query of the event class to subscribe for and its selected properties.
  332.        ''' </param>
  333.        '''
  334.        ''' <param name="groupWithinInterval">
  335.        ''' The interval, in seconds, of the specified interval at which WMI sends one aggregate event,
  336.        ''' rather than many events.
  337.        ''' </param>
  338.        ''' ----------------------------------------------------------------------------------------------------
  339.        <DebuggerStepThrough>
  340.        Public Sub New(ByVal query As SelectQuery,
  341.                       ByVal groupWithinInterval As UInteger)
  342.  
  343.            Dim strArray As String() = New String(query.SelectedProperties.Count - 1) {}
  344.            query.SelectedProperties.CopyTo(strArray, 0)
  345.  
  346.            MyBase.Query = New WqlEventQuery(eventClassName:=query.ClassName,
  347.                                             condition:=query.Condition,
  348.                                             groupWithinInterval:=TimeSpan.FromSeconds(groupWithinInterval),
  349.                                             groupByPropertyList:=strArray)
  350.  
  351.        End Sub
  352.  
  353. #End Region
  354.  
  355.    End Class
  356.  
  357. #End Region

Ejemplo de uso para subscribirnos a la class Win32_VolumeChangeEvent, la cual nos informa de cambios de volumen, del montaje y desmontaje de particiones del sistema:

Código
  1. Public NotInheritable Class Form1 : Inherits Form
  2.  
  3.    Private WithEvents eventWatcher As New WMIEventWatcher("Win32_VolumeChangeEvent", withinInterval:=0.5F)
  4.  
  5.    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
  6.        Me.eventWatcher.Scope = New ManagementScope("root\CIMV2", New ConnectionOptions() With {.EnablePrivileges = True})
  7.        Me.eventWatcher.Start()
  8.    End Sub
  9.  
  10.    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing
  11.        Me.eventWatcher.Dispose()
  12.    End Sub
  13.  
  14.    Private Sub EventWatcher_EventArrived(ByVal sender As Object, ByVal e As EventArrivedEventArgs) _
  15.    Handles eventWatcher.EventArrived
  16.        Dim driveName As String = CStr(e.NewEvent.Properties("DriveName").Value)
  17.        Dim eventType As Integer = CInt(e.NewEvent.Properties("EventType").Value)
  18.  
  19.        Console.WriteLine(String.Format("Drive Name: {0}", driveName))
  20.        Console.WriteLine(String.Format("Event Type: {0}", eventType))
  21.    End Sub
  22.  
  23. End Class

Ejemplo de uso para subscribirnos a la class Win32_LogicalDisk, mediante la cual con el uso de una condición en la consulta de WMI, nos reportará cambios de inserción y eyección en dispositivos de CD-ROM:

Código
  1. Public Class Form1 : Inherits Form
  2.  
  3.    Private WithEvents eventWatcher As New WMIEventWatcher(
  4.        "__InstanceModificationEvent",
  5.        condition:="TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.DriveType = 5",
  6.        withinInterval:=0.5F
  7.    )
  8.  
  9.    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
  10.        Me.eventWatcher.Scope = New ManagementScope("root\CIMV2", New ConnectionOptions() With {.EnablePrivileges = True})
  11.        Me.eventWatcher.Start()
  12.    End Sub
  13.  
  14.    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing
  15.        Me.eventWatcher.Dispose()
  16.    End Sub
  17.  
  18.    Private Sub EventWatcher_EventArrived(ByVal sender As Object, ByVal e As EventArrivedEventArgs) Handles eventWatcher.EventArrived
  19.  
  20.        Using mo As ManagementBaseObject = DirectCast(pd.Value, ManagementBaseObject)
  21.  
  22.            Dim name As String = Convert.ToString(mo.Properties("Name").Value)
  23.            string label = Convert.ToString(mo.Properties("VolumeName").Value);
  24.  
  25.            Dim di As DriveInfo = (From item In DriveInfo.GetDrives()
  26.                                   Where String.IsNullOrEmpty(item.Name)
  27.                                  ).Single()
  28.  
  29.            If Not String.IsNullOrEmpty(di.VolumeLabel) Then
  30.  
  31.                Console.WriteLine(String.Format("CD has been inserted in drive {0}.", di.Name))
  32.            Else
  33.  
  34.                Console.WriteLine(String.Format("CD has been ejected from drive {0}.", di.Name))
  35.  
  36.            End If
  37.  
  38.        End Using
  39.  
  40.    End Sub
  41.  
  42. End Class
Nota: No he podido testear el ejemplo del dispositivo CD-ROM.



Todas estas funcionalidades y muchísimas más las podrán encontrar en mi Framework de pago ElektroKit.
« Última modificación: 1 Abril 2017, 18:07 por Eleкtro » En línea


Eleкtro
Novato Astral y
Moderador Global
***
Conectado Conectado

Mensajes: 8.848


El sentido común es el menos común de los sentidos


Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #503 en: 2 Abril 2017, 22:36 »

¿Cómo manipular imágenes GIF animadas?

La librería de clases de .NET Framework no expone ningún tipo para representar de forma específica una imagen GIF. Tenemos el tipo Bitmap, Icon, e Image para representar de forma global cualquier tipo de imagen (incluyendo un GIF). Pero... ¿y si queremos representar de forma específica una imagen GIF con todos sus frames?, pues esta clase que he desarrollado sería un buen comienzo para llevarlo a cabo:

Código
  1. ' ***********************************************************************
  2. ' Author   : Elektro
  3. ' Modified : 02-April-2017
  4. ' ***********************************************************************
  5.  
  6. #Region " Public Members Summary "
  7.  
  8. #Region " Constructors "
  9.  
  10. ' New(String)
  11. ' New(FileInfo)
  12. ' New(Image)
  13.  
  14. #End Region
  15.  
  16. #Region " Properties "
  17.  
  18. ' Image As Image
  19. ' FrameCount As Integer
  20. ' Frames(Integer) As Bitmap
  21. ' ActiveFrame As Bitmap
  22. ' ActiveFrameIndex As Integer
  23. ' EndOfFrames As Boolean
  24.  
  25. #End Region
  26.  
  27. #Region " Functions "
  28.  
  29. ' NextFrame() As Bitmap
  30. ' GetFrames() As List(Of Bitmap)
  31.  
  32. #End Region
  33.  
  34. #End Region
  35.  
  36. #Region " Option Statements "
  37.  
  38. Option Strict On
  39. Option Explicit On
  40. Option Infer Off
  41.  
  42. #End Region
  43.  
  44. #Region " Imports "
  45.  
  46. Imports System.Drawing
  47. Imports System.Drawing.Imaging
  48. Imports System.IO
  49.  
  50. #End Region
  51.  
  52. #Region " GIF "
  53.  
  54.    ''' ----------------------------------------------------------------------------------------------------
  55.    ''' <summary>
  56.    ''' Represents a GIF image.
  57.    ''' </summary>
  58.    ''' ----------------------------------------------------------------------------------------------------
  59.    Public Class GIF
  60.  
  61. #Region " Properties "
  62.  
  63.        ''' ----------------------------------------------------------------------------------------------------
  64.        ''' <summary>
  65.        ''' Gets the GIF image.
  66.        ''' </summary>
  67.        ''' ----------------------------------------------------------------------------------------------------
  68.        ''' <value>
  69.        ''' The GIF image.
  70.        ''' </value>
  71.        ''' ----------------------------------------------------------------------------------------------------
  72.        Public ReadOnly Property Image As Image
  73.  
  74.        ''' ----------------------------------------------------------------------------------------------------
  75.        ''' <summary>
  76.        ''' Gets the frame count of the GIF image.
  77.        ''' </summary>
  78.        ''' ----------------------------------------------------------------------------------------------------
  79.        ''' <value>
  80.        ''' The frame count of the GIF image.
  81.        ''' </value>
  82.        ''' ----------------------------------------------------------------------------------------------------
  83.        Public ReadOnly Property FrameCount As Integer
  84.  
  85.        ''' ----------------------------------------------------------------------------------------------------
  86.        ''' <summary>
  87.        ''' Gets the frame at the specified index.
  88.        ''' </summary>
  89.        ''' ----------------------------------------------------------------------------------------------------
  90.        ''' <value>
  91.        ''' The frame index.
  92.        ''' </value>
  93.        ''' ----------------------------------------------------------------------------------------------------
  94.        Default Public Overridable ReadOnly Property Frames(ByVal index As Integer) As Bitmap
  95.            <DebuggerStepperBoundary>
  96.            Get
  97.                Using img As Image = DirectCast(Me.Image.Clone(), Image)
  98.                    img.SelectActiveFrame(FrameDimension.Time, index)
  99.                    Return New Bitmap(img) ' Deep copy of the frame (only the frame).
  100.                End Using
  101.            End Get
  102.        End Property
  103.  
  104.        ''' ----------------------------------------------------------------------------------------------------
  105.        ''' <summary>
  106.        ''' Gets the active frame.
  107.        ''' </summary>
  108.        ''' ----------------------------------------------------------------------------------------------------
  109.        ''' <value>
  110.        ''' The active frame.
  111.        ''' </value>
  112.        ''' ----------------------------------------------------------------------------------------------------
  113.        Public Overridable ReadOnly Property ActiveFrame As Bitmap
  114.            <DebuggerStepperBoundary>
  115.            Get
  116.                Return New Bitmap(Me.Image) ' Deep copy of the frame (only the frame).
  117.            End Get
  118.        End Property
  119.  
  120.        ''' ----------------------------------------------------------------------------------------------------
  121.        ''' <summary>
  122.        ''' Gets the index in the frame count of the current active frame.
  123.        ''' </summary>
  124.        ''' ----------------------------------------------------------------------------------------------------
  125.        ''' <value>
  126.        ''' The index in the frame count of the current active frame.
  127.        ''' </value>
  128.        ''' ----------------------------------------------------------------------------------------------------
  129.        Public Property ActiveFrameIndex As Integer
  130.            <DebuggerStepThrough>
  131.            Get
  132.                Return Me.activeFrameIndexB
  133.            End Get
  134.            <DebuggerStepperBoundary>
  135.            Set(ByVal value As Integer)
  136.                If (value <> Me.activeFrameIndexB) Then
  137.                    Me.Image.SelectActiveFrame(FrameDimension.Time, value)
  138.                    Me.activeFrameIndexB = value
  139.                    Me.eof = (value = Me.FrameCount)
  140.                End If
  141.            End Set
  142.        End Property
  143.        ''' ----------------------------------------------------------------------------------------------------
  144.        ''' <summary>
  145.        ''' ( Backing Field )
  146.        ''' The index in the frame count of the current active frame.
  147.        ''' </summary>
  148.        ''' ----------------------------------------------------------------------------------------------------
  149.        Private activeFrameIndexB As Integer
  150.  
  151.        ''' ----------------------------------------------------------------------------------------------------
  152.        ''' <summary>
  153.        ''' Gets a value indicating whether the frame count is at EOF,
  154.        ''' this means there is no more frames to advance in the GIF image.
  155.        ''' </summary>
  156.        ''' ----------------------------------------------------------------------------------------------------
  157.        ''' <value>
  158.        ''' <see langword="True"/> if there is no more frames to advance in the GIF image; otherwise, <see langword="False"/>.
  159.        ''' </value>
  160.        ''' ----------------------------------------------------------------------------------------------------
  161.        Public ReadOnly Property EndOfFrames As Boolean
  162.            <DebuggerStepThrough>
  163.            Get
  164.                Return Me.eof
  165.            End Get
  166.        End Property
  167.        ''' ----------------------------------------------------------------------------------------------------
  168.        ''' <summary>
  169.        ''' ( Backing Field )
  170.        ''' A value indicating whether the frame count is at EOF,
  171.        ''' this means there is no more frames to advance in the GIF image.
  172.        ''' </summary>
  173.        ''' ----------------------------------------------------------------------------------------------------
  174.        Private eof As Boolean
  175.  
  176. #End Region
  177.  
  178. #Region " Constructors "
  179.  
  180.        ''' ----------------------------------------------------------------------------------------------------
  181.        ''' <summary>
  182.        ''' Prevents a default instance of the <see cref="GIF"/> class from being created.
  183.        ''' </summary>
  184.        ''' ----------------------------------------------------------------------------------------------------
  185.        <DebuggerNonUserCode>
  186.        Private Sub New()
  187.        End Sub
  188.  
  189.        ''' ----------------------------------------------------------------------------------------------------
  190.        ''' <summary>
  191.        ''' Initializes a new instance of the <see cref="GIF"/> class.
  192.        ''' </summary>
  193.        ''' ----------------------------------------------------------------------------------------------------
  194.        ''' <param name="filepath">
  195.        ''' The filepath.
  196.        ''' </param>
  197.        ''' ----------------------------------------------------------------------------------------------------
  198.        <DebuggerStepThrough>
  199.        Public Sub New(ByVal filepath As String)
  200.  
  201.            Me.New(Image.FromFile(filepath))
  202.  
  203.        End Sub
  204.  
  205.        ''' ----------------------------------------------------------------------------------------------------
  206.        ''' <summary>
  207.        ''' Initializes a new instance of the <see cref="GIF"/> class.
  208.        ''' </summary>
  209.        ''' ----------------------------------------------------------------------------------------------------
  210.        ''' <param name="file">
  211.        ''' The image file.
  212.        ''' </param>
  213.        ''' ----------------------------------------------------------------------------------------------------
  214.        <DebuggerStepThrough>
  215.        Public Sub New(ByVal file As FileInfo)
  216.  
  217.            Me.New(Image.FromFile(file.FullName))
  218.  
  219.        End Sub
  220.  
  221.        ''' ----------------------------------------------------------------------------------------------------
  222.        ''' <summary>
  223.        ''' Initializes a new instance of the <see cref="GIF"/> class.
  224.        ''' </summary>
  225.        ''' ----------------------------------------------------------------------------------------------------
  226.        ''' <param name="img">
  227.        ''' The image.
  228.        ''' </param>
  229.        ''' ----------------------------------------------------------------------------------------------------
  230.        <DebuggerStepThrough>
  231.        Public Sub New(ByVal img As Image)
  232.  
  233.            Me.Image = img
  234.            Me.FrameCount = Me.Image.GetFrameCount(FrameDimension.Time)
  235.  
  236.        End Sub
  237.  
  238. #End Region
  239.  
  240. #Region " Public Methods "
  241.  
  242.        ''' ----------------------------------------------------------------------------------------------------
  243.        ''' <summary>
  244.        ''' Advances one position in the frame count and returns the next frame.
  245.        ''' </summary>
  246.        ''' ----------------------------------------------------------------------------------------------------
  247.        ''' <returns>
  248.        ''' The next frame.
  249.        ''' </returns>
  250.        ''' ----------------------------------------------------------------------------------------------------
  251.        <DebuggerStepThrough>
  252.        Public Overridable Function NextFrame() As Bitmap
  253.  
  254.            If (Me.eof) Then
  255.                Throw New IndexOutOfRangeException()
  256.  
  257.            Else
  258.                Dim frame As Bitmap = Me.Frames(Me.activeFrameIndexB)
  259.                Me.activeFrameIndexB += 1
  260.                Me.eof = (Me.activeFrameIndexB >= Me.FrameCount)
  261.                Return frame
  262.  
  263.            End If
  264.  
  265.        End Function
  266.  
  267.        ''' ----------------------------------------------------------------------------------------------------
  268.        ''' <summary>
  269.        ''' Gets a <see cref="List(Of Bitmap)"/> containing all the frames in the image.
  270.        ''' </summary>
  271.        ''' ----------------------------------------------------------------------------------------------------
  272.        ''' <returns>
  273.        ''' A <see cref="List(Of Bitmap)"/> containing all the frames in the image.
  274.        ''' </returns>
  275.        ''' ----------------------------------------------------------------------------------------------------
  276.        <DebuggerStepThrough>
  277.        Public Overridable Function GetFrames() As List(Of Bitmap)
  278.  
  279.            Using img As Image = DirectCast(Me.Image.Clone(), Image)
  280.                Return GetFramesFromImage(img)
  281.            End Using
  282.  
  283.        End Function
  284.  
  285. #End Region
  286.  
  287. #Region " Private Methods "
  288.  
  289.        ''' ----------------------------------------------------------------------------------------------------
  290.        ''' <summary>
  291.        ''' Gets a <see cref="List(Of Bitmap)"/> containing all the frames in the source GIF image.
  292.        ''' </summary>
  293.        ''' ----------------------------------------------------------------------------------------------------
  294.        ''' <param name="img">
  295.        ''' The source <see cref="Image"/>.
  296.        ''' </param>
  297.        ''' ----------------------------------------------------------------------------------------------------
  298.        ''' <returns>
  299.        ''' The resulting percentage difference value between the two specified images.
  300.        ''' </returns>
  301.        ''' ----------------------------------------------------------------------------------------------------
  302.        Private Shared Function GetFramesFromImage(ByVal img As Image) As List(Of Bitmap)
  303.  
  304.            Dim imgs As New List(Of Bitmap)
  305.            Dim frameCount As Integer = img.GetFrameCount(FrameDimension.Time)
  306.  
  307.            For i As Integer = 0 To (frameCount - 1)
  308.                img.SelectActiveFrame(FrameDimension.Time, i)
  309.                imgs.Add(New Bitmap(img)) ' Deep copy of the frame (only the frame).
  310.            Next
  311.  
  312.            Return imgs
  313.  
  314.        End Function
  315.  
  316. #End Region
  317.  
  318.    End Class
  319.  
  320. #End Region
  321.  

Ejemplos de uso:
Código
  1. Dim pcb As PictureBox = Me.PictureBox1
  2. Dim gif As New GIF("C:\File.gif")
  3.  
  4. Do Until gif.EndOfFrames ' Iterate frames until the end of frame count.
  5.  
  6.    ' Free previous Bitmap object.
  7.    If (pcb.Image IsNot Nothing) Then
  8.        pcb.Image.Dispose()
  9.        pcb.Image = Nothing
  10.    End If
  11.  
  12.    pcb.Image = gif.NextFrame()
  13.    Thread.Sleep(60) ' Simulate a FPS thingy.
  14.    Application.DoEvents()
  15.  
  16.    If (gif.EndOfFrames) Then
  17.        ' Set active frame to 0 for infinite loop:
  18.        gif.ActiveFrameIndex = 0
  19.    End If
  20.  
  21. Loop

Nótese que el método GIF.GetFrames() devuelve una colección de Bitmaps con todos los frames de la imagen GIF. Las posibilidades son infinitas con esta colección, podemos añadir, editar o eliminar frames para crear un nuevo GIF, o simplemente mostrar la secuencia de frames...

¡Saludos!
« Última modificación: 2 Abril 2017, 22:40 por Eleкtro » En línea


Eleкtro
Novato Astral y
Moderador Global
***
Conectado Conectado

Mensajes: 8.848


El sentido común es el menos común de los sentidos


Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #504 en: 7 Abril 2017, 06:16 »

Determinar si dos colores son similares

Código
  1.    ''' ----------------------------------------------------------------------------------------------------
  2.    ''' <summary>
  3.    ''' Determines whether two colors are similar.
  4.    ''' <para></para>
  5.    ''' It compares the RGB channel differences to match inside the range of the specified tolerance values.
  6.    ''' </summary>
  7.    ''' ----------------------------------------------------------------------------------------------------
  8.    ''' <param name="color1">
  9.    ''' The first color to compare.
  10.    ''' </param>
  11.    '''
  12.    ''' <param name="color2">
  13.    ''' The second color to compare.
  14.    ''' </param>
  15.    '''
  16.    ''' <param name="toleranceR">
  17.    ''' The tolerance of the Red color channel.
  18.    ''' From 0 to 255.
  19.    ''' </param>
  20.    '''
  21.    ''' <param name="toleranceG">
  22.    ''' The tolerance of the Green color channel.
  23.    ''' From 0 to 255.
  24.    ''' </param>
  25.    '''
  26.    ''' <param name="toleranceB">
  27.    ''' The tolerance of the Blue color channel.
  28.    ''' From 0 to 255.
  29.    ''' </param>
  30.    ''' ----------------------------------------------------------------------------------------------------
  31.    ''' <returns>
  32.    ''' <see langword="True"/> if the colors are similar,
  33.    ''' this means the RGB differences matches inside the range of the specified tolerance value,
  34.    ''' <see langword="False"/> otherwise.
  35.    ''' </returns>
  36.    ''' ----------------------------------------------------------------------------------------------------
  37.    Public Shared Function IsColorSimilar(ByVal color1 As Color, ByVal color2 As Color,
  38.                                          ByVal toleranceR As Byte, ByVal toleranceG As Byte, ByVal toleranceB As Byte) As Boolean
  39.  
  40.        Return Math.Abs(CInt(color1.R) - color2.R) <= toleranceR AndAlso
  41.               Math.Abs(CInt(color1.G) - color2.G) <= toleranceG AndAlso
  42.               Math.Abs(CInt(color1.B) - color2.B) <= toleranceB
  43.  
  44.    End Function

Modo de empleo:
Código
  1. Dim areSimilar As Boolean = IsColorSimilar(Color.FromArgb(0, 0, 0), Color.FromArgb(0, 0, 1),
  2.                                           toleranceR:=0, toleranceG:=0, toleranceB:=1)
  3. ' Result: True

Código
  1.    ''' ----------------------------------------------------------------------------------------------------
  2.    ''' <summary>
  3.    ''' Determines whether two colors are similar.
  4.    ''' <para></para>
  5.    ''' It compares the RGB channel difference to match inside the range of the specified tolerance value.
  6.    ''' </summary>
  7.    ''' ----------------------------------------------------------------------------------------------------
  8.    ''' <param name="color1">
  9.    ''' The first color to compare.
  10.    ''' </param>
  11.    '''
  12.    ''' <param name="color2">
  13.    ''' The second color to compare.
  14.    ''' </param>
  15.    '''
  16.    ''' <param name="tolerance">
  17.    ''' The global tolerance of the RGB color channels.
  18.    ''' From 0 to 255.
  19.    ''' </param>
  20.    ''' ----------------------------------------------------------------------------------------------------
  21.    ''' <returns>
  22.    ''' <see langword="True"/> if the colors are similar,
  23.    ''' this means the RGB differences matches inside the range of the specified tolerance value,
  24.    ''' <see langword="False"/> otherwise.
  25.    ''' </returns>
  26.    ''' ----------------------------------------------------------------------------------------------------
  27.    Public Shared Function IsColorSimilar(ByVal color1 As Color, ByVal color2 As Color, ByVal tolerance As Byte) As Boolean
  28.  
  29.        Return (Math.Abs(CInt(color1.R) - color2.R) +
  30.                Math.Abs(CInt(color1.G) - color2.G) +
  31.                Math.Abs(CInt(color1.B) - color2.B)) <= tolerance
  32.  
  33.    End Function

Modo de empleo :

Código
  1. Dim result1 As Boolean = IsColorSimilar(Color.FromArgb(0, 0, 0), Color.FromArgb(0, 0, 1), tolerance:=1)
  2. ' Result: True
  3. '  Logic: Blue channel difference = 1, which is equal than the specified tolerance value.
  4.  
  5. Dim result2 As Boolean = IsColorSimilar(Color.FromArgb(0, 0, 0), Color.FromArgb(0, 1, 1), tolerance:=1)
  6. ' Result: False
  7. '  Logic: Red channel + Blue channel differences = 2, which is a bigger value than the specified tolerance value.



Voltear una imagen

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Specifies a flip type operation to perform for an image.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. Public Enum FlipType As Integer
  7.  
  8.    ''' <summary>
  9.    ''' Horizontal flip.
  10.    ''' </summary>
  11.    Horizontal = 1
  12.  
  13.    ''' <summary>
  14.    ''' Vertical flip.
  15.    ''' </summary>
  16.    Vertical = 2
  17.  
  18.    ''' <summary>
  19.    ''' Both a horizontal and vertical flip.
  20.    ''' </summary>
  21.    Both = 3
  22.  
  23. End Enum
  24.  
  25. public module ImageExtensions
  26.  
  27. ''' ----------------------------------------------------------------------------------------------------
  28. ''' <summary>
  29. ''' Flips an <see cref="Image"/>.
  30. ''' </summary>
  31. ''' ----------------------------------------------------------------------------------------------------
  32. ''' <param name="sender">
  33. ''' The source <see cref="Image"/>.
  34. ''' </param>
  35. '''
  36. ''' <param name="fliptype">
  37. ''' The flip type operation to perform.
  38. ''' </param>
  39. ''' ----------------------------------------------------------------------------------------------------
  40. ''' <returns>
  41. ''' The resulting <see cref="Image"/>.
  42. ''' </returns>
  43. ''' ----------------------------------------------------------------------------------------------------
  44. <Extension>
  45. <DebuggerStepThrough>
  46. <EditorBrowsable(EditorBrowsableState.Always)>
  47. Public Function Flip(ByVal sender As Image, ByVal fliptype As FlipType) As Image
  48.  
  49.    Dim flippedImage As New Bitmap(sender.Width, sender.Height, sender.PixelFormat)
  50.  
  51.    Using g As Graphics = Graphics.FromImage(flippedImage)
  52.  
  53.        Dim m As Matrix = Nothing
  54.        Select Case fliptype
  55.            Case FlipType.Horizontal
  56.                m = New Matrix(-1, 0, 0, 1, 0, 0)
  57.                m.Translate(flippedImage.Width, 0, MatrixOrder.Append)
  58.  
  59.            Case FlipType.Vertical
  60.                m = New Matrix(1, 0, 0, -1, 0, 0)
  61.                m.Translate(0, flippedImage.Height, MatrixOrder.Append)
  62.  
  63.            Case FlipType.Both
  64.                m = New Matrix(-1, 0, 0, -1, 0, 0)
  65.                m.Translate(flippedImage.Width, flippedImage.Height, MatrixOrder.Append)
  66.        End Select
  67.  
  68.        ' Draw
  69.        g.Transform = m
  70.        g.DrawImage(sender, 0, 0)
  71.  
  72.        'clean up
  73.        m.Dispose()
  74.    End Using
  75.  
  76.    Return flippedImage
  77.  
  78. End Function
  79.  
  80. end module

Modo de empleo:

Código
  1. dim img as image = image.fromfile("C:\file.png")
  2. dim flipped as image=  imf.Flip(FlipType.Vertical)



Cifrado XOR

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Encrypts or decrypts a string using XOR algorithm.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <param name="text">
  7. ''' The text to encrypt.
  8. ''' </param>
  9. '''
  10. ''' <param name="key">
  11. ''' The key to use for encryption of decryption.
  12. ''' </param>
  13. ''' ----------------------------------------------------------------------------------------------------
  14. ''' <returns>
  15. ''' The encrypted string.
  16. ''' </returns>
  17. ''' ----------------------------------------------------------------------------------------------------
  18. <DebuggerStepThrough>
  19. Public Shared Function XorEncryptOrDecrypt(ByVal text As String, ByVal key As Integer) As String
  20.  
  21.    Dim sb As New StringBuilder(text.Length, text.Length)
  22.    For Each c As Char In text
  23.        ' Get the ASCII value of the character.
  24.        Dim charValue As Integer = Convert.ToInt32(c)
  25.        ' XOR the value.
  26.        charValue = (charValue Xor key)
  27.        ' Convert back to string.
  28.        sb.Append(Char.ConvertFromUtf32(charValue))
  29.    Next
  30.  
  31.    Return sb.ToString()
  32.  
  33. End Function

Modo de empleo:
Código
  1. Dim str As String = "Hello World"
  2. Dim encrypted As String = XorEncryptOrDecrypt(str, 1)       ' Result: "Idmmn!Vnsme"
  3. Dim decrypted As String = XorEncryptOrDecrypt(encrypted, 1) ' Result: "Hello World"



Obtener un array con los bytes del archivo de la aplicación actual

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Gets the bytes of the local file that points to the running assembly.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <value>
  7. ''' A <see cref="Byte()"/> array containing the bytes of the local file that points to the running assembly.
  8. ''' </value>
  9. ''' ----------------------------------------------------------------------------------------------------
  10. Public Shared ReadOnly Property SelfBytes As Byte()
  11.    <DebuggerStepThrough>
  12.    Get
  13.        Using fs As FileStream = File.OpenRead(System.Windows.Forms.Application.ExecutablePath)
  14.            Dim exeBytes As Byte() = New Byte(CInt(fs.Length - 1)) {}
  15.            fs.Read(exeBytes, 0, exeBytes.Length)
  16.            Return exeBytes
  17.        End Using
  18.    End Get
  19. End Property

Modo de empleo:
Código
  1. Dim selfBytes As Byte() = SelfBytes()



Obtener recursos embedidos en un ensamblado .NET

Código
  1. Partial Public NotInheritable Class ResourceUtil
  2.  
  3.    ''' ----------------------------------------------------------------------------------------------------
  4.    ''' <summary>
  5.    ''' Gets an embedded resource in the specified <see cref="Assembly"/>.
  6.    ''' </summary>
  7.    ''' ----------------------------------------------------------------------------------------------------
  8.    ''' <param name="name">
  9.    ''' The name of the resource.
  10.    ''' </param>
  11.    '''
  12.    ''' <param name="ass">
  13.    ''' The <see cref="Assembly"/> to look for the resource.
  14.    ''' </param>
  15.    ''' ----------------------------------------------------------------------------------------------------
  16.    ''' <returns>
  17.    ''' A <see cref="Byte()"/> array containing the bytes of the embedded resource.
  18.    ''' </returns>
  19.    ''' ----------------------------------------------------------------------------------------------------
  20.    Public Shared Function GetEmbeddedResource(ByVal name As String, ByVal ass As Assembly) As Byte()
  21.  
  22.        name = ResourceUtil.FormatResourceName(name, ass)
  23.  
  24.        Using resx As Stream = ass.GetManifestResourceStream(name)
  25.  
  26.            If (resx Is Nothing) Then
  27.                Throw New Exception("Resource not found in the specified .NET assembly.")
  28.  
  29.            Else
  30.                Dim content As Byte() = New Byte(CInt(resx.Length - 1)) {}
  31.                resx.Read(content, 0, content.Length)
  32.                Return content
  33.  
  34.            End If
  35.  
  36.        End Using
  37.  
  38.    End Function
  39.  
  40.    ''' ----------------------------------------------------------------------------------------------------
  41.    ''' <summary>
  42.    ''' Gets an embedded resource in the calling assembly.
  43.    ''' </summary>
  44.    ''' ----------------------------------------------------------------------------------------------------
  45.    ''' <param name="name">
  46.    ''' The name of the resource.
  47.    ''' </param>
  48.    ''' ----------------------------------------------------------------------------------------------------
  49.    ''' <returns>
  50.    ''' A <see cref="Byte()"/> array containing the bytes of the embedded resource.
  51.    ''' </returns>
  52.    ''' ----------------------------------------------------------------------------------------------------
  53.    Public Shared Function GetEmbeddedResource(ByVal name As String) As Byte()
  54.  
  55.        Return ResourceUtil.GetEmbeddedResource(name, Assembly.GetCallingAssembly())
  56.  
  57.    End Function
  58.  
  59.    ''' ----------------------------------------------------------------------------------------------------
  60.    ''' <summary>
  61.    ''' Gets an embedded resource of type <see cref="String"/> in the specified <see cref="Assembly"/>.
  62.    ''' </summary>
  63.    ''' ----------------------------------------------------------------------------------------------------
  64.    ''' <param name="name">
  65.    ''' The name of the resource.
  66.    ''' </param>
  67.    '''
  68.    ''' <param name="ass">
  69.    ''' The <see cref="Assembly"/> to look for the resource.
  70.    ''' </param>
  71.    ''' ----------------------------------------------------------------------------------------------------
  72.    ''' <returns>
  73.    ''' The embedded resource as <see cref="String"/>.
  74.    ''' </returns>
  75.    ''' ----------------------------------------------------------------------------------------------------
  76.    Public Shared Function GetEmbeddedResourceAsString(ByVal name As String, ByVal ass As Assembly, Optional ByVal enc As Encoding = Nothing) As String
  77.  
  78.        If (enc Is Nothing) Then
  79.            enc = Encoding.Default
  80.        End If
  81.  
  82.        name = ResourceUtil.FormatResourceName(name, ass)
  83.  
  84.        Using resx As Stream = ass.GetManifestResourceStream(name)
  85.  
  86.            If (resx Is Nothing) Then
  87.                Throw New Exception("Resource not found in the specified .NET assembly.")
  88.            Else
  89.                Using reader As New StreamReader(resx, enc)
  90.                    Return reader.ReadToEnd()
  91.                End Using
  92.            End If
  93.  
  94.        End Using
  95.  
  96.    End Function
  97.  
  98.    ''' ----------------------------------------------------------------------------------------------------
  99.    ''' <summary>
  100.    ''' Gets an embedded resource of type <see cref="String"/> in the calling assembly.
  101.    ''' </summary>
  102.    ''' ----------------------------------------------------------------------------------------------------
  103.    ''' <param name="name">
  104.    ''' The name of the resource.
  105.    ''' </param>
  106.    ''' ----------------------------------------------------------------------------------------------------
  107.    ''' <returns>
  108.    ''' The embedded resource as <see cref="String"/>.
  109.    ''' </returns>
  110.    ''' ----------------------------------------------------------------------------------------------------
  111.    Public Shared Function GetEmbeddedResourceAsString(ByVal name As String, Optional ByVal enc As Encoding = Nothing) As String
  112.  
  113.        Return ResourceUtil.GetEmbeddedResourceAsString(name, Assembly.GetCallingAssembly(), enc)
  114.  
  115.    End Function
  116.  
  117.    ''' ----------------------------------------------------------------------------------------------------
  118.    ''' <summary>
  119.    ''' Gets an embedded resource of type <see cref="Image"/> in the specified <see cref="Assembly"/>.
  120.    ''' </summary>
  121.    ''' ----------------------------------------------------------------------------------------------------
  122.    ''' <param name="name">
  123.    ''' The name of the resource.
  124.    ''' </param>
  125.    '''
  126.    ''' <param name="ass">
  127.    ''' The <see cref="Assembly"/> to look for the resource.
  128.    ''' </param>
  129.    ''' ----------------------------------------------------------------------------------------------------
  130.    ''' <returns>
  131.    ''' The embedded resource as <see cref="Image"/>.
  132.    ''' </returns>
  133.    ''' ----------------------------------------------------------------------------------------------------
  134.    Public Shared Function GetEmbeddedResourceAsImage(ByVal name As String, ByVal ass As Assembly) As Image
  135.  
  136.        name = ResourceUtil.FormatResourceName(name, ass)
  137.  
  138.        Using resx As Stream = ass.GetManifestResourceStream(name)
  139.  
  140.            If (resx Is Nothing) Then
  141.                Throw New Exception("Resource not found in the specified .NET assembly.")
  142.            Else
  143.                Using ms As New MemoryStream()
  144.                    resx.CopyTo(ms)
  145.                    Return Image.FromStream(ms)
  146.                End Using
  147.  
  148.            End If
  149.  
  150.        End Using
  151.  
  152.    End Function
  153.  
  154.    ''' ----------------------------------------------------------------------------------------------------
  155.    ''' <summary>
  156.    ''' Gets an embedded resource of type <see cref="Image"/> in the calling assembly.
  157.    ''' </summary>
  158.    ''' ----------------------------------------------------------------------------------------------------
  159.    ''' <param name="name">
  160.    ''' The name of the resource.
  161.    ''' </param>
  162.    ''' ----------------------------------------------------------------------------------------------------
  163.    ''' <returns>
  164.    ''' The embedded resource as <see cref="Image"/>.
  165.    ''' </returns>
  166.    ''' ----------------------------------------------------------------------------------------------------
  167.    Public Shared Function GetEmbeddedResourceAsImage(ByVal name As String) As Image
  168.  
  169.        Return ResourceUtil.GetEmbeddedResourceAsImage(name, Assembly.GetCallingAssembly())
  170.  
  171.    End Function
  172.  
  173.    ''' ----------------------------------------------------------------------------------------------------
  174.    ''' <summary>
  175.    ''' Formats a resource name.
  176.    ''' </summary>
  177.    ''' ----------------------------------------------------------------------------------------------------
  178.    ''' <param name="name">
  179.    ''' The name of the resource.
  180.    ''' </param>
  181.    '''
  182.    ''' <param name="ass">
  183.    ''' The assembly that contains the resource.
  184.    ''' </param>
  185.    ''' ----------------------------------------------------------------------------------------------------
  186.    ''' <returns>
  187.    ''' The resulting formatted resource name.
  188.    ''' </returns>
  189.    ''' ----------------------------------------------------------------------------------------------------
  190.    Private Shared Function FormatResourceName(ByVal name As String, ByVal ass As Assembly) As String
  191.  
  192.        Return String.Format("{0}.{1}", ass.GetName().Name, name.Replace(" ", "_").
  193.                                                                 Replace("\", ".").
  194.                                                                 Replace("/", "."))
  195.  
  196.    End Function
  197.  
  198. End Class

Ejemplo de uso para la aplicación actual:
Código
  1. Dim data As Byte() = GetEmbeddedResource("file.txt")
  2. Dim dataAsString As String = Encoding.Default.GetString(data)
  3.  
  4. Dim str As String = GetEmbeddedResourceAsString("file.txt", Encoding.Default)
  5.  
  6. Dim img As Image = GetEmbeddedResourceAsImage("file.png")

Ejemplo de uso con un ensamblado específico:
Código
  1. Dim data As Byte() = GetEmbeddedResource("file.txt", Assembly.GetCallingAssembly())
  2. Dim dataAsString As String = Encoding.Default.GetString(data)
  3.  
  4. Dim str As String = GetEmbeddedResourceAsString("file.txt", Assembly.GetCallingAssembly(), Encoding.Default)
  5.  
  6. Dim img As Image = GetEmbeddedResourceAsImage("file.png", Assembly.GetCallingAssembly())



Todas estas funcionalidades y muchísimas más las podrán encontrar en mi Framework ElektroKit.
« Última modificación: 7 Abril 2017, 06:26 por Eleкtro » En línea


Eleкtro
Novato Astral y
Moderador Global
***
Conectado Conectado

Mensajes: 8.848


El sentido común es el menos común de los sentidos


Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #505 en: 13 Abril 2017, 12:50 »

Pausar la ejecución de la consola hasta que se pulse cierta tecla...

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Pause the console execution Indefinitely until any key is pressed.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. <DebuggerStepThrough>
  7. Public Shared Sub Pause()
  8.    Console.ReadKey(intercept:=True)
  9. End Sub
  10.  
  11. ''' ----------------------------------------------------------------------------------------------------
  12. ''' <summary>
  13. ''' Pause the console execution Indefinitely until the specified key is pressed.
  14. ''' </summary>
  15. ''' ----------------------------------------------------------------------------------------------------
  16. ''' <param name="key">
  17. ''' The key to wait for.
  18. ''' </param>
  19. ''' ----------------------------------------------------------------------------------------------------
  20. <DebuggerStepThrough>
  21. Public Shared Sub Pause(ByVal key As Keys)
  22.  
  23.    Dim keyInfo As ConsoleKeyInfo
  24.  
  25.    Do Until (keyInfo.Key = key)
  26.        keyInfo = Console.ReadKey(intercept:=True)
  27.    Loop
  28.  
  29. End Sub

Modo de empleo:
Código
  1. Console.WriteLine("Press any key to exit...")
  2. Pause()
  3. Environment.Exit(0)

Código
  1. Dim key As Keys = Keys.Enter
  2. Dim keyName As String = [Enum].GetName(GetType(Keys), key)
  3.  
  4. Console.WriteLine(String.Format("Press '{0}' key to continue...", keyName))
  5. Pause(key)
  6. Console.WriteLine("Well done.")
En línea


Eleкtro
Novato Astral y
Moderador Global
***
Conectado Conectado

Mensajes: 8.848


El sentido común es el menos común de los sentidos


Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #506 en: 29 Abril 2017, 20:00 »

Un puñado de funciones para extender las posibilidades de la función built-in System.IO.Path.GetTempFileName()

Modo de empleo:

Código
  1. Dim tmpFile1 As FileInfo = GetTempFile()
  2. Dim tmpFile2 As FileInfo = GetTempFile("txt")
  3. Dim tmpFile3 As FileInfo = GetTempFile(SpecialFolder.LocalApplicationData)
  4. Dim tmpFile4 As FileInfo = GetTempFile(SpecialFolder.LocalApplicationData, "txt")
  5. Dim tmpFile5 As FileInfo = GetTempFile(New DirectoryInfo("C:\Folder\"))
  6. Dim tmpFile6 As FileInfo = GetTempFile(New DirectoryInfo("C:\Folder\"), "txt")
  7. Dim tmpFile7 As FileInfo = GetTempFile("C:\Folder\", "txt")

Código
  1. Dim tmpFilePath1 As String = GetTempFileName()
  2. Dim tmpFilePath2 As String = GetTempFileName("txt")
  3. Dim tmpFilePath3 As String = GetTempFileName(SpecialFolder.LocalApplicationData)
  4. Dim tmpFilePath4 As String = GetTempFileName(SpecialFolder.LocalApplicationData, "txt")
  5. Dim tmpFilePath5 As String = GetTempFileName(New DirectoryInfo("C:\Folder\"))
  6. Dim tmpFilePath6 As String = GetTempFileName(New DirectoryInfo("C:\Folder\"), "txt")
  7. Dim tmpFilePath7 As String = GetTempFileName("C:\Folder\", "txt")

Código fuente:

Código
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Creates a uniquely named, zero-byte temporary file on the system's default temporary folder
  4. ''' and returns the file.
  5. ''' </summary>
  6. ''' ----------------------------------------------------------------------------------------------------
  7. ''' <example> This is a code example.
  8. ''' <code>
  9. ''' Dim tmpFile As FileInfo = GetTempFile()
  10. ''' Console.WriteLine(tmpFile.FullName)
  11. ''' </code>
  12. ''' </example>
  13. ''' ----------------------------------------------------------------------------------------------------
  14. ''' <returns>
  15. ''' The resulting <see cref="FileInfo"/>.
  16. ''' </returns>
  17. ''' ----------------------------------------------------------------------------------------------------
  18. <DebuggerStepThrough>
  19. Public Shared Function GetTempFile() As FileInfo
  20.  
  21.    Return New FileInfo(Path.GetTempFileName())
  22.  
  23. End Function
  24.  
  25. ''' ----------------------------------------------------------------------------------------------------
  26. ''' <summary>
  27. ''' Creates a uniquely named, zero-byte temporary file on the specified folder
  28. ''' and returns the file.
  29. ''' </summary>
  30. ''' ----------------------------------------------------------------------------------------------------
  31. ''' <example> This is a code example.
  32. ''' <code>
  33. ''' Dim tmpFile As FileInfo = GetTempFile(SpecialFolder.LocalApplicationData)
  34. ''' Console.WriteLine(tmpFile.FullName)
  35. ''' </code>
  36. ''' </example>
  37. ''' ----------------------------------------------------------------------------------------------------
  38. ''' <param name="folder">
  39. ''' The folder where to create the temporary file.
  40. ''' </param>
  41. ''' ----------------------------------------------------------------------------------------------------
  42. ''' <returns>
  43. ''' The resulting <see cref="FileInfo"/>.
  44. ''' </returns>
  45. ''' ----------------------------------------------------------------------------------------------------
  46. <DebuggerStepThrough>
  47. Public Shared Function GetTempFile(ByVal folder As SpecialFolder) As FileInfo
  48.  
  49.    Return GetTempFile(Environment.GetFolderPath(folder), "tmp")
  50.  
  51. End Function
  52.  
  53. ''' ----------------------------------------------------------------------------------------------------
  54. ''' <summary>
  55. ''' Creates a uniquely named, zero-byte temporary file on the specified folder
  56. ''' and returns the file.
  57. ''' </summary>
  58. ''' ----------------------------------------------------------------------------------------------------
  59. ''' <example> This is a code example.
  60. ''' <code>
  61. ''' Dim tmpFile As FileInfo = GetTempFile(New DirectoryInfo("C:\Folder\"))
  62. ''' Console.WriteLine(tmpFile.FullName)
  63. ''' </code>
  64. ''' </example>
  65. ''' ----------------------------------------------------------------------------------------------------
  66. ''' <param name="dir">
  67. ''' The folder where to create the temporary file.
  68. ''' </param>
  69. ''' ----------------------------------------------------------------------------------------------------
  70. ''' <returns>
  71. ''' The resulting <see cref="FileInfo"/>.
  72. ''' </returns>
  73. ''' ----------------------------------------------------------------------------------------------------
  74. <DebuggerStepThrough>
  75. Public Shared Function GetTempFile(ByVal dir As DirectoryInfo) As FileInfo
  76.  
  77.    Return GetTempFile(dir.FullName, "tmp")
  78.  
  79. End Function
  80.  
  81. ''' ----------------------------------------------------------------------------------------------------
  82. ''' <summary>
  83. ''' Creates a uniquely named, zero-byte temporary file on the system's default temporary folder with the specified file extension
  84. ''' and returns the file.
  85. ''' </summary>
  86. ''' ----------------------------------------------------------------------------------------------------
  87. ''' <example> This is a code example.
  88. ''' <code>
  89. ''' Dim tmpFile As FileInfo = GetTempFile("txt")
  90. ''' Console.WriteLine(tmpFile.FullName)
  91. ''' </code>
  92. ''' </example>
  93. ''' ----------------------------------------------------------------------------------------------------
  94. ''' <param name="extension">
  95. ''' The file extension to assign to the temporary file.
  96. ''' </param>
  97. ''' ----------------------------------------------------------------------------------------------------
  98. ''' <returns>
  99. ''' The resulting <see cref="FileInfo"/>.
  100. ''' </returns>
  101. ''' ----------------------------------------------------------------------------------------------------
  102. ''' <exception cref="ArgumentNullException">
  103. ''' extension
  104. ''' </exception>
  105. ''' ----------------------------------------------------------------------------------------------------
  106. <DebuggerStepThrough>
  107. Public Shared Function GetTempFile(ByVal extension As String) As FileInfo
  108.  
  109.    Return GetTempFile(Environment.GetFolderPath(SpecialFolder.LocalApplicationData), extension)
  110.  
  111. End Function
  112.  
  113. ''' ----------------------------------------------------------------------------------------------------
  114. ''' <summary>
  115. ''' Creates a uniquely named, zero-byte temporary file on the specified folder with the specified file extension
  116. ''' and returns the file.
  117. ''' </summary>
  118. ''' ----------------------------------------------------------------------------------------------------
  119. ''' <example> This is a code example.
  120. ''' <code>
  121. ''' Dim tmpFile As FileInfo = GetTempFile(SpecialFolder.LocalApplicationData, "txt")
  122. ''' Console.WriteLine(tmpFile.FullName)
  123. ''' </code>
  124. ''' </example>
  125. ''' ----------------------------------------------------------------------------------------------------
  126. ''' <param name="folder">
  127. ''' The folder where to create the temporary file.
  128. ''' </param>
  129. '''
  130. ''' <param name="extension">
  131. ''' The file extension to assign to the temporary file.
  132. ''' </param>
  133. ''' ----------------------------------------------------------------------------------------------------
  134. ''' <returns>
  135. ''' The resulting <see cref="FileInfo"/>.
  136. ''' </returns>
  137. ''' ----------------------------------------------------------------------------------------------------
  138. ''' <exception cref="ArgumentNullException">
  139. ''' extension
  140. ''' </exception>
  141. ''' ----------------------------------------------------------------------------------------------------
  142. <DebuggerStepThrough>
  143. Public Shared Function GetTempFile(ByVal folder As SpecialFolder, ByVal extension As String) As FileInfo
  144.  
  145.    Return GetTempFile(Environment.GetFolderPath(folder), extension)
  146.  
  147. End Function
  148.  
  149. ''' ----------------------------------------------------------------------------------------------------
  150. ''' <summary>
  151. ''' Creates a uniquely named, zero-byte temporary file on the specified folder with the specified file extension
  152. ''' and returns the file.
  153. ''' </summary>
  154. ''' ----------------------------------------------------------------------------------------------------
  155. ''' <example> This is a code example.
  156. ''' <code>
  157. ''' Dim tmpFile As FileInfo = GetTempFile(New DirectoryInfo("C:\Folder\"), "txt")
  158. ''' Console.WriteLine(tmpFile.FullName)
  159. ''' </code>
  160. ''' </example>
  161. ''' ----------------------------------------------------------------------------------------------------
  162. ''' <param name="dir">
  163. ''' The folder where to create the temporary file.
  164. ''' </param>
  165. '''
  166. ''' <param name="extension">
  167. ''' The file extension to assign to the temporary file.
  168. ''' </param>
  169. ''' ----------------------------------------------------------------------------------------------------
  170. ''' <returns>
  171. ''' The resulting <see cref="FileInfo"/>.
  172. ''' </returns>
  173. ''' ----------------------------------------------------------------------------------------------------
  174. ''' <exception cref="ArgumentNullException">
  175. ''' extension
  176. ''' </exception>
  177. ''' ----------------------------------------------------------------------------------------------------
  178. <DebuggerStepThrough>
  179. Public Shared Function GetTempFile(ByVal dir As DirectoryInfo, ByVal extension As String) As FileInfo
  180.  
  181.    Return GetTempFile(dir.FullName, extension)
  182.  
  183. End Function
  184.  
  185. ''' ----------------------------------------------------------------------------------------------------
  186. ''' <summary>
  187. ''' Creates a uniquely named, zero-byte temporary file on the specified folder with the specified file extension
  188. ''' and returns the file.
  189. ''' </summary>
  190. ''' ----------------------------------------------------------------------------------------------------
  191. ''' <example> This is a code example.
  192. ''' <code>
  193. ''' Dim tmpFile As FileInfo = GetTempFile("C:\Folder\", "txt")
  194. ''' Console.WriteLine(tmpFile.FullName)
  195. ''' </code>
  196. ''' </example>
  197. ''' ----------------------------------------------------------------------------------------------------
  198. ''' <param name="dirPath">
  199. ''' The full path of the folder where to create the temporary file.
  200. ''' </param>
  201. '''
  202. ''' <param name="extension">
  203. ''' The file extension to assign to the temporary file.
  204. ''' </param>
  205. ''' ----------------------------------------------------------------------------------------------------
  206. ''' <returns>
  207. ''' The resulting <see cref="FileInfo"/>.
  208. ''' </returns>
  209. ''' ----------------------------------------------------------------------------------------------------
  210. ''' <exception cref="ArgumentNullException">
  211. ''' dirPath or extension
  212. ''' </exception>
  213. ''' ----------------------------------------------------------------------------------------------------
  214. <DebuggerStepThrough>
  215. Public Shared Function GetTempFile(ByVal dirPath As String, ByVal extension As String) As FileInfo
  216.  
  217.    If String.IsNullOrWhiteSpace(dirPath) Then
  218.        Throw New ArgumentNullException("dirPath")
  219.  
  220.    ElseIf String.IsNullOrWhiteSpace(extension) Then
  221.        Throw New ArgumentNullException("extension")
  222.  
  223.    Else
  224.        Dim dir As New DirectoryInfo(dirPath)
  225.        If Not (dir.Exists) Then
  226.            Try
  227.                dir.Create()
  228.            Catch ex As Exception
  229.                Throw
  230.                Return Nothing
  231.            End Try
  232.        End If
  233.  
  234.        Dim tmpFile As FileInfo = Nothing
  235.        Dim newFilePath As String
  236.        Dim defaultFolderPath As String = Environment.GetFolderPath(SpecialFolder.LocalApplicationData)
  237.        Dim defaultFileExtension As String = "tmp"
  238.        Do
  239.            If (tmpFile IsNot Nothing) AndAlso (tmpFile.Exists) Then
  240.                tmpFile.Delete()
  241.            End If
  242.            tmpFile = New FileInfo(Path.GetTempFileName())
  243.  
  244.            If Not (dir.FullName.Equals(defaultFolderPath, StringComparison.OrdinalIgnoreCase)) Then
  245.                newFilePath = Path.Combine(dir.FullName, tmpFile.Name)
  246.            Else
  247.                newFilePath = tmpFile.FullName
  248.            End If
  249.  
  250.            If Not (extension.Equals(defaultFileExtension, StringComparison.OrdinalIgnoreCase)) Then
  251.                newFilePath = Path.ChangeExtension(newFilePath, extension)
  252.            End If
  253.  
  254.        Loop Until (newFilePath.Equals(tmpFile.FullName, StringComparison.OrdinalIgnoreCase)) OrElse Not File.Exists(newFilePath)
  255.  
  256.        tmpFile.MoveTo(newFilePath)
  257.        tmpFile.Refresh()
  258.  
  259.        Return tmpFile
  260.  
  261.    End If
  262.  
  263. End Function
  264.  
  265. ''' ----------------------------------------------------------------------------------------------------
  266. ''' <summary>
  267. ''' Creates a uniquely named, zero-byte temporary file on the system's default temporary folder
  268. ''' and returns the file path.
  269. ''' </summary>
  270. ''' ----------------------------------------------------------------------------------------------------
  271. ''' <example> This is a code example.
  272. ''' <code>
  273. ''' Dim tmpFile As String = GetTempFileName()
  274. ''' Console.WriteLine(tmpFile)
  275. ''' </code>
  276. ''' </example>
  277. ''' ----------------------------------------------------------------------------------------------------
  278. ''' <returns>
  279. ''' The full path of the temporary file.
  280. ''' </returns>
  281. ''' ----------------------------------------------------------------------------------------------------
  282. <DebuggerStepThrough>
  283. Public Shared Function GetTempFileName() As String
  284.  
  285.    Return Path.GetTempFileName()
  286.  
  287. End Function
  288.  
  289. ''' ----------------------------------------------------------------------------------------------------
  290. ''' <summary>
  291. ''' Creates a uniquely named, zero-byte temporary file on the specified folder
  292. ''' and returns the file path.
  293. ''' </summary>
  294. ''' ----------------------------------------------------------------------------------------------------
  295. ''' <example> This is a code example.
  296. ''' <code>
  297. ''' Dim tmpFile As String = GetTempFileName(SpecialFolder.LocalApplicationData)
  298. ''' Console.WriteLine(tmpFile)
  299. ''' </code>
  300. ''' </example>
  301. ''' ----------------------------------------------------------------------------------------------------
  302. ''' <param name="folder">
  303. ''' The folder where to create the temporary file.
  304. ''' </param>
  305. ''' ----------------------------------------------------------------------------------------------------
  306. ''' <returns>
  307. ''' The full path of the temporary file.
  308. ''' </returns>
  309. ''' ----------------------------------------------------------------------------------------------------
  310. <DebuggerStepThrough>
  311. Public Shared Function GetTempFileName(ByVal folder As SpecialFolder) As String
  312.  
  313.    Return GetTempFile(Environment.GetFolderPath(folder), "tmp").FullName
  314.  
  315. End Function
  316.  
  317. ''' ----------------------------------------------------------------------------------------------------
  318. ''' <summary>
  319. ''' Creates a uniquely named, zero-byte temporary file on the specified folder
  320. ''' and returns the file path.
  321. ''' </summary>
  322. ''' ----------------------------------------------------------------------------------------------------
  323. ''' <example> This is a code example.
  324. ''' <code>
  325. ''' Dim tmpFile As String = GetTempFileName(New DirectoryInfo("C:\Folder\"))
  326. ''' Console.WriteLine(tmpFile)
  327. ''' </code>
  328. ''' </example>
  329. ''' ----------------------------------------------------------------------------------------------------
  330. ''' <param name="dir">
  331. ''' The folder where to create the temporary file.
  332. ''' </param>
  333. ''' ----------------------------------------------------------------------------------------------------
  334. ''' <returns>
  335. ''' The full path of the temporary file.
  336. ''' </returns>
  337. ''' ----------------------------------------------------------------------------------------------------
  338. <DebuggerStepThrough>
  339. Public Shared Function GetTempFileName(ByVal dir As DirectoryInfo) As String
  340.  
  341.    Return GetTempFile(dir.FullName, "tmp").FullName
  342.  
  343. End Function
  344.  
  345. ''' ----------------------------------------------------------------------------------------------------
  346. ''' <summary>
  347. ''' Creates a uniquely named, zero-byte temporary file on the system's default temporary folder with the specified file extension
  348. ''' and returns the file path.
  349. ''' </summary>
  350. ''' ----------------------------------------------------------------------------------------------------
  351. ''' <example> This is a code example.
  352. ''' <code>
  353. ''' Dim tmpFile As String = GetTempFileName("txt")
  354. ''' Console.WriteLine(tmpFile)
  355. ''' </code>
  356. ''' </example>
  357. ''' ----------------------------------------------------------------------------------------------------
  358. ''' <param name="extension">
  359. ''' The file extension to assign to the temporary file.
  360. ''' </param>
  361. ''' ----------------------------------------------------------------------------------------------------
  362. ''' <returns>
  363. ''' The full path of the temporary file.
  364. ''' </returns>
  365. ''' ----------------------------------------------------------------------------------------------------
  366. ''' <exception cref="ArgumentNullException">
  367. ''' extension
  368. ''' </exception>
  369. ''' ----------------------------------------------------------------------------------------------------
  370. <DebuggerStepThrough>
  371. Public Shared Function GetTempFileName(ByVal extension As String) As String
  372.  
  373.    Return GetTempFile(Environment.GetFolderPath(SpecialFolder.LocalApplicationData), extension).FullName
  374.  
  375. End Function
  376.  
  377. ''' ----------------------------------------------------------------------------------------------------
  378. ''' <summary>
  379. ''' Creates a uniquely named, zero-byte temporary file on the specified folder with the specified file extension
  380. ''' and returns the file path.
  381. ''' </summary>
  382. ''' ----------------------------------------------------------------------------------------------------
  383. ''' <example> This is a code example.
  384. ''' <code>
  385. ''' Dim tmpFile As String = GetTempFileName(SpecialFolder.LocalApplicationData, "txt")
  386. ''' Console.WriteLine(tmpFile)
  387. ''' </code>
  388. ''' </example>
  389. ''' ----------------------------------------------------------------------------------------------------
  390. ''' <param name="folder">
  391. ''' The folder where to create the temporary file.
  392. ''' </param>
  393. '''
  394. ''' <param name="extension">
  395. ''' The file extension to assign to the temporary file.
  396. ''' </param>
  397. ''' ----------------------------------------------------------------------------------------------------
  398. ''' <returns>
  399. ''' The full path of the temporary file.
  400. ''' </returns>
  401. ''' ----------------------------------------------------------------------------------------------------
  402. ''' <exception cref="ArgumentNullException">
  403. ''' extension
  404. ''' </exception>
  405. ''' ----------------------------------------------------------------------------------------------------
  406. <DebuggerStepThrough>
  407. Public Shared Function GetTempFileName(ByVal folder As SpecialFolder, ByVal extension As String) As String
  408.  
  409.    Return GetTempFile(Environment.GetFolderPath(folder), extension).FullName
  410.  
  411. End Function
  412.  
  413. ''' ----------------------------------------------------------------------------------------------------
  414. ''' <summary>
  415. ''' Creates a uniquely named, zero-byte temporary file on the specified folder with the specified file extension
  416. ''' and returns the file path.
  417. ''' </summary>
  418. ''' ----------------------------------------------------------------------------------------------------
  419. ''' <example> This is a code example.
  420. ''' <code>
  421. ''' Dim tmpFile As String = GetTempFileName(New DirectoryInfo("C:\Folder\"), "txt")
  422. ''' Console.WriteLine(tmpFile)
  423. ''' </code>
  424. ''' </example>
  425. ''' ----------------------------------------------------------------------------------------------------
  426. ''' <param name="dir">
  427. ''' The folder where to create the temporary file.
  428. ''' </param>
  429. '''
  430. ''' <param name="extension">
  431. ''' The file extension to assign to the temporary file.
  432. ''' </param>
  433. ''' ----------------------------------------------------------------------------------------------------
  434. ''' <returns>
  435. ''' The full path of the temporary file.
  436. ''' </returns>
  437. ''' ----------------------------------------------------------------------------------------------------
  438. ''' <exception cref="ArgumentNullException">
  439. ''' extension
  440. ''' </exception>
  441. ''' ----------------------------------------------------------------------------------------------------
  442. <DebuggerStepThrough>
  443. Public Shared Function GetTempFileName(ByVal dir As DirectoryInfo, ByVal extension As String) As String
  444.  
  445.    Return GetTempFile(dir.FullName, extension).FullName
  446.  
  447. End Function
  448.  
  449. ''' ----------------------------------------------------------------------------------------------------
  450. ''' <summary>
  451. ''' Creates a uniquely named, zero-byte temporary file on the specified folder with the specified file extension
  452. ''' and returns the file path.
  453. ''' </summary>
  454. ''' ----------------------------------------------------------------------------------------------------
  455. ''' <example> This is a code example.
  456. ''' <code>
  457. ''' Dim tmpFile As String = GetTempFileName("C:\Folder\", "txt")
  458. ''' Console.WriteLine(tmpFile)
  459. ''' </code>
  460. ''' </example>
  461. ''' ----------------------------------------------------------------------------------------------------
  462. ''' <param name="dirPath">
  463. ''' The full path of the folder where to create the temporary file.
  464. ''' </param>
  465. '''
  466. ''' <param name="extension">
  467. ''' The file extension to assign to the temporary file.
  468. ''' </param>
  469. ''' ----------------------------------------------------------------------------------------------------
  470. ''' <returns>
  471. ''' The full path of the temporary file.
  472. ''' </returns>
  473. ''' ----------------------------------------------------------------------------------------------------
  474. ''' <exception cref="ArgumentNullException">
  475. ''' dirPath or extension
  476. ''' </exception>
  477. ''' ----------------------------------------------------------------------------------------------------
  478. <DebuggerStepThrough>
  479. Public Shared Function GetTempFileName(ByVal dirPath As String, ByVal extension As String) As String
  480.  
  481.    Return GetTempFile(dirPath, extension).FullName
  482.  
  483. End Function
  484.  
« Última modificación: 29 Abril 2017, 20:13 por Eleкtro » En línea


Eleкtro
Novato Astral y
Moderador Global
***
Conectado Conectado

Mensajes: 8.848


El sentido común es el menos común de los sentidos


Ver Perfil
Re: Librería de Snippets para VB.Net !! (Compartan aquí sus snippets)
« Respuesta #507 en: 6 Mayo 2017, 14:05 »

Método Application.DoEvents() perfeccionado

Muchos programadores de VB.NET a veces se encuentran en un escenario de programación en el que deben realizar una operación asincrónica, pero en lugar de implementar el modo correcto de programación asincrónica suelen llamar al método Application.DoEvents() con la intención de esperar a que dicha operación asincrónica termine y evitar el bloqueo en el hilo de la interfáz gráfica. Esto se suele hacer decorando la llamada a dicho método usando un búcle, por ejemplo:

Código
  1. Do While (condición)
  2.     Application.DoEvents()
  3. Loop

Sin embargo, hacer llamadas consecutivas a dicho método en un tiempo de intervalo demasiado corto (como en el búcle de arriba) causará un exceso muy importante de consumo de recursos en el equipo, puesto que basicamente lo que hace el método Application.DoEvents() es recibir, procesar, y despachar todos los mensajes pendientes en la cola, y no lo hace de forma selectiva, así que se procesan todos los mensajes de entrada/input, de dibujado/paint, los eventos, y etc, una y otra vez.

El método Application.DoEvents() tiene un propósito muy distinto del que realmente se le suele dar, y hay muchas formas de evitar tener que usar dicho método, pero no entraremos en esos temas ahora. Lo que explicaré será como poder mejorar el rendimiento y la responsabilidad de nuestra aplicación en un 90% al usar el método Application.DoEvents() cuando se le pretenda dar el uso que se ha explicado al principio.

Puesto que el método Application.DoEvents() se suele utilizar para aumentar la respuesta de la UI en una iteración intensiva, lo más apropiado para aumentar el rendimiento sería comprobar si existen mensajes de entrada (teclado o ratón) en la cola de mensajes del hilo de la UI antes de llamar a Application.DoEvents(). Y para ello existe una función Win32 a la que podemos recurrir presicamente para obtener un valor que nos diga si hay mensajes que se deban procesar o no los hay. La función se llama GetInputState, y en fin, todo esto que acabo de explicar quedaría implementado así:

Código
  1. ''' <summary>
  2. ''' Determines whether there are mouse-button or keyboard messages in the calling thread's message queue.
  3. ''' </summary>
  4. ''' <remarks>
  5. ''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644935(v=vs.85).aspx"/>
  6. ''' </remarks>
  7. ''' <returns>
  8. ''' If the queue contains one or more new mouse-button or keyboard messages, the return value is <see langword="True"/>.
  9. ''' <para></para>
  10. ''' If there are no new mouse-button or keyboard messages in the queue, the return value is <see langword="False"/>.
  11. ''' </returns>
  12. <SuppressUnmanagedCodeSecurity>
  13. <DllImport("user32.dll", SetLastError:=False)>
  14. Private Shared Function GetInputState() As <MarshalAs(UnmanagedType.Bool)> Boolean
  15. End Function
  16.  
  17. ''' <summary>
  18. ''' Processes all Windows messages currently in the message queue of the application.
  19. ''' <para></para>
  20. ''' This method greatly boosts the performance of any application in difference to <see cref="Application.DoEvents()"/> method.
  21. ''' <para></para>
  22. ''' When calling <see cref="Application.DoEvents()"/> to make the UI responsive, it generally decreases application performance;
  23. ''' <para></para>
  24. ''' however, using this method, we make sure there is at least one input event (keyboard or mouse) that needs to be processed before internally calling <see cref="Application.DoEvents()"/>.
  25. ''' </summary>
  26. Public Shared Sub DoEvents()
  27.    If GetInputState() Then
  28.        Global.System.Windows.Forms.Application.DoEvents()
  29.    End If
  30. End Sub

Modo de empleo:
Código
  1. Do While True
  2.     DoEvents()
  3. Loop
« Última modificación: 6 Mayo 2017, 14:08 por Eleкtro » En línea


Páginas: 1 ... 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 [51] Ir Arriba Respuesta Imprimir 

Ir a:  

Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines