Menú

Mostrar Mensajes

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

Mostrar Mensajes Menú

Mensajes - Eleкtro

#6041
Creo que te refieres a esto, entonces simplemente añade los If necesarios:

Código (dos) [Seleccionar]
@Echo OFF

If Exist "%ProgramFiles(x86)%\Mozilla Thunderbird\thunderbird.exe" (
Start /W "thunderbird" "%ProgramFiles(x86)%\Mozilla Thunderbird\thunderbird.exe"
)

If Exist "%ProgramFiles%\Mozilla Thunderbird\thunderbird.exe" (
Start /W "thunderbird" "%ProgramFiles%\Mozilla Thunderbird\thunderbird.exe"
)

If Exist "%HomeDrive%\correo\thunderbird\thunderbird.exe" (
Start /W "thunderbird" "%HomeDrive%\correo\thunderbird\thunderbird.exe"
)

Exit


También podrías ahorrarte cualquier If y en su lugar utilizar el comando DIR para realizar una búsqueda en los discos duros conectados según el nombre del archivo (en este caso "thunderbird.exe") para así hallar su ubicación exacta y ejecutar el programa sin conocer su ruta exacta por un "IF Exist Ruta", pero bueno, no se si llegas a necesitar tanto.

Saludos!
#6042
El comando Start espera como primer argumento un título, y como segundo argumento la ruta del archivo, estás cometiendo un fallo muy habitual.

Código (dos) [Seleccionar]
@Echo OFF

If Defined ProgramFiles(x86) (
Start /W "thunderbird for Winx64" "%ProgramFiles(x86)%\Mozilla Thunderbird\thunderbird.exe"
) Else (
Start /W "thunderbird for Winx86" "%ProgramFiles%\Mozilla Thunderbird\thunderbird.exe"
)

Exit


EDITO: Perdón, no leí el final de la duda que formulaste:

No, Batch no soporta multiples condiciones del tipo Else (ElseIf...), lo único que puedes hacer es usar múltiples If, por ejemplo:

Código (dos) [Seleccionar]
If Condición1 (
...
) Else (
...
)

If Condición2 (
...
) Else (
...
)


También puedes anidarlos, ejemplo:

Código (dos) [Seleccionar]
If Condición1 (
...

If Condición2 (
...
) Else (
...
)

) Else (
...
)


Quizás también te sirva saber que Batch soporta el operador AND, de forma oculta, ejemplo:

Código (dos) [Seleccionar]
If Condición1 If Condición2 (
...
) Else (
...
)


Esto sería, If Condición1 y Condición2 se cumplen then...

Saludos
#6043
Cita de: Jero67 en 30 Noviembre 2014, 22:12 PMYo mismo me respondo  :o

metiendolos dentro de un Panel o GroupBox

Claro, hay que entender como funciona internamente un RadioButton,
éste se basa en todos los controles de su mismo type (RadioButton) que estén alojados en la misma colección de controles (ControlCollection), es decir, dentro del contenedor de controles donde hayas colocado el RadioButton.

Si colocas un RadioButton directamente en el Form, la colección de controles al que está asociado el RadioButton será "Form1.Contols", así que necesitas añadir una colección de controles o contenedor adicional para poder separar los RadioButton y así su comportamiento, para eso nos sirve un GroupBox, ya que si colocas un RadioButton en un GroupBox, éste se basará en la colección de controles del GroupBox, es decir, "Form1.GroupBox1.Controls".

Puedes cambiar el container en tiempo de ejecución asignando la propiedad Parent:
Código (csharp) [Seleccionar]
RadioButton1.Parent = Me.GroupBox1;
Cita de: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.parent%28v=vs.110%29.aspxSetting the Parent property value to Nothing removes the control from the Control.ControlCollection of its current parent control.

O bien usando el método Add de una colección de controles. (Ej: Me.Controls.Add)

Control.ControlCollection.Add Method - MSDN
Control.ControlCollection.AddRange Method - MSDN

Saludos.
#6044
Depende de que versión estemos hablando (2010, 2012, 2013, etc).

Por ejemplo, no existe una tabla comparativa oficial de Microsoft VS2013 Express contra versiones superiores, pero aquí puedes ver una buena tabla NO oficial de diferencias:
http://www.techxtend.com/partnercenter/partners.aspx?name=microsoft-visual-studio-2013-comparisons

Aparte, en la wikipedia puedes encontrar información adicional:
Cita de: http://en.wikipedia.org/wiki/Microsoft_Visual_Studio_Express#ExtensibilityVisual Studio is extensible by nature, ultimately consisting of a core "shell" that implements all commands, windows, editors, project types, languages, and other features through dynamically loadable modules called "packages".[34][35] Microsoft encourages and fosters third-party partners to create modules for Visual Studio via the free VSIP program. However, according to Dan Fernandez, Microsoft "made a business decision to not allow 3rd party extensibility in Express".[36]

La diferencia principal y en mi opinión la más importante de la edición express, como nos cuenta la Wikipedia, es que NO tiene soporte para plugins/extensiones, así que herramientas como GhostDoc, ReSharper, Telerik JustCode/JustTrace/JustDecompile, cualquier paquete de NuGet u otras extensiones supuestamente no podrás instalarlas en la IDE, y esto limitaría tu capacidad productiva en caso de que estés acostumbrado a extender tus capacidades utilizando este tipo de herramientas las cuales son practicamente necesarias para el día a día (una vez descubres de que son capaces de hacer por ti).

La segunda diferencia más importante, ya comentada por El Benjo, es la carencia de herramientas productivas en la edición express, como por ejemplo el Ofuscador o el Tracer de rendimiento/memoria, ambos productos de Microsoft que vienen incluidos en la versión Ultimate (eso si, no son gratis).

En mi opinión, no merece la pena instalar la versión Express, es una manera tonta de limitar tus capacidades, a menos que sepas que no vas a necesitar más.

La versión Comunity no la he llegado a probar (yo uso la Ultimate), pero al parecer esta versión si que tiene soporte para plugins:
Cita de: http://www.visualstudio.com/en-us/news/vs2013-community-vs.aspxGet Visual Studio extensions that incorporate new languages, features, and development tools into this IDE. (These extensions are available from the Visual Studio Gallery.)

Saludos!




Cita de: El Benjo en  1 Diciembre 2014, 06:13 AMEs decir, no hay una versión express del .NET Framework.

.Net Framework 4.0 se distribuyó en dos versiones, la versión "Perfil de cliente" (Client profile), y la versión completa (Full profile).

La versión cliente podríamos considerarla una versión Express, ya que carece de diversas funcionalidades para el programador, para usar ciertas características (de la librería de classes de .Net FW 4.0) hay que usar la versión completa, y lo mismo ocurre para que el enduser pueda utilizar esa aplicación donde utilizaste dichas características, hay que instalar en ese pc la versión completa.

http://blogs.msdn.com/b/jgoldb/archive/2010/04/12/what-s-new-in-net-framework-4-client-profile-rtm.aspx

Por suerte, Microsoft decidió cambiar esa tan mala decisión de planificacion en sus nuevas versiones/distribuciones de .Net Framework.

Saludos!
#6045
Buenas

Para una aplicación que estoy desarrollando me gustaría conocer los distintos tipos de archivos de líricas de canciones (lyrics) que sean reproducibles en WinAmp u otros reproductores, yo solo conozco los lyrics reproducibles en formato .lrc, que no son más que texto plano con este formato:

[00:12.00]Line 1 lyrics
[00:17.20]Line 2 lyrics
[00:21.10]Line 3 lyrics
...
[mm:ss.xx]last lyrics line


