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

#6051
Ejemplo de cómo utilizar la librería SharpShell para crear una shell-extensión, un menú contextual para nuestra aplicación: https://sharpshell.codeplex.com



La imagen de arriba no hace referencia al siguiente ejemplo, mi menú tiene la siguiente estructura:

· Título
        (Sub-menu)
        · Run
        · Open Files...


Código (vbnet) [Seleccionar]

#Region " Option Statements "

Option Strict On
Option Explicit On
Option Infer Off

#End Region

#Region " Imports "

Imports SharpShell.Attributes
Imports SharpShell.SharpContextMenu
Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.Windows.Forms
Imports System.ComponentModel

#End Region

#Region " MyAppContextMenu "

''' <summary>
''' The Application Context Menu Extension.
''' </summary>
<ComVisible(True)>
<COMServerAssociation(AssociationType.ClassOfExtension, ".ext")>
Public Class MyAppContextMenu : Inherits SharpContextMenu

#Region " Objects "

   ''' <summary>
   ''' Contains the application information.
   ''' </summary>
   Private ReadOnly application As New AppInfo With
           {
               .Title = "Menu Title",
               .Filename = "Application Filename",
               .Directory = My.Application.Info.DirectoryPath
           }

#End Region

#Region " Types "

   ''' <summary>
   ''' Contains information about an application.
   ''' This class cannot be inherited.
   ''' </summary>
   Protected NotInheritable Class AppInfo

       ''' <summary>
       ''' Gets or sets the application title.
       ''' </summary>
       ''' <value>The application title.</value>
       Protected Friend Property Title As String

       ''' <summary>
       ''' Gets or sets the application filename.
       ''' </summary>
       ''' <value>The application filename.</value>
       Protected Friend Property Filename As String

       ''' <summary>
       ''' Gets or sets the application working directory.
       ''' </summary>
       ''' <value>The application working directory.</value>
       Protected Friend Property Directory As String

       ''' <summary>
       ''' Gets the full qualified application path.
       ''' </summary>
       ''' <value>The full qualified application path.</value>
       Protected Friend ReadOnly Property FullPath As String
           Get
               Return Path.Combine(Me.Directory, Me.Filename, ".exe")
           End Get
       End Property

   End Class

#End Region

#Region " SharpShell Methods "

   ''' <summary>
   ''' Determines whether this instance can a shell context show menu, given the specified selected file list.
   ''' </summary>
   ''' <returns>
   ''' <c>true</c> if this instance should show a shell context menu for the specified file list; otherwise, <c>false</c>.
   ''' </returns>
   Protected Overrides Function CanShowMenu() As Boolean

       Return True

   End Function

   ''' <summary>
   ''' Creates the context menu.
   ''' </summary>
   ''' <returns>The context menu for the shell context menu.</returns>
   Protected Overrides Function CreateMenu() As ContextMenuStrip

       ' Create the menu strip.
       Dim menu As New ContextMenuStrip()

       ' Create the main item, this is used to show our application title.
       Dim itemTitle As New ToolStripMenuItem() With
           {
               .Text = Me.application.Title,
               .Image = My.Resources.TitleIcon
           }

       ' Create a 'Run' item.
       Dim itemRun As New ToolStripMenuItem() With
           {
               .Text = "Run",
               .Image = My.Resources.RunIcon
           }

       ' Create a 'Open file' item.
       Dim itemOpenFile As New ToolStripMenuItem() With
           {
               .Text = "Open file...",
               .Image = My.Resources.OpenFileIcon
           }

       ' Create a 'Open files' item.
       Dim itemOpenFiles As New ToolStripMenuItem() With
           {
               .Text = "Open files...",
               .Image = My.Resources.OpenFileIcon
           }

       ' Add the main item into the context menu.
       menu.Items.Add(itemTitle)

       ' Add the 'Run' sub-item into the 'itemTitle' item.
       itemTitle.DropDownItems.Add(itemRun)

       ' Add the 'Open file' or 'Open files' sub-item into the 'itemTitle' item.
       ' Depending on the amount of selected files.
       itemTitle.DropDownItems.Add(If(Me.SelectedItemPaths.Count = 1, itemOpenFile, itemOpenFiles))

       ' Suscribe to events.
       AddHandler itemRun.Click, AddressOf ItemRun_Click
       AddHandler itemOpenFile.Click, AddressOf ItemOpenFile_Click
       AddHandler itemOpenFiles.Click, AddressOf ItemOpenFiles_Click

       ' Return the menu.
       Return menu

   End Function

