SHAutoCompleteを使うと、テキスト入力部を持つコントロールにURLのオートコンプリート機能を付けることができる。 SHAutoCompleteにオートコンプリート機能を持たせたいコントロールのハンドルと動作を決めるフラグを渡すだけでオートコンプリート機能が有効になる。 ただし、ComboBoxの場合はこの方法ではうまく動作しないので、ここではComboBoxコントロールにURLのオートコンプリート機能を付ける方法を紹介する。
''' <summary>
''' オートコンプリート機能を持ったコンボボックス
''' </summary>
Public Class AutoCompleteComboBox
Inherits System.Windows.Forms.ComboBox
<DllImport("user32.dll")> _
Private Shared Function FindWindowEx( _
ByVal hWndParent As IntPtr, _
ByVal hwndChildAfter As IntPtr, _
ByVal lpszClass As String, _
ByVal lpszWindow As String) _
As IntPtr
End Function
<DllImport("shlwapi.dll")> _
Private Shared Function SHAutoComplete( _
ByVal hwndEdit As IntPtr, _
ByVal dwFlags As SHAutoCompleteFlags) _
As Integer
End Function
<Flags()> _
Private Enum SHAutoCompleteFlags As Integer
SHACF_DEFAULT = &H0
SHACF_FILESYSTEM = &H1
SHACF_URLALL = SHACF_URLHISTORY Or SHACF_URLMRU
SHACF_URLHISTORY = &H2
SHACF_URLMRU = &H4
SHACF_USETAB = &H8
SHACF_FILESYS_ONLY = &H10
SHACF_AUTOSUGGEST_FORCE_ON = &H10000000
SHACF_AUTOSUGGEST_FORCE_OFF = &H20000000
SHACF_AUTOAPPEND_FORCE_ON = &H40000000
SHACF_AUTOAPPEND_FORCE_OFF = &H80000000
End Enum
Protected Overrides Sub OnHandleCreated(ByVal e As EventArgs)
Dim hWndEdit As IntPtr = FindWindowEx(Me.Handle, IntPtr.Zero, "EDIT", Nothing)
' オートコンプリートを有効にする
If Not IntPtr.Zero.Equals(hWndEdit) Then SHAutoComplete(hWndEdit, SHAutoCompleteFlags.SHACF_URLALL)
MyBase.OnHandleCreated(e)
End Sub
End Class
このコードでは、OnHandleCreated()メソッドをオーバーライドし、ハンドルが作成された時点でSHAutoCompleteを呼び出している。 ここで、オートコンプリート機能を適用するためのウィンドウハンドルは直接ComboBox.Handleを使うのではなく、ComboBoxの中にある「EDIT」というクラス名を持つウィンドウハンドルを用いる。
なお、以前に直接入力したアドレスを取得するには、レジストリのHKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\TypedURLsに格納されている値を参照する。 ここにある「URL?」(?は10進の数字)という名前のキーを順に読んでいくことで以前に直接入力したアドレスを取得できる。
Dim keyUrls As Microsoft.Win32.RegistryKey
keyUrls = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\Microsoft\Internet Explorer\TypedURLs")
Dim urlCount As Integer = 1
comboBox.BeginUpdate()
Do
Dim url As String = CStr(keyUrls.GetValue(String.Format("url{0}", urlCount), String.Empty))
If String.Empty.Equals(url) Then Exit Do
comboBox.Items.Add(url)
urlCount += 1
Loop
comboBox.EndUpdate()