( Más info en Wikipedia: http://en.wikipedia.org/wiki/LRC_%28file_format%29 )

¿Alguien conoce mas tipos de lyrics sincronizados/reproducibles?

PD: No confundir con formatos de subtítulos (.ssa, .ass, .sub, etc), por favor '¬¬

Saludos!
#6046
Este snippet de mi vieja biblioteca te debería servir para tus propósitos, la función busca un caracter todas las ocurrencias de un caracter y devuelve todos sus índices.

De todas formas el problema que tienes no tiene mucho misterio, también puedes leer caracter por caracter usando un For, o una pila (usando la Class Stack) podría ser mejor según tus necesidades.

VB.Net:
Código (vbnet) [Seleccionar]
   ' Find Characters
   ' ( By Elektro )
   '
   ' Usage Examples:
   ' Dim CharIndex As Integer() = FindCharacters("Elektro", "E", IgnoreCase:=True) ' Result: {0, 2}
   '
   ''' <summary>
   ''' Matches a character/string pattern in a String and returns the starting indexes of all concurrences.
   ''' </summary>
   ''' <param name="String">Indicates the string.</param>
   ''' <param name="Characters">Indicates the character(s) to find.</param>
   ''' <param name="IgnoreCase">if set to <c>true</c>, sensitive case is ignored.</param>
   ''' <returns>System.Int32().</returns>
   Public Function FindCharacters(ByVal [String] As String,
                                  ByVal Characters As String,
                                  Optional ByVal IgnoreCase As Boolean = False) As Integer()

       Return Enumerable.Range(0, [String].Length).
                         Where(Function(i As Integer) Characters.Select(Function(b1, b2) New With {b2, b1}).
                         All(Function(p) If(IgnoreCase,
                                            [String].ToLower.ToCharArray()(i + p.b2).Equals(Char.ToLower(p.b1)),
                                            [String].ToCharArray()(i + p.b2).Equals(p.b1)))).
                         ToArray()

   End Function


C#, traducción al vuelo:
Código (csharp) [Seleccionar]
// Matches a character/string pattern in a String and returns the starting indexes of all concurrences.
// ( By Elektro )
//
// Usage Examples:
// Dim CharIndex As Integer() = FindCharacters("Elektro", "E", IgnoreCase:=True) ' Result: {0, 2}
//
/// <summary>
/// Finds the characters.
/// </summary>
/// <param name="String">Indicates the string.</param>
/// <param name="Characters">Indicates the character(s) to find.</param>
/// <param name="IgnoreCase">if set to <c>true</c>, sensitive case is ignored.</param>
/// <returns>System.Int32().</returns>
public int[] FindCharacters(string String, string Characters, bool IgnoreCase = false)
{

return Enumerable.Range(0, String.Length).Where((int i) => Characters.Select((b1, b2) => new {
b2,
b1
}).All(p => IgnoreCase ? String.ToLower.ToCharArray()(i + p.b2).Equals(char.ToLower(p.b1)) : String.ToCharArray()(i + p.b2).Equals(p.b1))).ToArray();

}

//=======================================================
//Service provided by Telerik (www.telerik.com)
//=======================================================


Saludos
#6047
Foro Libre / Re: Video Real ? FAKE
30 Noviembre 2014, 02:08 AM
Es más falso que un billete de 3 euros.

Que "casualidad" que los automóviles hayan pasado en el momento preciso en la escala del tiempo para que el individuo pueda realizar los 3 movimientos tan "casualmente" perfectos y más sincronizados que un reloj atómico, primero pasa un automóvil para esquivarlo corriendo, luego un coche pequeño para poder saltarlo, y luego uno más grande para poder tumbarse en el suelo, que "proeza" tan digna de "admiración".

Saludos!
#6048
Una actualización de este snippet para añadir el efecto de parpadeo a un control, o al texto de un control, es muy sencillo de usar.

Código (vbnet) [Seleccionar]
' ***********************************************************************
' Author   : Elektro
' Modified : 16-November-2014
' ***********************************************************************
' <copyright file="Blinker.vb" company="Elektro Studios">
'     Copyright (c) Elektro Studios. All rights reserved.
' </copyright>
' ***********************************************************************

#Region " Option Restrictions "

Option Strict On
Option Explicit On
Option Infer Off

#End Region

#Region " Usage Examples "

'Public Class Form1
'
'    Private labelBlinker As Blinker
'
'    Private Shadows Sub Shown() Handles MyBase.Shown
'
'        Me.labelBlinker = New Blinker(ctrl:=Label1)
'
'        ' Blink
'        With Me.labelBlinker
'            .Blink(interval:=500)
'            .BlinkText(interval:=500, customText:="Custom Text!")
'        End With
'
'        ' Unblink
'        With Me.labelBlinker
'            .Unblink(visible:=True)
'            .UnblinkText(restoreText:=True)
'        End With
'
'    End Sub
'
'End Class

#End Region

''' <summary>
''' Blinks a Control.
''' </summary>
Friend NotInheritable Class Blinker

#Region " Properties "

    ''' <summary>
    ''' Gets or sets the control to blink.
    ''' </summary>
    ''' <value>The control to blink.</value>
    Friend Property Ctrl As Control

#End Region

#Region " Objects "

    ''' <summary>
    ''' A custom text to restore it after blinking the control.
    ''' </summary>
    Private textToRestore As String

    ''' <summary>
    ''' A Timer to blink a control.
    ''' </summary>
    Private WithEvents blinkTimer As Timer

    ''' <summary>
    ''' A Timer to blink the text of a control.
    ''' </summary>
    Private WithEvents blinkTextTimer As Timer

    ''' <summary>
    ''' Determines whether the control is blinking.
    ''' </summary>
    Private isBlinking As Boolean = False

    ''' <summary>
    ''' Determines whether the text of the control is blinking.
    ''' </summary>
    Private isBlinkingText As Boolean = False

#End Region

#Region " Constructors "

    ''' <summary>
    ''' Initializes a new instance of the <see cref="Blinker" /> class.
    ''' </summary>
    ''' <param name="ctrl">Indicates the control to blink.</param>
    Public Sub New(ByVal ctrl As Control)

        ' Assign the control to blink.
        Me.Ctrl = ctrl

    End Sub

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

#End Region

#Region " Public Methods "

    ''' <summary>
    ''' Blinks the Control.
    ''' </summary>
    ''' <param name="Interval">Indicates the blink interval, in ms.</param>
    Public Sub Blink(Optional ByVal interval As Integer = 500I)

        If blinkTimer Is Nothing Then
            blinkTimer = New Timer
        End If

        With blinkTimer
            .Interval = interval
            .Enabled = True
        End With

        Me.isBlinking = True

    End Sub

    ''' <summary>
    ''' Stop blinking the Control.
    ''' </summary>
    ''' <param name="Visible">Indicates the visibility of the control.</param>
    Public Sub Unblink(Optional ByVal visible As Boolean = True)

        If Not isBlinking Then
            Exit Sub
        End If

        With blinkTimer
            .Enabled = False
        End With

        Me.Ctrl.Visible = visible
        Me.isBlinking = False

    End Sub

    ''' <summary>
    ''' Blinks the text content of the Control.
    ''' </summary>
    ''' <param name="Interval">Indicates the blink interval.</param>
    ''' <param name="CustomText">Indicates a custom text to blink.</param>
    Public Sub BlinkText(Optional ByVal interval As Integer = 500I,
                         Optional ByVal customText As String = Nothing)

        If blinkTextTimer Is Nothing Then
            blinkTextTimer = New Timer
        End If

        With blinkTextTimer
            .Tag = If(String.IsNullOrEmpty(customText), Me.Ctrl.Text, customText)
            .Interval = interval
            .Enabled = True
        End With

        Me.textToRestore = Me.Ctrl.Text
        Me.isBlinkingText = True

    End Sub

    ''' <summary>
    ''' Stop blinking the text content of the Control.
    ''' </summary>
    ''' <param name="RestoreText">If set to <c>true</c>, the control text is resetted to the initial state before started blinking.</param>
    Public Sub UnblinkText(Optional ByVal restoreText As Boolean = False)

        If Not isBlinkingText Then
            Exit Sub
        End If

        With blinkTextTimer
            .Enabled = False
        End With

        If restoreText Then
            Me.Ctrl.Text = Me.textToRestore
        End If

        Me.isBlinkingText = False

    End Sub

#End Region

#Region " Event Handlers"

    ''' <summary>
    ''' Handles the Tick event of the BlinkTimer control.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
    Private Sub BlinkTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) _
    Handles blinkTimer.Tick

        Me.Ctrl.Visible = Not Me.Ctrl.Visible

    End Sub

    ''' <summary>
    ''' Handles the Tick event of the BlinkTextTimer control.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
    Private Sub BlinkTextTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) _
    Handles blinkTextTimer.Tick

        If String.IsNullOrEmpty(Me.Ctrl.Text) Then
            Me.Ctrl.Text = DirectCast(DirectCast(sender, Timer).Tag, String)

        Else
            Me.Ctrl.Text = String.Empty

        End If

    End Sub

#End Region

End Class
#6049
Ejemplo de cómo añadir en tiempo de ejecución la característica Drag (arrastrar) en un control, para arrastrarlo por la UI.

Código (vbnet) [Seleccionar]
' ***********************************************************************
' Author           : Elektro
' Last Modified On : 11-10-2014
' ***********************************************************************
' <copyright file="ControlDragger.vb" company="Elektro Studios">
'     Copyright (c) Elektro Studios. All rights reserved.
' </copyright>
' ***********************************************************************