#End Region

#Region " Application Methods "

   ''' <summary>
   ''' Runs the specified application.
   ''' </summary>
   ''' <param name="fileName">The name of an application file to run in the process.</param>
   ''' <param name="arguments">Command-line arguments to pass when starting the process.</param>
   Private Sub RunApp(ByVal fileName As String,
                      Optional ByVal arguments As String = "")

       Try
           Process.Start(fileName, arguments)

       Catch ex As FileNotFoundException
           ' Do something.

       Catch ex As InvalidOperationException
           ' Do something.

       Catch ex As Win32Exception
           ' Dim errorCode As Integer = Marshal.GetLastWin32Error()
           ' Do something.

       Catch ex As Exception
           ' Do something.

       End Try

   End Sub

   ''' <summary>
   ''' Opens the given file in the specified application.
   ''' </summary>
   ''' <param name="appPath">The application filepath to run.</param>
   ''' <param name="filepath">The filepath to send to the application arguments.</param>
   ''' <param name="stringFormat">The string format used to format the filepath.</param>
   Private Sub OpenFile(ByVal appPath As String,
                        ByVal filepath As String,
                        Optional ByVal stringFormat As String = """{0}""")

       Me.RunApp(appPath, String.Format(stringFormat, filepath))

   End Sub

   ''' <summary>
   ''' Opens the given files in the specified application.
   ''' </summary>
   ''' <param name="appPath">The application filepath to run.</param>
   ''' <param name="filepaths">The filepaths to send to the application arguments.</param>
   ''' <param name="stringFormat">The string format used to join the filepaths.</param>
   Private Sub OpenFiles(ByVal appPath As String,
                         ByVal filepaths As IEnumerable(Of String),
                         Optional ByVal stringFormat As String = """{0}"" ")

       Me.RunApp(fileName:=appPath,
                 arguments:=Me.JoinFilePaths(filepaths, stringFormat))

   End Sub

   ''' <summary>
   ''' Joins the selected filepaths in a single line, filepaths are closed with double-quotes and separated by a space.
   ''' eg: "File1" "File2" "File3"
   ''' </summary>
   ''' <param name="filepaths">The filepaths to join.</param>
   ''' <param name="joinFormat">The string format used to join the filepaths.</param>
   ''' <returns>The joined and formatted filepaths.</returns>
   Private Function JoinFilePaths(ByVal filepaths As IEnumerable(Of String),
                                  ByVal joinFormat As String) As String

       Dim sb As New StringBuilder()

       For Each filePath As String In filepaths
           sb.Append(String.Format(joinFormat, filePath))
       Next filePath

       Return sb.ToString

   End Function

#End Region

#Region " Event Handlers "

   ''' <summary>
   ''' Handles the Click event of the ItemRun menu item.
   ''' </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 ItemRun_Click(ByVal sender As Object, ByVal e As EventArgs)

       Me.RunApp(fileName:=Me.application.FullPath)

   End Sub

   ''' <summary>
   ''' Handles the Click event of the ItemOpenFile menu item.
   ''' </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 ItemOpenFile_Click(ByVal sender As Object, ByVal e As EventArgs)

       Me.OpenFile(appPath:=Me.application.FullPath,
                   filepath:=Me.SelectedItemPaths.First)

   End Sub

   ''' <summary>
   ''' Handles the Click event of the ItemOpenFiles menu item.
   ''' </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 ItemOpenFiles_Click(ByVal sender As Object, ByVal e As EventArgs)

       Me.OpenFiles(appPath:=Me.application.FullPath,
                    filepaths:=Me.SelectedItemPaths)

   End Sub

#End Region

End Class

#End Region


#6052
Una actualización de este ayudante para "renombrar" o capitalizar un String, dándole el formato deseado.

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

#Region " Option Statements "

Option Explicit On
Option Strict On
Option Infer Off

#End Region

#Region " Usage Examples "

' MsgBox(StringRenamer.Rename("Hello World!", StringRenamer.FormatCase.Upper))
' MsgBox(StringRenamer.Rename("Hello World!", StringRenamer.FormatCase.Upper, "\s+", "-", System.Text.RegularExpressions.RegexOptions.None))

#End Region

#Region " Imports "

Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Globalization

#End Region

#Region " String Renamer "

''' <summary>
''' Renames a string.
''' </summary>
Public NotInheritable Class StringRenamer

