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''' オートコンプリート機能を持ったコンボボックス ''' Public Class AutoCompleteComboBox Inherits System.Windows.Forms.ComboBox_ Private Shared Function FindWindowEx( _ ByVal hWndParent As IntPtr, _ ByVal hwndChildAfter As IntPtr, _ ByVal lpszClass As String, _ ByVal lpszWindow As String) _ As IntPtr End Function _ Private Shared Function SHAutoComplete( _ ByVal hwndEdit As IntPtr, _ ByVal dwFlags As SHAutoCompleteFlags) _ As Integer End Function _ 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()