#Region " Usage Examples "

'Public Class Form1
'
'    Private Dragger As ControlDragger = ControlDragger.Empty
'
'    Private Sub InitializeDrag()
'        Me.Dragger = New ControlDragger(Button1)
'        Me.Dragger.Cursor = Cursors.SizeAll
'        Me.Dragger.Enabled = True
'    End Sub
'
'    Private Sub AlternateDrag()
'        Dragger.Enabled = Not Dragger.Enabled
'    End Sub
'
'    Private Sub FinishDrag()
'        Dragger.Dispose()
'    End Sub
'
'    Private Sub Test() Handles MyBase.Shown
'        Me.InitializeDrag()
'    End Sub
'
'End Class

#End Region

#Region " Imports "

Imports System.ComponentModel

#End Region

#Region " Control Dragger "

''' <summary>
''' Enable or disable drag at runtime on a <see cref="Control"/>.
''' </summary>
Friend NotInheritable Class ControlDragger : Implements IDisposable

#Region " Properties "

    ''' <summary>
    ''' Gets the associated <see cref="Control"/> used to perform draggable operations.
    ''' </summary>
    ''' <value>The control.</value>
    <EditorBrowsable(EditorBrowsableState.Always)>
    <Description("The associated Control used to perform draggable operations.")>
    Friend ReadOnly Property Control As Control
        Get
            Return Me._ctrl
        End Get
    End Property
    ''' <summary>
    ''' The associated <see cref="Control"/> used to perform draggable operations.
    ''' </summary>
    Private WithEvents _ctrl As Control = Nothing

    ''' <summary>
    ''' Represents a <see cref="T:ControlDragger"/> instance that is <c>Nothing</c>.
    ''' </summary>
    ''' <value><c>Nothing</c></value>
    <EditorBrowsable(EditorBrowsableState.Always)>
    <Description("Represents a ControlDragger instance that is Nothing.")>
    Public Shared ReadOnly Property Empty As ControlDragger
        Get
            Return Nothing
        End Get
    End Property

    ''' <summary>
    ''' Gets or sets a value indicating whether drag is enabled on the associated <see cref="Control"/>.
    ''' </summary>
    ''' <value><c>true</c> if drag is enabled; otherwise, <c>false</c>.</value>
    <EditorBrowsable(EditorBrowsableState.Always)>
    <Description("A value indicating whether drag is enabled on the associated control.")>
    Friend Property Enabled As Boolean = True

    ''' <summary>
    ''' Gets or sets the <see cref="Cursor"/> used to drag the associated <see cref="Control"/>.
    ''' </summary>
    ''' <value>The <see cref="Cursor"/>.</value>
    <EditorBrowsable(EditorBrowsableState.Always)>
    <Description("The Cursor used to drag the associated Control")>
    Friend Property Cursor As Cursor = Cursors.SizeAll

    ''' <summary>
    ''' A <see cref="T:ControlDragger"/> instance instance containing the draggable information of the associated <see cref="Control"/>.
    ''' </summary>
    ''' <value>The draggable information.</value>
    <EditorBrowsable(EditorBrowsableState.Never)>
    <Description("A ControlDragger instance instance containing the draggable information of the associated Control.")>
    Private Property DragInfo As ControlDragger = ControlDragger.Empty

    ''' <summary>
    ''' Gets or sets the initial mouse coordinates, normally <see cref="Control.MousePosition"/>.
    ''' </summary>
    ''' <value>The initial mouse coordinates.</value>
    <EditorBrowsable(EditorBrowsableState.Never)>
    <Description("The initial mouse coordinates, normally 'Control.MousePosition'")>
    Private Property InitialMouseCoords As Point = Point.Empty

    ''' <summary>
    ''' Gets or sets the initial <see cref="Control"/> location, normally <see cref="Control.Location"/>.
    ''' </summary>
    ''' <value>The initial location.</value>
    <EditorBrowsable(EditorBrowsableState.Never)>
    <Description("The initial Control location, normally 'Control.Location'")>
    Private Property InitialLocation As Point = Point.Empty

    ''' <summary>
    ''' Gets or sets the old control's cursor to restore it after dragging.
    ''' </summary>
    ''' <value>The old control's cursor.</value>
    <EditorBrowsable(EditorBrowsableState.Never)>
    <Description("The old control's cursor to restore it after dragging.")>
    Private Property oldCursor As Cursor = Nothing

#End Region

#Region " Constructors "

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

    ''' <summary>
    ''' Initializes a new instance of the <see cref="ControlDragger"/> class.
    ''' </summary>
    ''' <param name="ctrl">The <see cref="Control"/> used to perform draggable operations.</param>
    Public Sub New(ByVal ctrl As Control)

        Me._ctrl = ctrl

    End Sub

    ''' <summary>
    ''' Initializes a new instance of the <see cref="ControlDragger"/> class.
    ''' </summary>
    ''' <param name="mouseCoordinates">The current mouse coordinates.</param>
    ''' <param name="location">The current location.</param>
    Private Sub New(ByVal mouseCoordinates As Point, ByVal location As Point)

        Me.InitialMouseCoords = mouseCoordinates
        Me.InitialLocation = location

    End Sub

#End Region

#Region " Private Methods "

    ''' <summary>
    ''' Return the new location.
    ''' </summary>
    ''' <param name="mouseCoordinates">The current mouse coordinates.</param>
    ''' <returns>The new location.</returns>
    Private Function GetNewLocation(ByVal mouseCoordinates As Point) As Point

        Return New Point(InitialLocation.X + (mouseCoordinates.X - InitialMouseCoords.X),
                         InitialLocation.Y + (mouseCoordinates.Y - InitialMouseCoords.Y))

    End Function

#End Region

#Region " Hidden Methods "

    ''' <summary>
    ''' Serves as a hash function for a particular type.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub GetHashCode()
    End Sub

    ''' <summary>
    ''' Gets the System.Type of the current instance.
    ''' </summary>
    ''' <returns>The exact runtime type of the current instance.</returns>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Function [GetType]()
        Return Me.GetType
    End Function

    ''' <summary>
    ''' Determines whether the specified System.Object instances are considered equal.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub Equals()
    End Sub

    ''' <summary>
    ''' Determines whether the specified System.Object instances are the same instance.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Private Shadows Sub ReferenceEquals()
    End Sub

    ''' <summary>
    ''' Returns a String that represents the current object.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub ToString()
    End Sub

#End Region

#Region " Event Handlers "

    ''' <summary>
    ''' Handles the MouseEnter event of the control.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    Private Sub ctrl_MouseEnter(ByVal sender As Object, ByVal e As EventArgs) _
    Handles _ctrl.MouseEnter

        Me.oldCursor = Me._ctrl.Cursor

        If Me.Enabled Then

            Me._ctrl.Cursor = Me.Cursor
            Me._ctrl.BringToFront()

        End If

    End Sub

    ''' <summary>
    ''' Handles the MouseLeave event of the control.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    Private Sub ctrl_MouseLeave(ByVal sender As Object, ByVal e As EventArgs) _
    Handles _ctrl.MouseLeave

        Me._ctrl.Cursor = Me.oldCursor

    End Sub

    ''' <summary>
    ''' Handles the MouseDown event of the control.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
    Private Sub ctrl_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) _
    Handles _ctrl.MouseDown

        If Me.Enabled Then

            Me.DragInfo = New ControlDragger(Control.MousePosition, Me._ctrl.Location)

        End If

    End Sub

    ''' <summary>
    ''' Handles the MouseMove event of the control.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
    Private Sub ctrl_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) _
    Handles _ctrl.MouseMove

        If Me.Enabled AndAlso (Me.DragInfo IsNot ControlDragger.Empty) Then

            Me._ctrl.Location = New Point(Me.DragInfo.GetNewLocation(Control.MousePosition))

        End If

    End Sub

    ''' <summary>
    ''' Handles the MouseUp event of the control.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
    Private Sub ctrl_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) _
    Handles _ctrl.MouseUp

        Me.DragInfo = ControlDragger.Empty

    End Sub

#End Region