#Region " Enumerations "

    ''' <summary>
    ''' Specifies a string format case.
    ''' </summary>
    Public Enum FormatCase As Integer

        ''' <summary>
        ''' LowerCase
        '''
        ''' [Example]
        ''' Input : ABCDEF
        ''' Output: abcdef
        ''' </summary>
        Lower = &H0

        ''' <summary>
        ''' UpperCase.
        '''
        ''' [Example]
        ''' Input : abcdef
        ''' Output: ABCDEF
        ''' </summary>
        Upper = &H1

        ''' <summary>
        ''' TitleCase.
        '''
        ''' [Example]
        ''' Input : abcdef
        ''' Output: Abcdef
        ''' </summary>
        Title = &H2

        ''' <summary>
        ''' WordCase.
        '''
        ''' [Example]
        ''' Input : abc def
        ''' Output: Abc Def
        ''' </summary>
        Word = &H3

        ''' <summary>
        ''' CamelCase (With first letter to LowerCase).
        '''
        ''' [Example]
        ''' Input : ABC DEF
        ''' Output: abcDef
        ''' </summary>
        CamelLower = &H4

        ''' <summary>
        ''' CamelCase (With first letter to UpperCase).
        '''
        ''' [Example]
        ''' Input : ABC DEF
        ''' Output: AbcDef
        ''' </summary>
        CamelUpper = &H5

        ''' <summary>
        ''' MixedCase (With first letter to LowerCase).
        '''
        ''' [Example]
        ''' Input : ab cd ef
        ''' Output: aB Cd eF
        ''' </summary>
        MixedTitleLower = &H6

        ''' <summary>
        ''' MixedCase (With first letter to UpperCase).
        '''
        ''' [Example]
        ''' Input : ab cd ef
        ''' Output: Ab cD Ef
        ''' </summary>
        MixedTitleUpper = &H7

        ''' <summary>
        ''' MixedCase (With first letter of each word to LowerCase).
        '''
        ''' [Example]
        ''' Input : ab cd ef
        ''' Output: aB cD eF
        ''' </summary>
        MixedWordLower = &H8

        ''' <summary>
        ''' MixedCase (With first letter of each word to UpperCase).
        '''
        ''' [Example]
        ''' Input : ab cd ef
        ''' Output: Ab Cd Ef
        ''' </summary>
        MixedWordUpper = &H9

        ''' <summary>
        ''' ToggleCase.
        '''
        ''' [Example]
        ''' Input : abc def ghi
        ''' Output: aBC dEF gHI
        ''' </summary>
        Toggle = &H10

        ''' <summary>
        ''' Duplicates the characters.
        '''
        ''' [Example]
        ''' Input : Hello World!
        ''' Output: HHeelllloo  WWoorrlldd!!
        ''' </summary>
        Duplicated = &H11

        ''' <summary>
        ''' Inverts the characters.
        '''
        ''' [Example]
        ''' Input : Hello World!
        ''' Output: hELLO wORLD!
        ''' </summary>
        Inverted = &H12

    End Enum

#End Region

#Region " Publix Methods "

