Imports System.IO
Imports System.Xml
Imports System.Xml.Serialization
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.Runtime.CompilerServices

Imports Microsoft.Win32

Imports VB6 = Microsoft.VisualBasic

Module MainModule
    Public Const CrLf As String = VB6.vbCrLf
    Public Const CrLf2 As String = VB6.vbCrLf + VB6.vbCrLf

    Public Function Msg(ByVal message As String, ByVal icon As MessageBoxIcon) As DialogResult
        Return MessageBox.Show(message, Application.ProductName, MessageBoxButtons.OK, icon)
    End Function
End Module

Public Module TextBoxExtensions
    <Extension()> _
    Sub SetCue(ByVal obj As TextBox, ByVal value As String, ByVal hideWhenFocused As Boolean)
        Dim wParam = If(hideWhenFocused, 0, 1)
        Native.SendMessage(obj.Handle, Native.EM_SETCUEBANNER, wParam, value)
    End Sub
End Module

Public Module RegistryKeyExtensions
    <Extension()> _
    Public Function GetValue(Of T)(ByVal rootKey As RegistryKey, ByVal key As String, ByVal name As String) As T
        Using k = rootKey.OpenSubKey(key)
            If Not k Is Nothing Then
                Dim r = k.GetValue(name)

                If Not r Is Nothing Then
                    Return DirectCast(r, T)
                End If
            End If
        End Using
    End Function

    <Extension()> _
    Public Function GetString(ByVal rootKey As RegistryKey, ByVal key As String, ByVal name As String) As String
        Return GetValue(Of String)(rootKey, key, name)
    End Function

    <Extension()> _
    Sub Write(ByVal obj As RegistryKey, ByVal key As String, ByVal name As String, ByVal value As Object)
        Dim k = obj.OpenSubKey(key, True)

        If k Is Nothing Then
            k = obj.CreateSubKey(key, RegistryKeyPermissionCheck.ReadWriteSubTree)
        End If

        k.SetValue(name, value)
        k.Close()
    End Sub

    <Extension()> _
    Public Sub Destroy(ByVal rootKey As RegistryKey, ByVal key As String)
        Dim k = rootKey.OpenSubKey(key)

        If Not k Is Nothing Then
            Dim names = k.GetSubKeyNames
            k.Close()

            For Each i In names
                Destroy(rootKey, key + "\" + i)
            Next

            rootKey.DeleteSubKey(key, True)
        End If
    End Sub
End Module

Public Class Native
    Public Const SHCNE_ASSOCCHANGED As Integer = &H8000000
    Public Const SHCNF_IDLIST As Integer = &H0
    Public Const EM_SETCUEBANNER As Integer = &H1501

    <DllImport("shell32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Friend Shared Sub SHChangeNotify(ByVal wEventId As UInt32, ByVal uFlags As UInt32, ByVal dwItem1 As IntPtr, ByVal dwItem2 As IntPtr)
    End Sub

    <DllImport("uxtheme.dll", CharSet:=CharSet.Unicode)> _
    Shared Function SetWindowTheme(ByVal hWnd As IntPtr, ByVal pszSubAppName As String, ByVal pszSubIdList As String) As Integer
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Unicode)> _
    Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As Integer, <MarshalAs(UnmanagedType.LPWStr)> ByVal lParam As String) As IntPtr
    End Function
End Class

Public Class FileAssociation
    Public Shared Sub Create(ByVal executable As String, ByVal extension As String, ByVal parameter As String)
        If Not extension.StartsWith(".") Then
            extension = "." + extension
        End If

        Dim name = Application.ProductName.Replace(" ", "") + extension

        Registry.ClassesRoot.Write(extension, Nothing, name)
        Registry.ClassesRoot.Destroy(name)
        Registry.ClassesRoot.Write(name + "\DefaultIcon", Nothing, executable + ",0")
        Registry.ClassesRoot.Write(name + "\shell\open\command", Nothing, """" + executable + """ " + parameter)
        Registry.CurrentUser.Destroy("Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" + extension + "\UserChoice")
        Registry.CurrentUser.Write("Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" + extension + "\UserChoice", "Progid", name)
    End Sub

    Public Shared Sub RefreshIconCache()
        Native.SHChangeNotify(Native.SHCNE_ASSOCCHANGED, Native.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero)
    End Sub
End Class

Public Class Item
    Public Name As String
    Public Filepath As String
    Public Company As String
    Public Image As Image
End Class