#Region " IDisposable "

    ''' <summary>
    ''' To detect redundant calls when disposing.
    ''' </summary>
    Private IsDisposed As Boolean = False

    ''' <summary>
    ''' Prevent calls to methods after disposing.
    ''' </summary>
    ''' <exception cref="System.ObjectDisposedException"></exception>
    Private Sub DisposedCheck()

        If Me.IsDisposed Then
            Throw New ObjectDisposedException(Me.GetType().FullName)
        End If

    End Sub

    ''' <summary>
    ''' Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    ''' </summary>
    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

    ''' <summary>
    ''' Releases unmanaged and - optionally - managed resources.
    ''' </summary>
    ''' <param name="IsDisposing">
    ''' <c>true</c> to release both managed and unmanaged resources;
    ''' <c>false</c> to release only unmanaged resources.
    ''' </param>
    Protected Sub Dispose(ByVal IsDisposing As Boolean)

        If Not Me.IsDisposed Then

            If IsDisposing Then

                With Me._ctrl

                    If Not .IsDisposed AndAlso Not .Disposing Then

                        RemoveHandler .MouseEnter, AddressOf ctrl_MouseEnter
                        RemoveHandler .MouseLeave, AddressOf ctrl_MouseLeave
                        RemoveHandler .MouseDown, AddressOf ctrl_MouseDown
                        RemoveHandler .MouseMove, AddressOf ctrl_MouseMove
                        RemoveHandler .MouseUp, AddressOf ctrl_MouseUp

                    End If

                End With ' Me._ctrl

                With Me

                    .Enabled = False
                    .DragInfo = ControlDragger.Empty
                    .InitialMouseCoords = Point.Empty
                    .InitialLocation = Point.Empty
                    .oldCursor = Nothing
                    ._ctrl = Nothing

                End With ' Me

            End If ' IsDisposing

        End If ' Not Me.IsDisposed

        Me.IsDisposed = True

    End Sub

#End Region

End Class

#End Region





Ejemplo de cómo añadir en tiempo de ejecución la característica Resize (redimensionar) en un control, para redimensionarlo por la UI.

Código (vbnet) [Seleccionar]
' ***********************************************************************
' Author           : Elektro
' Last Modified On : 11-10-2014
' ***********************************************************************
' <copyright file="ControlResizer.vb" company="Elektro Studios">
'     Copyright (c) Elektro Studios. All rights reserved.
' </copyright>
' ***********************************************************************

#Region " Usage Examples "

'Public Class Form1
'
'    Private Resizer As ControlResizer = ControlResizer.Empty
'
'    Private Sub InitializeResizer()
'        Me.Resizer = New ControlResizer(Button1)
'        Me.Resizer.Enabled = True
'        Me.Resizer.PixelMargin = 4
'    End Sub
'
'    Private Sub AlternateResizer()
'        Me.Resizer.Enabled = Not Resizer.Enabled
'    End Sub
'
'    Private Sub FinishResizer()
'        Me.Resizer.Dispose()
'    End Sub
'
'    Private Sub Test() Handles MyBase.Shown
'        Me.InitializeResizer()
'    End Sub
'
'End Class

#End Region

#Region " Imports "

Imports System.ComponentModel

#End Region

#Region " Control Resizer "

''' <summary>
''' Enable or disable resize at runtime on a <see cref="Control"/>.
''' </summary>
Public Class ControlResizer : Implements IDisposable

#Region " Properties "