#End Region

    ''' <summary>
    ''' Renames a string to the specified StringCase.
    ''' </summary>
    ''' <param name="str">The string to rename.</param>
    ''' <param name="fCase">The format case.</param>
    ''' <returns>The renamed string.</returns>
    Public Shared Function Rename(ByVal str As String,
                                  ByVal fCase As FormatCase) As String

        Select Case fCase

            Case FormatCase.Lower
                Return str.ToLower

            Case FormatCase.Upper
                Return str.ToUpper

            Case FormatCase.Title
                Return Char.ToUpper(str.First) & str.Substring(1).ToLower

            Case FormatCase.Word
                Return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(str.ToLower)

            Case FormatCase.CamelLower
                Return Char.ToLower(str.First) &
                       CultureInfo.InvariantCulture.TextInfo.ToTitleCase(str.ToLower).
                       Replace(" "c, String.Empty).
                       Substring(1)

            Case FormatCase.CamelUpper
                Return Char.ToUpper(str.First) &
                       CultureInfo.InvariantCulture.TextInfo.ToTitleCase(str.ToLower).
                       Replace(" "c, String.Empty).
                       Substring(1)

            Case FormatCase.MixedTitleLower
                Dim sb As New StringBuilder
                For i As Integer = 0 To (str.Length - 1) Step 2
                    If Not (i + 1) >= str.Length Then
                        sb.Append(Char.ToLower(str(i)) & Char.ToUpper(str(i + 1)))
                    Else
                        sb.Append(Char.ToLower(str(i)))
                    End If
                Next i
                Return sb.ToString

            Case FormatCase.MixedTitleUpper
                Dim sb As New StringBuilder
                For i As Integer = 0 To (str.Length - 1) Step 2
                    If Not (i + 1) >= str.Length Then
                        sb.Append(Char.ToUpper(str(i)) & Char.ToLower(str(i + 1)))
                    Else
                        sb.Append(Char.ToUpper(str(i)))
                    End If
                Next i
                Return sb.ToString

            Case FormatCase.MixedWordLower
                Dim sb As New StringBuilder
                For Each token As String In str.Split
                    sb.Append(StringRenamer.Rename(token, FormatCase.MixedTitleLower) & " ")
                Next token
                Return sb.ToString

            Case FormatCase.MixedWordUpper
                Dim sb As New StringBuilder
                For Each token As String In str.Split
                    sb.Append(StringRenamer.Rename(token, FormatCase.MixedTitleUpper) & " ")
                Next token
                Return sb.ToString

            Case FormatCase.Toggle
                Dim sb As New StringBuilder
                For Each token As String In str.Split
                    sb.Append(Char.ToLower(token.First) & token.Substring(1).ToUpper & " ")
                Next token
                Return sb.ToString

            Case FormatCase.Duplicated
                Dim sb As New StringBuilder
                For Each c As Char In str
                    sb.Append(New String(c, 2))
                Next c
                Return sb.ToString

            Case FormatCase.Inverted
                Dim sb As New StringBuilder
                For Each c As Char In str
                    sb.Append(If(Char.IsLower(c),
                                 Char.ToUpper(c),
                                 Char.ToLower(c)))
                Next c
                Return sb.ToString

            Case Else
                Return str

        End Select

    End Function

    ''' <summary>
    ''' Rename a string to the specified StringCase,
    ''' Also finds and replaces text after the string is renamed.
    ''' </summary>
    ''' <param name="str">The string to rename.</param>
    ''' <param name="fCase">The format case.</param>
    ''' <param name="FindWhat">The RegEx pattern to match.</param>
    ''' <param name="ReplaceWith">The replacement string.</param>
    ''' <param name="regexOptions">The RegEx options.</param>
    ''' <returns>The renamed string.</returns>
    Public Shared Function Rename(ByVal str As String,
                                  ByVal fCase As FormatCase,
                                  ByVal findWhat As String,
                                  ByVal replaceWith As String,
                                  ByVal regexOptions As RegexOptions) As String

        Return Regex.Replace(StringRenamer.Rename(str, fCase),
                             findWhat,
                             replaceWith,
                             regexOptions)

    End Function

End Class

#End Region





Ejemplo de como filtrar las extensiones mostradas en un FolderView control, de la librería shell mega pack: http://www.ssware.com/fldrview.htm



Código (vbnet) [Seleccionar]

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

            ' This event occurs when node is expanded.

            If e.Node.HasExpandedOnce Then
                Exit Sub
            End If

            Me.FilterNodeFiles(folderView:=DirectCast(sender, FolderView),
                               allowedExtensions:=".mp3".ToLower.Split)

        End Sub

        ''' <summary>
        ''' Handles the BeforeNodeSort event of the FolderView1 control.
        ''' </summary>
        ''' <param name="sender">The source of the event.</param>
        ''' <param name="e">The <see cref="BeforeNodeSortEventArgs"/> instance containing the event data.</param>
        Private Sub FolderView1_BeforeNodeSort(sender As Object, e As BeforeNodeSortEventArgs) _
        Handles FolderView1.BeforeNodeSort

            ' This event occurs when a file is created/moved/pasted inside a node.

            Me.FilterNodeFiles(folderView:=DirectCast(sender, FolderView),
                               allowedExtensions:=".mp3".ToLower.Split)

        End Sub

        ''' <summary>
        ''' Filters the files that can be shown in the TreeNodes of a <see cref="FolderView"/>.
        ''' </summary>
        ''' <param name="folderView">The <see cref="FolderView"/>.</param>
        ''' <param name="allowedExtensions">The allowed file extensions.</param>
        Private Sub FilterNodeFiles(ByVal folderView As FolderView, ByVal allowedExtensions() As String)

            For Each node As FOVTreeNode In folderView.Nodes.Cast(Of FOVTreeNode).Reverse

                If Not (node.IsFolder) _
                AndAlso Not (allowedExtensions.Contains(IO.Path.GetExtension(node.Text).ToLower)) Then

                    node.Delete()

                End If

            Next node

        End Sub