#Region " Visible "

    ''' <summary>
    ''' Gets the associated <see cref="Control"/> used to perform resizable operations.
    ''' </summary>
    ''' <value>The control.</value>
    <EditorBrowsable(EditorBrowsableState.Always)>
    <Description("The associated Control used to perform resizable operations.")>
    Friend ReadOnly Property Control As Control
        Get
            Return Me._ctrl
        End Get
    End Property
    ''' <summary>
    ''' The associated <see cref="Control"/> used to perform draggable operations.
    ''' </summary>
    Private WithEvents _ctrl As Control = Nothing

    ''' <summary>
    ''' Gets or sets the pixel margin required to activate resize indicators.
    ''' </summary>
    ''' <value>The pixel margin required activate resize indicators.</value>
    <EditorBrowsable(EditorBrowsableState.Always)>
    <Description("The associated Control used to perform resizable operations.")>
    Friend Property PixelMargin As Integer = 4I

    ''' <summary>
    ''' Gets or sets a value indicating whether resize is enabled on the associated <see cref="Control"/>.
    ''' </summary>
    ''' <value><c>true</c> if resize is enabled; otherwise, <c>false</c>.</value>
    <EditorBrowsable(EditorBrowsableState.Always)>
    <Description("A value indicating whether resize is enabled on the associated control.")>
    Friend Property Enabled As Boolean = True

    ''' <summary>
    ''' Represents a <see cref="T:ControlResizer"/> instance that is <c>Nothing</c>.
    ''' </summary>
    ''' <value><c>Nothing</c></value>
    <EditorBrowsable(EditorBrowsableState.Always)>
    <Description("Represents a ControlResizer instance that is Nothing.")>
    Public Shared ReadOnly Property Empty As ControlResizer
        Get
            Return Nothing
        End Get
    End Property

#End Region

#Region " Hidden "

    ''' <summary>
    ''' Gets or sets a value indicating whether the left mouse button is down.
    ''' </summary>
    ''' <value><c>true</c> if left mouse button is down; otherwise, <c>false</c>.</value>
    Private Property IsLeftMouseButtonDown As Boolean = False

    ''' <summary>
    ''' Gets or sets the current active edge.
    ''' </summary>
    ''' <value>The current active edge.</value>
    Private Property ActiveEdge As Edges = Edges.None

    ''' <summary>
    ''' Gets or sets the old control's cursor to restore it after resizing.
    ''' </summary>
    ''' <value>The old control's cursor.</value>
    Private Property oldCursor As Cursor = Nothing

#End Region

#End Region

#Region " Enumerations "

    ''' <summary>
    ''' Contains the Edges.
    ''' </summary>
    Private Enum Edges As Integer

        ''' <summary>
        ''' Any edge.
        ''' </summary>
        None = 0I

        ''' <summary>
        ''' Left edge.
        ''' </summary>
        Left = 1I

        ''' <summary>
        ''' Right edge.
        ''' </summary>
        Right = 2I

        ''' <summary>
        ''' Top edge.
        ''' </summary>
        Top = 3I

        ''' <summary>
        ''' Bottom edge.
        ''' </summary>
        Bottom = 4I

        ''' <summary>
        ''' Top-Left edge.
        ''' </summary>
        TopLeft = 5I

        ''' <summary>
        ''' Top-Right edge.
        ''' </summary>
        TopRight = 6I

        ''' <summary>
        ''' Bottom-Left edge.
        ''' </summary>
        BottomLeft = 7I

        ''' <summary>
        ''' Bottom-Right edge.
        ''' </summary>
        BottomRight = 8I

    End Enum

#End Region

#Region " Constructors "

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

    ''' <summary>
    ''' Initializes a new instance of the <see cref="ControlResizer"/> class.
    ''' </summary>
    ''' <param name="ctrl">The control.</param>
    Public Sub New(ByVal ctrl As Control)

        Me._ctrl = ctrl

    End Sub

#End Region

#Region " Event Handlers "

    ''' <summary>
    ''' Handles the MouseEnter event of the control.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    Private Sub ctrl_MouseEnter(ByVal sender As Object, ByVal e As EventArgs) _
    Handles _ctrl.MouseEnter

        Me.oldCursor = Me._ctrl.Cursor

    End Sub

    ''' <summary>
    ''' Handles the MouseLeave event of the control.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    Private Sub ctrl_MouseLeave(ByVal sender As Object, ByVal e As EventArgs) _
    Handles _ctrl.MouseLeave

        Me.ActiveEdge = Edges.None
        Me._ctrl.Cursor = Me.oldCursor

    End Sub

    ''' <summary>
    ''' Handles the MouseDown event of the control.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
    Private Sub ctrl_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) _
    Handles _ctrl.MouseDown

        Me.IsLeftMouseButtonDown = (e.Button = MouseButtons.Left)

    End Sub

    ''' <summary>
    ''' Handles the MouseUp event of the control.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
    Private Sub ctrl_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) _
    Handles _ctrl.MouseUp

        Me.IsLeftMouseButtonDown = False

    End Sub

    ''' <summary>
    ''' Handles the MouseMove event of the control.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
    Private Sub ctrl_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) _
    Handles _ctrl.MouseMove

        If Not Me.Enabled Then
            Exit Sub

        ElseIf (Me.IsLeftMouseButtonDown) AndAlso Not (Me.ActiveEdge = Edges.None) Then
            Me.SetControlBounds(e)

        Else
            Me.SetActiveEdge(e)
            Me.SetSizeCursor()

        End If

    End Sub

#End Region

#Region " Private Methods "

    ''' <summary>
    ''' Sets the active edge.
    ''' </summary>
    ''' <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
    Private Sub SetActiveEdge(ByVal e As MouseEventArgs)

        Select Case True

            ' Top-Left Corner
            Case e.X <= (Me.PixelMargin * 2) AndAlso
                 e.Y <= (Me.PixelMargin * 2)

                Me.ActiveEdge = Edges.TopLeft

                ' TopRight Corner
            Case e.X > Me._ctrl.Width - (Me.PixelMargin * 2) AndAlso
                 e.Y <= (Me.PixelMargin * 2)

                Me.ActiveEdge = Edges.TopRight

                ' Bottom-Left Corner
            Case (e.X <= Me.PixelMargin * 2) AndAlso
                 (e.Y > Me._ctrl.Height - (Me.PixelMargin * 2))

                Me.ActiveEdge = Edges.BottomLeft

                ' Bottom-Right Corner
            Case (e.X > Me._ctrl.Width - (Me.PixelMargin * 2) - 1) AndAlso
                 (e.Y > Me._ctrl.Height - (Me.PixelMargin * 2))

                Me.ActiveEdge = Edges.BottomRight


                ' Left Edge
            Case e.X <= Me.PixelMargin
                Me.ActiveEdge = Edges.Left

                ' Right Edge
            Case e.X > Me._ctrl.Width - (Me.PixelMargin + 1)
                Me.ActiveEdge = Edges.Right

                ' Top Edge
            Case e.Y <= Me.PixelMargin
                Me.ActiveEdge = Edges.Top

                ' Bottom Edge
            Case e.Y > Me._ctrl.Height - (Me.PixelMargin + 1)
                Me.ActiveEdge = Edges.Bottom

            Case Else ' Any Edge
                Me.ActiveEdge = Edges.None

        End Select

    End Sub

    ''' <summary>
    ''' Sets the size cursor.
    ''' </summary>
    Private Sub SetSizeCursor()

        Select Case Me.ActiveEdge

            Case Edges.Left
                Me._ctrl.Cursor = Cursors.SizeWE

            Case Edges.Right
                Me._ctrl.Cursor = Cursors.SizeWE

            Case Edges.Top
                Me._ctrl.Cursor = Cursors.SizeNS

            Case Edges.Bottom
                Me._ctrl.Cursor = Cursors.SizeNS

            Case Edges.TopLeft
                Me._ctrl.Cursor = Cursors.SizeNWSE

            Case Edges.TopRight
                Me._ctrl.Cursor = Cursors.SizeNESW

            Case Edges.BottomLeft
                Me._ctrl.Cursor = Cursors.SizeNESW

            Case Edges.BottomRight
                Me._ctrl.Cursor = Cursors.SizeNWSE

            Case Edges.None
                If Me.oldCursor IsNot Nothing Then
                    Me._ctrl.Cursor = Me.oldCursor
                End If

        End Select

    End Sub

    ''' <summary>
    ''' Sets the control bounds.
    ''' </summary>
    ''' <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
    Private Sub SetControlBounds(ByVal e As MouseEventArgs)

        If Me._ctrl.Size.Width = Me._ctrl.MinimumSize.Width Then
            ' Exit Sub
        Else
            Debug.WriteLine(Me._ctrl.Size.ToString)
        End If

        Me._ctrl.SuspendLayout()

        Select Case Me.ActiveEdge

            Case Edges.Left
                If Not Me._ctrl.Width - e.X < (Me._ctrl.MinimumSize.Width) Then
                    Me._ctrl.SetBounds(x:=Me._ctrl.Left + e.X,
                                       y:=Me._ctrl.Top,
                                       width:=Me._ctrl.Width - e.X,
                                       height:=Me._ctrl.Height)
                End If

            Case Edges.Right
                Me._ctrl.SetBounds(x:=Me._ctrl.Left,
                                   y:=Me._ctrl.Top,
                                   width:=Me._ctrl.Width - (Me._ctrl.Width - e.X),
                                   height:=Me._ctrl.Height)

            Case Edges.Top
                If Not Me._ctrl.Height - e.Y < (Me._ctrl.MinimumSize.Height) Then
                    Me._ctrl.SetBounds(x:=Me._ctrl.Left,
                                       y:=Me._ctrl.Top + e.Y,
                                       width:=Me._ctrl.Width,
                                       height:=Me._ctrl.Height - e.Y)
                End If

            Case Edges.Bottom
                Me._ctrl.SetBounds(x:=Me._ctrl.Left,
                                   y:=Me._ctrl.Top,
                                   width:=Me._ctrl.Width,
                                   height:=Me._ctrl.Height - (Me._ctrl.Height - e.Y))

            Case Edges.TopLeft
                Me._ctrl.SetBounds(x:=If(Not Me._ctrl.Width - e.X < (Me._ctrl.MinimumSize.Width),
                                         Me._ctrl.Left + e.X,
                                         Me._ctrl.Left),
                                   y:=If(Not Me._ctrl.Height - e.Y < (Me._ctrl.MinimumSize.Height),
                                         Me._ctrl.Top + e.Y,
                                         Me._ctrl.Top),
                                   width:=If(Not Me._ctrl.Width - e.X < (Me._ctrl.MinimumSize.Width),
                                             Me._ctrl.Width - e.X,
                                             Me._ctrl.Width),
                                   height:=If(Not Me._ctrl.Height - e.Y < (Me._ctrl.MinimumSize.Height),
                                              Me._ctrl.Height - e.Y,
                                              Me._ctrl.Height))

            Case Edges.TopRight
                Me._ctrl.SetBounds(x:=Me._ctrl.Left,
                                   y:=If(Not Me._ctrl.Height - e.Y < (Me._ctrl.MinimumSize.Height),
                                         Me._ctrl.Top + e.Y,
                                         Me._ctrl.Top),
                                   width:=Me._ctrl.Width - (Me._ctrl.Width - e.X),
                                   height:=If(Not Me._ctrl.Height - e.Y < (Me._ctrl.MinimumSize.Height),
                                              Me._ctrl.Height - e.Y,
                                              Me._ctrl.Height))

            Case Edges.BottomLeft
                Me._ctrl.SetBounds(x:=If(Not Me._ctrl.Width - e.X < (Me._ctrl.MinimumSize.Width),
                                         Me._ctrl.Left + e.X,
                                         Me._ctrl.Left),
                                   y:=Me._ctrl.Top,
                                   width:=If(Not Me._ctrl.Width - e.X < (Me._ctrl.MinimumSize.Width),
                                             Me._ctrl.Width - e.X,
                                             Me._ctrl.Width),
                                   height:=Me._ctrl.Height - (Me._ctrl.Height - e.Y))

            Case Edges.BottomRight
                Me._ctrl.SetBounds(x:=Me._ctrl.Left,
                                   y:=Me._ctrl.Top,
                                   width:=Me._ctrl.Width - (Me._ctrl.Width - e.X),
                                   height:=Me._ctrl.Height - (Me._ctrl.Height - e.Y))

        End Select

        Me._ctrl.ResumeLayout()

    End Sub

#End Region

#Region " Hidden Methods "

    ''' <summary>
    ''' Serves as a hash function for a particular type.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub GetHashCode()
    End Sub

    ''' <summary>
    ''' Gets the System.Type of the current instance.
    ''' </summary>
    ''' <returns>The exact runtime type of the current instance.</returns>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Function [GetType]()
        Return Me.GetType
    End Function

    ''' <summary>
    ''' Determines whether the specified System.Object instances are considered equal.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub Equals()
    End Sub

    ''' <summary>
    ''' Determines whether the specified System.Object instances are the same instance.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Private Shadows Sub ReferenceEquals()
    End Sub

    ''' <summary>
    ''' Returns a String that represents the current object.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub ToString()
    End Sub

#End Region

#Region " IDisposable "

    ''' <summary>
    ''' To detect redundant calls when disposing.
    ''' </summary>
    Private IsDisposed As Boolean = False

    ''' <summary>
    ''' Prevent calls to methods after disposing.
    ''' </summary>
    ''' <exception cref="System.ObjectDisposedException"></exception>
    Private Sub DisposedCheck()

        If Me.IsDisposed Then
            Throw New ObjectDisposedException(Me.GetType().FullName)
        End If

    End Sub

    ''' <summary>
    ''' Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    ''' </summary>
    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

    ''' <summary>
    ''' Releases unmanaged and - optionally - managed resources.
    ''' </summary>
    ''' <param name="IsDisposing">
    ''' <c>true</c> to release both managed and unmanaged resources;
    ''' <c>false</c> to release only unmanaged resources.
    ''' </param>
    Protected Sub Dispose(ByVal IsDisposing As Boolean)

        If Not Me.IsDisposed Then

            If IsDisposing Then

                With Me._ctrl

                    If Not .IsDisposed AndAlso Not .Disposing Then

                        RemoveHandler .MouseEnter, AddressOf ctrl_MouseEnter
                        RemoveHandler .MouseLeave, AddressOf ctrl_MouseLeave
                        RemoveHandler .MouseDown, AddressOf ctrl_MouseDown
                        RemoveHandler .MouseMove, AddressOf ctrl_MouseMove
                        RemoveHandler .MouseUp, AddressOf ctrl_MouseUp

                    End If

                End With ' Me._ctrl

                With Me

                    .Enabled = False
                    .oldCursor = Nothing
                    ._ctrl = Nothing

                End With ' Me

            End If ' IsDisposing

        End If ' Not Me.IsDisposed

        Me.IsDisposed = True

    End Sub

#End Region

End Class

#End Region
#6050
Una versión actualizada de mi MessageBox personalizado, cuyas funciones adicionales son la de aparecer centrado en el Form, o cambiar la fuente de texto (aunque dicha característica está algo improvisada)

Código (vbnet) [Seleccionar]
' ***********************************************************************
' Author   : Elektro
' Modified : 27-November-2014
' ***********************************************************************
' <copyright file="CenteredMessageBox.vb" company="Elektro Studios">
'     Copyright (c) Elektro Studios. All rights reserved.
' </copyright>
' ***********************************************************************

#Region " Usage Examples "

'Using New CenteredMessageBox(ownerForm:=Me,
'                             textFont:=New Font("Lucida Console", Font.SizeInPoints, FontStyle.Italic),
'                             timeOut:=2500)
'
'    MessageBox.Show("Text", "Title", MessageBoxButtons.OK, MessageBoxIcon.Information)
'
'End Using

#End Region

#Region " Option Statements "

Option Explicit On
Option Strict On
Option Infer Off

#End Region

#Region " Imports "

Imports System.Drawing
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.Windows.Forms
Imports System.ComponentModel

#End Region

#Region " Centered MessageBox "

''' <summary>
''' A customized <see cref="MessageBox"/>.
''' This class cannot be inherited.
''' </summary>
Friend NotInheritable Class CenteredMessageBox : Implements IDisposable

#Region " Properties "

   ''' <summary>
   ''' Gets the messagebox main window handle (hwnd).
   ''' </summary>
   ''' <value>The messagebox main window handle (hwnd).</value>
   Friend ReadOnly Property MessageBoxWindowHandle As IntPtr
       Get
           Return Me.messageBoxWindowHandle1
       End Get
   End Property
   ''' <summary>
   ''' The messagebox main window handle (hwnd).
   ''' </summary>
   Private messageBoxWindowHandle1 As IntPtr

   ''' <summary>
   ''' Gets the owner <see cref="Form"/> to center the <see cref="CenteredMessageBox"/>.
   ''' </summary>
   ''' <value>The owner <see cref="Form"/> to center the <see cref="CenteredMessageBox"/>.</value>
   Friend ReadOnly Property OwnerForm As Form
       Get
           Return Me.ownerForm1
       End Get
   End Property
   ''' <summary>
   ''' The owner <see cref="Form"/> to center the <see cref="CenteredMessageBox"/>
   ''' </summary>
   Private ownerForm1 As Form

   ''' <summary>
   ''' Gets the <see cref="Font"/> used to display the <see cref="CenteredMessageBox"/> text.
   ''' </summary>
   ''' <value>The <see cref="Font"/> used to display the <see cref="CenteredMessageBox"/> text.</value>
   Friend ReadOnly Property Font As Font
       Get
           Return Me.font1
       End Get
   End Property
   ''' <summary>
   ''' The <see cref="Font"/> used to display the <see cref="CenteredMessageBox"/> text.
   ''' </summary>
   Private ReadOnly font1 As Font

   ''' <summary>
   ''' Gets the time interval to auto-close this <see cref="CenteredMessageBox"/>, in milliseconds.
   ''' Default value is '0', which means Infinite.
   ''' </summary>
   Friend ReadOnly Property TimeOut As Integer
       Get
           Return Me.timeOut1
       End Get
   End Property
   ''' <summary>
   ''' The time interval to auto-close this <see cref="CenteredMessageBox"/>, in milliseconds.
   ''' Default value is '0', which means Infinite.
   ''' </summary>
   Private ReadOnly timeOut1 As Integer = 0

#End Region

#Region " Objects "

   ''' <summary>
   ''' A <see cref="Windows.Forms.Timer"/> that keeps track of <see cref="TimeOut"/> value to close this <see cref="CenteredMessageBox"/>.
   ''' </summary>
   Private WithEvents timeoutTimer As Timer

   ''' <summary>
   ''' Keeps track of the current amount of tries to find this <see cref="CenteredMessageBox"/> dialog.
   ''' </summary>
   Private tries As Integer

#End Region

#Region " P/Invoke "

   ''' <summary>
   ''' Platform Invocation methods (P/Invoke), access unmanaged code.
   ''' This class does not suppress stack walks for unmanaged code permission.
   ''' <see cref="System.Security.SuppressUnmanagedCodeSecurityAttribute"/>  must not be applied to this class.
   ''' This class is for methods that can be used anywhere because a stack walk will be performed.
   ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/ms182161.aspx
   ''' </summary>
   Protected NotInheritable Class NativeMethods