Una actualización de este ayudante de la librería TagLibSharp, para la edición de metadats de archivos de audio, ese wrapper está orientado al manejo de archivos MP3 solamente.

Código (vbnet) [Seleccionar]

' ***********************************************************************
' Author   : Elektro
' Modified : 29-Novembder-2014
' ***********************************************************************
' <copyright file="TagLibSharp Helper.vb" company="Elektro Studios">
'     Copyright (c) Elektro Studios. All rights reserved.
' </copyright>
' ***********************************************************************

#Region " Usage Examples "

'Dim tagger As New TagLibSharpHelper
'tagger.LoadFile("C:\Users\Administrador\Desktop\1.mp3")

'Dim sb As New System.Text.StringBuilder
'With sb
'    .AppendLine(String.Format("Is Corrupt?: {0}", tagger.IsCorrupt))
'    .AppendLine(String.Format("Is Writeable?: {0}", tagger.IsWriteable))
'    .AppendLine()
'    .AppendLine(String.Format("Tags: {0}", tagger.GetTags))
'    .AppendLine()
'    .AppendLine(String.Format("Title: {0}", tagger.GetTitle))
'    .AppendLine(String.Format("Artist: {0}", tagger.GetArtist))
'    .AppendLine(String.Format("Album: {0}", tagger.GetAlbum))
'    .AppendLine(String.Format("Genre: {0}", tagger.GetGenre))
'    .AppendLine(String.Format("Year: {0}", tagger.GetYear))
'End With
'MessageBox.Show(sb.ToString)

'tagger.RemoveTag(TagLib.TagTypes.Id3v1 Or TagLib.TagTypes.Id3v2) ' Removes ID3v1 + ID3v2 Tags

'tagger.SetTag(Sub(x As TagLib.File) x.Tag.Title = "Title Test")

'tagger.SetTags({Sub(x As TagLib.File) x.Tag.Title = "Title Test",
'                Sub(x As TagLib.File) x.Tag.Performers = {"My Artist"}})

#End Region

#Region " Option Statements "

Option Strict On
Option Explicit On
Option Infer Off

#End Region

#Region " Imports "

Imports TagLib

#End Region

#Region " TagLibSharp Helper "

Public NotInheritable Class TagLibSharpHelper

#Region " Properties "

    ''' <summary>
    ''' Gets or sets the <see cref="TagLib.File"/> object.
    ''' </summary>
    ''' <value>The <see cref="TagLib.File"/> object.</value>
    Private Property TagFile As TagLib.File

    Public ReadOnly Property CurrentFile As String
        Get
            Return Me.TagFile.Name
        End Get
    End Property

#End Region

#Region " Constructors "

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

    ''' <summary>
    ''' Initializes a new instance of the <see cref="TagLibSharpHelper" /> class.
    ''' </summary>
    ''' <param name="file">The file to load.</param>
    Public Sub New(ByVal file As String)
        Me.LoadFile(file)
    End Sub

#End Region