#Region " Functions "

       ''' <summary>
       ''' Retrieves the thread identifier of the calling thread.
       ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683183%28v=vs.85%29.aspx
       ''' </summary>
       ''' <returns>The thread identifier of the calling thread.</returns>
       <DllImport("kernel32.dll", SetLastError:=False)>
       Protected Friend Shared Function GetCurrentThreadId() As Integer
       End Function

       ''' <summary>
       ''' Enumerates all nonchild windows associated with a thread by passing the handle to each window,
       ''' in turn, to an application-defined callback function.
       ''' <see cref="EnumThreadWindows"/> continues until the last window is enumerated or the callback function returns <c>false</c>.
       ''' To enumerate child windows of a particular window, use the EnumChildWindows function.
       ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633495%28v=vs.85%29.aspx
       ''' </summary>
       ''' <param name="dwThreadId">The identifier of the thread whose windows are to be enumerated.</param>
       ''' <param name="lpfn">A pointer to an application-defined callback function.</param>
       ''' <param name="lParam">An application-defined value to be passed to the callback function.</param>
       ''' <returns>
       ''' <c>true</c> if the callback function returns <c>true</c> for all windows in the thread specified by dwThreadId parameter.
       ''' <c>false</c> if the callback function returns <c>false</c> on any enumerated window,
       ''' or if there are no windows found in the thread specified by dwThreadId parameter.</returns>
       <DllImport("user32.dll", SetLastError:=False)>
       Protected Friend Shared Function EnumThreadWindows(
                     ByVal dwThreadId As Integer,
                     ByVal lpfn As NativeMethods.EnumThreadWndProc,
                     ByVal lParam As IntPtr
           ) As <MarshalAs(UnmanagedType.Bool)> Boolean
       End Function

       ''' <summary>
       ''' Retrieves the name of the class to which the specified window belongs.
       ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633582%28v=vs.85%29.aspx
       ''' </summary>
       ''' <param name="hWnd">A handle to the window and, indirectly, the class to which the window belongs.</param>
       ''' <param name="buffer">The class name string.</param>
       ''' <param name="buflen">
       ''' The length of the lpClassName buffer, in characters.
       ''' The buffer must be large enough to include the terminating null character;
       ''' otherwise, the class name string is truncated to nMaxCount-1 characters.
       ''' </param>
       ''' <returns>
       ''' If the function succeeds, the return value is the number of characters copied to the buffer,
       ''' not including the terminating null character.
       ''' If the function fails, the return value is 0.
       ''' </returns>
       <DllImport("user32.dll", SetLastError:=False, CharSet:=CharSet.Auto)>
       Protected Friend Shared Function GetClassName(
                     ByVal hWnd As IntPtr,
                     ByVal buffer As StringBuilder,
                     ByVal buflen As Integer
           ) As Integer
       End Function

       ''' <summary>
       ''' Retrieves a handle to a control in the specified dialog box.
       ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645481%28v=vs.85%29.aspx
       ''' </summary>
       ''' <param name="hWnd">A handle to the dialog box that contains the control.</param>
       ''' <param name="item">The identifier of the control to be retrieved.</param>
       ''' <returns>
       ''' If the function succeeds, the return value is the window handle of the specified control.
       ''' If the function fails, the return value is <see cref="IntPtr.Zero"/>,
       ''' indicating an invalid dialog box handle or a nonexistent control
       ''' </returns>
       <DllImport("user32.dll", SetLastError:=False)>
       Protected Friend Shared Function GetDlgItem(
                     ByVal hWnd As IntPtr,
                     ByVal item As Integer
           ) As IntPtr
       End Function

       ''' <summary>
       ''' Retrieves the dimensions of the bounding rectangle of the specified window.
       ''' The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
       ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633519%28v=vs.85%29.aspx
       ''' </summary>
       ''' <param name="hWnd">A handle to the window.</param>
       ''' <param name="rc">
       ''' A pointer to a <see cref="RECT"/> structure that receives the screen coordinates of
       ''' the upper-left and lower-right corners of the window.
       ''' </param>
       ''' <returns><c>true</c> if the function succeeds, <c>false</c> otherwise.</returns>
       <DllImport("user32.dll", SetLastError:=False)>
       Protected Friend Shared Function GetWindowRect(
                     ByVal hWnd As IntPtr,
                     ByRef rc As Rect
           ) As <MarshalAs(UnmanagedType.Bool)> Boolean
       End Function

       ''' <summary>
       ''' Destroys the specified window.
       ''' The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it.
       ''' The function also destroys the window's menu, flushes the thread message queue, destroys timers, removes clipboard ownership,
       ''' and breaks the clipboard viewer chain (if the window is at the top of the viewer chain).
       ''' If the specified window is a parent or owner window,
       ''' DestroyWindow automatically destroys the associated child or owned windows when it destroys the parent or owner window.
       ''' The function first destroys child or owned windows, and then it destroys the parent or owner window.
       ''' DestroyWindow also destroys modeless dialog boxes created by the CreateDialog function.
       ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632682%28v=vs.85%29.aspx
       ''' </summary>
       ''' <param name="hwnd">Handle to the window to be destroyed.</param>
       ''' <returns><c>true</c> if the function succeeds, <c>false</c> otherwise.</returns>
       <DllImport("user32.dll", SetLastError:=False)>
       Protected Friend Shared Function DestroyWindow(
                     ByVal hwnd As IntPtr
           ) As <MarshalAs(UnmanagedType.Bool)> Boolean
       End Function

       ''' <summary>
       ''' Changes the position and dimensions of the specified window.
       ''' For a top-level window, the position and dimensions are relative to the upper-left corner of the screen.
       ''' For a child window, they are relative to the upper-left corner of the parent window's client area.
       ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633534%28v=vs.85%29.aspx
       ''' </summary>
       ''' <param name="hWnd">A handle to the window.</param>
       ''' <param name="x">The new position of the left side of the window.</param>
       ''' <param name="y">The new position of the top of the window.</param>
       ''' <param name="width">The new width of the window.</param>
       ''' <param name="height">The new height of the window.</param>
       ''' <param name="repaint">
       ''' Indicates whether the window is to be repainted.
       ''' If this parameter is TRUE, the window receives a message.
       ''' If the parameter is FALSE, no repainting of any kind occurs.
       ''' This applies to the client area, the nonclient area (including the title bar and scroll bars),
       ''' and any part of the parent window uncovered as a result of moving a child window.
       ''' </param>
       ''' <returns><c>true</c> if the function succeeds, <c>false</c> otherwise.</returns>
       <DllImport("user32.dll", SetLastError:=False)>
       Protected Friend Shared Function MoveWindow(
                     ByVal hWnd As IntPtr,
                     ByVal x As Integer,
                     ByVal y As Integer,
                     ByVal width As Integer,
                     ByVal height As Integer,
                     ByVal repaint As Boolean
           ) As <MarshalAs(UnmanagedType.Bool)> Boolean
       End Function

       ''' <summary>
       ''' Changes the size, position, and Z order of a child, pop-up, or top-level window.
       ''' These windows are ordered according to their appearance on the screen.
       ''' The topmost window receives the highest rank and is the first window in the Z order.
       ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545%28v=vs.85%29.aspx
       ''' </summary>
       ''' <param name="hWnd">A handle to the window.</param>
       ''' <param name="hWndInsertAfter">A handle to the window to precede the positioned window in the Z order.</param>
       ''' <param name="x">The new position of the left side of the window, in client coordinates.</param>
       ''' <param name="y">The new position of the top of the window, in client coordinates.</param>
       ''' <param name="cx">The new width of the window, in pixels.</param>
       ''' <param name="cy">The new height of the window, in pixels.</param>
       ''' <param name="uFlags">The window sizing and positioning flags.</param>
       ''' <returns><c>true</c> if the function succeeds, <c>false</c> otherwise.</returns>
       <DllImport("user32.dll", SetLastError:=True)> _
       Protected Friend Shared Function SetWindowPos(
                     ByVal hWnd As IntPtr,
                     ByVal hWndInsertAfter As IntPtr,
                     ByVal x As Integer,
                     ByVal y As Integer,
                     ByVal cx As Integer,
                     ByVal cy As Integer,
                     ByVal uFlags As SetWindowPosFlags
           ) As <MarshalAs(UnmanagedType.Bool)> Boolean
       End Function

       ''' <summary>
       ''' Sends the specified message to a window or windows.
       ''' The <see cref="SendMessage"/> function calls the window procedure for the specified window and
       ''' does not return until the window procedure has processed the message.
       ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644950%28v=vs.85%29.aspx
       ''' </summary>
       ''' <param name="hWnd">A handle to the window whose window procedure will receive the message.</param>
       ''' <param name="msg">The windows message to be sent.</param>
       ''' <param name="wParam">Additional message-specific information.</param>
       ''' <param name="lParam">Additional message-specific information.</param>
       ''' <returns>The result of the message processing; it depends on the message sent.</returns>
       <DllImport("user32.dll", SetLastError:=False)>
       Protected Friend Shared Function SendMessage(
                     ByVal hWnd As IntPtr,
                     ByVal msg As WindowsMessages,
                     ByVal wParam As IntPtr,
                     ByVal lParam As IntPtr
           ) As IntPtr
       End Function

#End Region

#Region " Callbacks "

       ''' <summary>
       ''' An application-defined callback function used with the <see cref="EnumThreadWindows"/> function.
       ''' It receives the window handles associated with a thread.
       ''' The WNDENUMPROC type defines a pointer to this callback function.
       ''' <see cref="EnumThreadWndProc"/> is a placeholder for the application-defined function name
       ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633496%28v=vs.85%29.aspx
       ''' </summary>
       ''' <param name="hWnd">A handle to a window associated with the thread specified in the <see cref="EnumThreadWindows"/> function.</param>
       ''' <param name="lParam">The application-defined value given in the <see cref="EnumThreadWindows"/> function.</param>
       ''' <returns>
       ''' To continue enumeration, the callback function must return <c>true</c>;
       ''' To stop enumeration, it must return <c>false</c>.
       ''' </returns>
       Protected Friend Delegate Function EnumThreadWndProc(
                 ByVal hWnd As IntPtr,
                 ByVal lParam As IntPtr
       ) As Boolean

#End Region

#Region " Enumerations "

       ''' <summary>
       ''' Specifies a System-Defined Message.
       ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644927%28v=vs.85%29.aspx#system_defined
       ''' </summary>
       <Description("Enum used for 'SendMessage' function.")>
       Protected Friend Enum WindowsMessages As Integer

           ' **************************************
           ' NOTE:
           ' This enumeration is partially defined.
           ' **************************************

           ''' <summary>
           ''' Sets the font that a control is to use when drawing text.
           ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632642%28v=vs.85%29.aspx
           ''' </summary>
           WM_SETFONT = &H30

           ''' <summary>
           ''' Retrieves the font with which the control is currently drawing its text.
           ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632624%28v=vs.85%29.aspx
           ''' </summary>
           WM_GETFONT = &H31

       End Enum

       ''' <summary>
       ''' Specifies the window sizing and positioning flags.
       ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545%28v=vs.85%29.aspx
       ''' </summary>
       <FlagsAttribute>
       <Description("Enum used for 'SetWindowPos' function.")>
       Protected Friend Enum SetWindowPosFlags As UInteger

           ' **************************************
           ' NOTE:
           ' This enumeration is partially defined.
           ' **************************************

           ''' <summary>
           ''' Indicates any flag.
           ''' </summary>
           None = &H0UI

       End Enum

#End Region