#Region " Public Methods "

    ''' <summary>
    ''' Instances a file.
    ''' </summary>
    ''' <param name="file">The file to load.</param>
    Public Sub LoadFile(ByVal file As String)

        Try
            Me.TagFile = TagLib.File.Create(file)

        Catch ex As CorruptFileException
            Throw

        Catch ex As UnsupportedFormatException
            Throw

        Catch ex As Exception
            Throw

        End Try

    End Sub

    ''' <summary>
    ''' Determines whether the current file is possibly corrupted.
    ''' </summary>
    Public Function IsCorrupt() As Boolean

        Me.CheckTagFile()
        Return Me.TagFile.PossiblyCorrupt

    End Function

    ''' <summary>
    ''' Determines whether the current file can be written.
    ''' </summary>
    Public Function IsWriteable() As Boolean

        Me.CheckTagFile()
        Return Me.TagFile.Writeable

    End Function

    ''' <summary>
    ''' Get TagTypes of file.
    ''' </summary>
    Public Function GetTags() As String

        Me.CheckTagFile()
        Return Me.TagFile.TagTypesOnDisk.ToString

    End Function

    ''' <summary>
    ''' Gets the Title tag of the current file.
    ''' </summary>
    Public Function GetTitle() As String

        Me.CheckTagFile()
        Return Me.TagFile.Tag.Title

    End Function

    ''' <summary>
    ''' Gets the Artist tag of the current file.
    ''' </summary>
    Public Function GetArtist() As String

        Me.CheckTagFile()

        If Me.TagFile.Tag.Performers.Count <> 0 Then
            Return Me.TagFile.Tag.Performers(0)

        Else
            Return String.Empty

        End If

    End Function

    ''' <summary>
    ''' Gets the Album tag of the current file.
    ''' </summary>
    Public Function GetAlbum() As String

        Me.CheckTagFile()
        Return Me.TagFile.Tag.Album

    End Function

    ''' <summary>
    ''' Gets the Genre tag of the current file.
    ''' </summary>
    Public Function GetGenre() As String

        Me.CheckTagFile()
        If Me.TagFile.Tag.Genres.Count <> 0 Then
            Return Me.TagFile.Tag.Genres(0)

        Else
            Return String.Empty

        End If

    End Function

    ''' <summary>
    ''' Gets the Year tag of the current file.
    ''' </summary>
    Public Function GetYear() As String

        Me.CheckTagFile()
        Return Me.TagFile.Tag.Year.ToString

    End Function

    ''' <summary>
    ''' Sets a Tag field.
    ''' </summary>
    Public Sub SetTag(ByVal fieldSetter As Action(Of TagLib.File))

        Me.CheckTagFile()
        If Not Me.IsCorrupt AndAlso Me.IsWriteable Then

            Try
                fieldSetter(TagFile)

            Catch ex As Exception
                Throw

            End Try

            Me.SaveFile()

        End If

    End Sub

    ''' <summary>
    ''' Sets multiple Tag fields.
    ''' </summary>
    Public Sub SetTags(ByVal fieldSetter() As Action(Of TagLib.File))

        Me.CheckTagFile()
        If Not Me.IsCorrupt AndAlso Me.IsWriteable Then

            For Each field As Action(Of TagLib.File) In fieldSetter

                Try
                    field(TagFile)

                Catch ex As Exception
                    Throw

                End Try

            Next field

            Me.SaveFile()

        End If

    End Sub

    ''' <summary>
    ''' Remove a Tag from the current file.
    ''' </summary>
    ''' <param name="tagTypes">The tag types to remove from file.</param>
    Public Sub RemoveTag(ByVal tagTypes As TagTypes)

        Me.CheckTagFile()
        If Not Me.IsCorrupt AndAlso Me.IsWriteable Then

            Try
                Me.TagFile.RemoveTags(tagTypes)

            Catch ex As Exception
                Throw

            End Try

            Me.SaveFile()

        End If

    End Sub

#End Region

#Region " Private Methods "

    ''' <summary>
    ''' Saves the current file.
    ''' </summary>
    Private Sub SaveFile()

        Me.CheckTagFile()

        Try
            Me.TagFile.Save()

        Catch ex As Exception
            Throw

        End Try

    End Sub

    ''' <summary>
    ''' Checks whether a <see cref="TagLib.File"/> object is loaded.
    ''' </summary>
    Private Sub CheckTagFile()

        If Me.TagFile Is Nothing Then

            Throw New Exception("Any file is loaded.")

        End If

    End Sub

#End Region

End Class

#End Region





Ejemplo (...un poco cutre por el momento) de cmo utilizar un KryptonSeparator, del set de controles Krypton: http://www.componentfactory.com/toolkit_utilitycontrols.php



Código (vbnet) [Seleccionar]

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

            Dim separator As KryptonSeparator = DirectCast(sender, KryptonSeparator)
            Dim leftCtrl As Control = Me.ListBox1
            Dim rightCtrl As Control = Me.ListBox2

            If (e.MouseCursorX > 0) _
            AndAlso Not ((rightCtrl.Size.Width - e.MouseCursorX) < rightCtrl.MinimumSize.Width) Then

                separator.Location = New Point(separator.Location.X + e.MouseCursorX, separator.Location.Y)
                leftCtrl.Width += e.MouseCursorX
                rightCtrl.Width -= e.MouseCursorX
                rightCtrl.Left = separator.Right

            ElseIf (e.MouseCursorX < 0) _
            AndAlso Not ((leftCtrl.Size.Width + e.MouseCursorX - separator.Width) < leftCtrl.MinimumSize.Width) Then

                separator.Location = New Point(separator.Location.X - separator.Width, separator.Location.Y)
                leftCtrl.Width -= separator.Width
                rightCtrl.Width += separator.Width
                rightCtrl.Left = separator.Right

            End If

        End Sub
#6053
1) Estoy de acuerdo en que se haga una sección donde se pueda ayudar en la utilización de aplicaciones como: "Unity, UDK, CryEngine, Flash, GameMaker, etc" para el desarrollo de juegos.
Cómo podría ser la sección de Diseño Grafico, donde más que nada se formulan dudas de la utilización de Photoshop, o al menos eso es lo que siempre vi allí.

2) Por otro lado es algo que entra en conflicto con mis ideas, ya que en mi opinión los subforos de programación deben clasificarse según lenguajes de programación, no según temáticas de software/programación ni mucho menos aplicaciones, la razón es simple, temáticas hay miles y entre otras cosas no dariamos a basto para el mantenimiento, por no decir que algunas temáticas llegarían a tener con suerte solamente 1 mensaje publicado.

Aparte de esto, la programación de juegos no se queda en la utilización de esas aplicaciones, sino en los lenguajes que se han de utilizar para elaborar las entrañas del juego, bien lo sabes, al menos en Unity pude comprobar que se debe recurrir a lenguajes como C#, Python, etc. Ya existe un subforo para cada uno de los lenguajes de programación más usados hoy en dia.

Cita de: Ikillnukes en 29 Noviembre 2014, 11:31 AMYo creo que los posibles usuarios que estén aquí y que estén haciendo algo relacionado con programación de juegos no han preguntado nada, por la posible ausencia de un subforo dedicado a dicha temática.
Crees erroneamente, ya que los usuarios formulan sus preguntas de la temática que sea donde corresponde, es decir, en el subforo del lenguaje que estén utilizando.
Cómo sabes modero tres secciones de programación, y puedo decir que si, he visto varias preguntas relacionadas con la programación de juegos, de hecho hay una duda muy reciente sobre la programación de juegos en Python.

Saludos!
#6054
He reproducido las circunstancias del problema que describes, para ello he desarrollado una mini-aplicación CommandLine que simplemente genera el mismo string con los caracteres ilegales "<" ">", pero a mi me funciona correctamente el commando de redirección que a ti al parecer no te funciona.

De todas formas, prueba a usar la sintaxis más adecuada:
("fastboot.exe" oem get_unlock_data)1>> ".\FastbootCodigo.txt"

Si eso no te funciona entonces quizás lo más probable es que la aplicación no esté enviando los datos a la salida estándar, así que prueba a redirigir la salida de error:
("fastboot.exe" oem get_unlock_data)2>> ".\FastbootCodigo.txt"

Saludos.
#6055
Para llamarse Microsoft se han currado muy pero que muy poco la interfaz de usuario de dicha característica que obligan a la utilización e interfaz de PS para el proceso de descarga e instalación, pf, los newbies no sabrán ni localizar PS ni ponerse a escribir las instrucciones necesarias en la consola para descargar paquetes sin una GUI "pa tontos", hacer las cosas de esa manera no es nada propio de Microsoft, y luego está lo de Windows "10".

Saludos!
#6056
Bueno, visto que no quieres acudir a quien deberías acudir y prefieres hacer de detective por ti mismo, te cuento:

Puedes probar con distintos servicios online tanto gratis como de pago que recopilan bases de datos de teléfonos móvil, no te costará nada encontrar estos servicios en Google, obviamente los servicios de pago te darían mayores posibilidades de éxito en tu búsqueda, este método de búsqueda se denomina Reverse Phone Lookup, pero te advierto que es un método muy ineficaz debido a que que cada día miles de personas renuevan/tiran o se compran un mvl y suelen ser servicios que obtienen los datos desde muchas y diferentes bases de datos (ya que no existe una MEGA-db pública donde se recopile la información de todos los telfs de La Tierra, bueno, quizás la CIA, jaja, aunque eso sería privado, claro...), de todas formas es el único medio público de localización que puede usar una persona "normal" (al menos que yo sepa), a menos que acudas a la policia o a un detective privado (no tienes excusa para eso, jeje :P).

Saludos
#6057
Cita de: DefaultUser en 28 Noviembre 2014, 04:38 AM
necesito localizar a alguien que me llama amenazando de muerte y dice que me va a matar...