#Region " Structures "

       ''' <summary>
       ''' Defines the coordinates of the upper-left and lower-right corners of a rectangle.
       ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897%28v=vs.85%29.aspx
       ''' </summary>
       <Description("Structure used for 'GetWindowRect' function.")>
       Protected Friend Structure Rect

           ''' <summary>
           ''' The x-coordinate of the upper-left corner of the rectangle.
           ''' </summary>
           Friend Left As Integer

           ''' <summary>
           ''' The y-coordinate of the upper-left corner of the rectangle.
           ''' </summary>
           Friend Top As Integer

           ''' <summary>
           ''' The x-coordinate of the lower-right corner of the rectangle.
           ''' </summary>
           Friend Right As Integer

           ''' <summary>
           ''' The y-coordinate of the lower-right corner of the rectangle.
           ''' </summary>
           Friend Bottom As Integer

       End Structure

#End Region

   End Class

#End Region

#Region " Constructors "

   ''' <summary>
   ''' Initializes a new instance of the <see cref="CenteredMessageBox"/> class.
   ''' </summary>
   ''' <param name="ownerForm">The form that owns this <see cref="CenteredMessageBox"/>.</param>
   ''' <param name="TextFont">The <see cref="Font"/> used to display the text of this <see cref="CenteredMessageBox"/>.</param>
   ''' <param name="TimeOut">
   ''' The time interval to auto-close this <see cref="CenteredMessageBox"/>, in milliseconds;
   ''' Default value is '0', which means Infinite.
   ''' </param>
   Public Sub New(ByVal ownerForm As Form,
                  Optional textFont As Font = Nothing,
                  Optional timeOut As Integer = 0I)

       Me.ownerForm1 = ownerForm
       Me.font1 = textFont
       Me.timeOut1 = timeOut
       Me.ownerForm1.BeginInvoke(New MethodInvoker(AddressOf Me.FindDialog))

   End Sub

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

#End Region

#Region " Private Methods "

   ''' <summary>
   ''' Finds the <see cref="CenteredMessageBox"/> dialog window.
   ''' </summary>
   Private Sub FindDialog()

       ' Enumerate windows to find the message box
       If Me.tries < 0 Then
           Return
       End If

       Dim callback As New NativeMethods.EnumThreadWndProc(AddressOf Me.CheckWindow)

       If NativeMethods.EnumThreadWindows(NativeMethods.GetCurrentThreadId(), callback, IntPtr.Zero) Then

           If Threading.Interlocked.Increment(Me.tries) < 10 Then
               Me.ownerForm1.BeginInvoke(New MethodInvoker(AddressOf Me.FindDialog))
           End If

       End If

       If Me.timeOut1 > 0 Then

           Me.timeoutTimer = New Timer With
                             {
                                 .Interval = Me.timeOut1,
                                 .Enabled = True
                             }

           Me.timeoutTimer.Start()

       End If

   End Sub

   ''' <summary>
   ''' Checks whether the specified window is our <see cref="CenteredMessageBox"/> dialog.
   ''' </summary>
   ''' <param name="hWnd">A handle to the window to check.</param>
   ''' <param name="lParam">The application-defined value given in the <see cref="NativeMethods.EnumThreadWindows"/> function.</param>
   ''' <returns>
   ''' <c>true</c> the specified window is our <see cref="CenteredMessageBox"/> dialog, <c>false</c> otherwise.
   ''' </returns>
   Private Function CheckWindow(ByVal hWnd As IntPtr,
                                ByVal lParam As IntPtr) As Boolean

       ' Checks if <hWnd> is a dialog
       Dim sb As New StringBuilder(260)
       NativeMethods.GetClassName(hWnd, sb, sb.Capacity)
       If sb.ToString() <> "#32770" Then
           Return True
       End If

       ' Get the control that displays the text.
       Dim hText As IntPtr = NativeMethods.GetDlgItem(hWnd, &HFFFFI)
       Me.messageBoxWindowHandle1 = hWnd

       ' Get the dialog Rect.
       Dim frmRect As New Rectangle(Me.ownerForm1.Location, Me.ownerForm1.Size)
       Dim dlgRect As NativeMethods.Rect
       NativeMethods.GetWindowRect(hWnd, dlgRect)

       ' Set the custom Font (if any).
       If hText <> IntPtr.Zero Then

           Me.SetFont(font:=Me.font1,
                      hwnd:=hText,
                      rect:=frmRect)

       End If

       ' Center the dialog window in the specified Form.
       Me.CenterDialog(hwnd:=hWnd,
                       dialogRect:=dlgRect,
                       formRect:=frmRect)

       ' Stop the EnumThreadWndProc callback by sending False.
       Return False

   End Function

   ''' <summary>
   ''' Sets the font of this <see cref="CenteredMessageBox"/> window.
   ''' </summary>
   ''' <param name="font">The <see cref="Font"/> used to display the <see cref="CenteredMessageBox"/> text.</param>
   ''' <param name="hwnd">A handle to the <see cref="CenteredMessageBox"/> window.</param>
   ''' <param name="rect">A <see cref="Rectangle"/> to positionate the text.</param>
   Private Sub SetFont(ByVal font As Font,
                       ByVal hwnd As IntPtr,
                       ByVal rect As Rectangle)

       Select Case font IsNot Nothing

           Case True
               ' Set the text position.
               NativeMethods.SetWindowPos(hWnd:=hwnd,
                                          hWndInsertAfter:=IntPtr.Zero,
                                          x:=65,
                                          y:=35,
                                          cx:=rect.Width,
                                          cy:=font.Height,
                                          uFlags:=NativeMethods.SetWindowPosFlags.None)

               ' Set the new font.
               NativeMethods.SendMessage(hWnd:=hwnd,
                                         msg:=NativeMethods.WindowsMessages.WM_SETFONT,
                                         wParam:=font.ToHfont,
                                         lParam:=New IntPtr(1))

           Case Else
               ' Do Nothing.

               ' Get the dialog font.
               ' dim fnt as Font = Font.FromHfont(NativeMethods.SendMessage(hWnd:=hwnd,
               '                                                            msg:=NativeMethods.WindowsMessages.WM_GETFONT,
               '                                                            wParam:=IntPtr.Zero,
               '                                                            lParam:=IntPtr.Zero))

       End Select

   End Sub

   ''' <summary>
   ''' Centers the <see cref="CenteredMessageBox"/> dialog in the specified <see cref="Form"/>.
   ''' </summary>
   ''' <param name="hwnd">A handle to the <see cref="CenteredMessageBox"/> window.</param>
   ''' <param name="dialogRect">The dialog <see cref="NativeMethods.Rect"/> structure.</param>
   ''' <param name="formRect">The form <see cref="Rectangle"/> structure.</param>
   Private Sub CenterDialog(ByVal hwnd As IntPtr,
                            ByVal dialogRect As NativeMethods.Rect,
                            ByVal formRect As Rectangle)

       ' Resize and positionate the messagebox window.
       NativeMethods.MoveWindow(hwnd,
                                x:=formRect.Left + (formRect.Width - dialogRect.Right + dialogRect.Left) \ 2I,
                                y:=formRect.Top + (formRect.Height - dialogRect.Bottom + dialogRect.Top) \ 2I,
                                width:=(dialogRect.Right - dialogRect.Left),
                                height:=(dialogRect.Bottom - dialogRect.Top),
                                repaint:=True)

   End Sub

#End Region

#Region " Event Handlers "

   ''' <summary>
   ''' Handles the Tick event of the TimeoutTimer control.
   ''' </summary>
   ''' <param name="sender">The source of the event.</param>
   ''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
   Private Sub TimeoutTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) _
   Handles timeoutTimer.Tick

       NativeMethods.DestroyWindow(Me.messageBoxWindowHandle1)
       Me.Dispose()

   End Sub

#End Region

#Region " IDisposable "

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

   ''' <summary>
   ''' Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
   ''' </summary>
   Public Sub Dispose() Implements IDisposable.Dispose

       Me.Dispose(isDisposing:=True)
       GC.SuppressFinalize(obj:=Me)

   End Sub

   ''' <summary>
   ''' Releases unmanaged and - optionally - managed resources.
   ''' </summary>
   ''' <param name="IsDisposing">
   ''' <c>true</c> to release both managed and unmanaged resources;
   ''' <c>false</c> to release only unmanaged resources.
   ''' </param>
   Protected Sub Dispose(ByVal isDisposing As Boolean)

       If Not Me.isDisposed Then

           If isDisposing Then

               Me.tries = -1
               Me.ownerForm1 = Nothing

               If Me.font1 IsNot Nothing Then
                   Me.font1.Dispose()
               End If

           End If

       End If

       Me.isDisposed = True

   End Sub

#End Region

End Class

#End Region