dice ser el tio de mi novia...
dice que no es de Buenos Aires...
Dice que tiene el 54 por que es de una empresa...
el dice ser de Salta

Para querer matarte parece que está intimando bastante xD

Cita de: DefaultUser en 28 Noviembre 2014, 04:38 AM((En su numero cuando llama aparece que es de Buenos Aires, por el 54, pero me dice que no, ¿puede estar mintiendome?))

¿Es que cabe la duda de que un individuo que te llama para decir sandeces te pueda mentir?.

Ahora en serio, disculpa que me lo tome a broma, pero si a mi me llama un desconocido desde otro país y me amenaza de muerte lo más seguro es que se esté burlando de mi y no tenga el valor necesario para burlarse cara a cara, ¿en serio crees que merece la importancia que le estás dando al asunto?, según la información que has proporcionado al explicar el "incidente" yo no creo que tu vida corra peligro.

Si temes por tu vida entonces llama a la policia, si es que no entiendo este tipo de posts... ¿por qué no acudes a la policia para que ellos se encarguen de rastrear al presunto asesino si lo consideran necesario?.

Saludos!
#6058
Cita de: MCKSys Argentina en 28 Noviembre 2014, 01:08 AMAgregar programas es tan sencillo como instalarlos.
No existe otra posible respuesta, jajaja.

Cita de: RIKO en 28 Noviembre 2014, 00:42 AMQuien me enseña a ... o modificar uno que ya esta hecho?
Si por "modificar" te refieres a modificar el comportamiento/funcionamiento de una aplicación sin tener acceso al código fuente entonces creo que no sabes donde te estás adentrando, te espera un largo aprendizaje por el camino de la Ingeniería Inversa, en el foro tienes una sección dedicada al tema si te decides, pero no esperes que nadie te enseñe a "como modificar un programa" y menos de la noche a la mañana... como mucho te pueden recomendar libros y largas lecturas que debes aprender y entender, y por supuesto también te ayudarán donde te quedes atascado.

Saludos!
#6059
Ay señor...

No soy para nada ningún experto en el diseño de Malware pero en mi opinión dudo muchísimo que eso pudiese ocurrir solamente por utilizar TeamViewer, ¿que el virus se envie por si solo en algún paquete de los que estas recibiendo por parte de TeamViewer y se auto-ejecute en tu equipo?, ni que esto fuera el tan explotado eMule u otro peer2peer para la propagación de virus, Teamviewer es un programa profesional y con sus medidas de seguridad implementadas bajo una conexión "segura".

Si me dijeras que TeamViewer crease una conexión a un equipo remoto en el PC donde te conectas (cosa que no hace), y ese individuo estuviese infectado con un virus que tuviese un spread implementado capaz de propagarse remotamente buscando conexiones de equipos remotos instalados, entonces vale, pero 1 de cada 1.000.000 de virus deben ser así de eficientes (por decir un número aleatorio bajo mi percepción, vaya).

Quizás me he equivocado en algún concepto de lo que he mencionado ya que como he dicho no soy experto en Malware, desconozco realmente si un virus puede propagarse mediante una conexión establecida entre 2 clientes de TeamViewer, pero nunca he escuchado ese caso, demasiadas preocupaciones teneis... de verdad, DEMASIADAS.

Además, los AntiVirus están para algo.

Saludos!

#6060
Un MessageBox no es más que un diálogo, y como tal puedes hallar el handle (hwnd) de su ventana principal, redimensionar la ventana y enumerar sus controles para quizás hacer lo mismo y dejar espacio para tu nuevo control, por ende puedes posicionar "X" control relativamente en el rectangle de dicho dialog.

Pero esa idea es una locura, lo mejor es que hagas un nuevo Form y lo personalices de forma manual con el aspecto típico de un MessageBox (hay muchos ejemplos en Google) y allí añadas los controles que desees, y luego utilices ese Form como un Dialog, ya que un MessageBox puede ser cambiado o extendido, sí, pero es una pesadilla ya que requiere bastante esfuerzo y mucho P/Invoking para realizar pequeñas modificaciones, de todas formas te muestro un ejemplo que desarrollé donde deberías poder encontrar todo lo necesario para tus intenciones, pero como ya dije, no te recomiendo este enfoque para tus necesidades:

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.Bold),
'                             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 "

Namespace Tools

   ''' <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.Unicode)>
           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 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 Namespace

#End Region