zoukankan      html  css  js  c++  java
  • 可以修改Autocomplete高度和宽度的TextBox.(ComboBox也试用)

    Imports System.ComponentModel
    Imports System.Runtime.InteropServices
    Imports System.Text
    
    Public Class TextBoxEx
        Inherits TextBox
        Private acDropDownHeight As Integer = 106
        Private acDropDownWidth As Integer = 170
    
    
        '<EditorBrowsable(EditorBrowsableState.Always), _  
    
        <Browsable(True), Description("The width, in pixels, of the auto complete drop down box"), DefaultValue(170)> _
        Public Property AutoCompleteDropDownWidth() As Integer
            Get
                Return acDropDownWidth
            End Get
    
            Set(value As Integer)
                acDropDownWidth = value
            End Set
        End Property
    
    
        '<EditorBrowsable(EditorBrowsableState.Always), _  
    
        <Browsable(True), Description("The height, in pixels, of the auto complete drop down box"), DefaultValue(106)> _
        Public Property AutoCompleteDropDownHeight() As Integer
            Get
                Return acDropDownHeight
            End Get
    
            Set(value As Integer)
                acDropDownHeight = value
            End Set
        End Property
    
    
        Protected Overrides Sub OnHandleCreated(e As EventArgs)
            MyBase.OnHandleCreated(e)
    
            ACWindow.RegisterOwner(Me)
        End Sub
    
        ''' <summary>  
        ''' Provides an encapsulation of an Auto complete drop down window   
        ''' handle and window proc.  
        ''' </summary>  
        Private Class ACWindow
            Inherits NativeWindow
            Private Shared ReadOnly ACWindows As Dictionary(Of IntPtr, ACWindow)
    
    
            Private Const WM_WINDOWPOSCHANGED As UInt32 = &H47
    
            Private Const WM_NCDESTROY As UInt32 = &H82
    
    
            Private Const SWP_NOSIZE As UInt32 = &H1
    
            Private Const SWP_NOMOVE As UInt32 = &H2
    
            Private Const SWP_NOZORDER As UInt32 = &H4
    
            Private Const SWP_NOREDRAW As UInt32 = &H8
    
            Private Const SWP_NOACTIVATE As UInt32 = &H10
            Private Const WM_SIZING As UInt32 = &H214
    
            Private Const GA_ROOT As UInt32 = 2
            Private Shared ReadOnly owners As List(Of TextBoxEx)
    
    
            <DllImport("user32.dll")> _
            Private Shared Function EnumThreadWindows(dwThreadId As Integer, lpfn As EnumThreadDelegate, lParam As IntPtr) As Boolean
            End Function
    
    
            <DllImport("user32.dll")> _
            Private Shared Function GetAncestor(hWnd As IntPtr, gaFlags As UInt32) As IntPtr
            End Function
    
    
            <DllImport("kernel32.dll")> _
            Private Shared Function GetCurrentThreadId() As Integer
            End Function
    
    
            <DllImport("user32.dll")> _
            Private Shared Sub GetClassName(hWnd As IntPtr, lpClassName As StringBuilder, nMaxCount As Integer)
            End Sub
    
    
            <DllImport("user32.dll")> _
            Private Shared Function SetWindowPos(hWnd As IntPtr, hWndInsertAfter As IntPtr, X As Integer, Y As Integer, cx As Integer, cy As Integer, _
                uFlags As UInteger) As Boolean
            End Function
    
    
            <DllImport("user32.dll")> _
            Private Shared Function GetWindowRect(hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
            End Function
    
    
            Private Delegate Function EnumThreadDelegate(hWnd As IntPtr, lParam As IntPtr) As Boolean
    
    
    
            <StructLayout(LayoutKind.Sequential)> _
            Private Structure RECT
                Public ReadOnly Left As Integer
    
                Public ReadOnly Top As Integer
    
                Public ReadOnly Right As Integer
    
                Public ReadOnly Bottom As Integer
    
    
                Public ReadOnly Property Location() As Point
                    Get
                        Return New Point(Left, Top)
                    End Get
                End Property
            End Structure
    
    
            Private owner As TextBoxEx
    
            Shared Sub New()
                ACWindows = New Dictionary(Of IntPtr, ACWindow)()
    
                owners = New List(Of TextBoxEx)()
            End Sub
    
    
            ''' <summary>  
            ''' Creates a new ACWindow instance from a specific window handle.  
            ''' </summary>  
            Private Sub New(handle As IntPtr)
                AssignHandle(handle)
            End Sub
    
    
            ''' <summary>  
            ''' Registers a ComboBoxEx for adjusting the Complete Dropdown window size.  
            ''' </summary>  
            Public Shared Sub RegisterOwner(owner As TextBoxEx)
                If (owners.Contains(owner)) Then
                    Return
                End If
    
                owners.Add(owner)
    
                EnumThreadWindows(GetCurrentThreadId(), AddressOf EnumThreadWindowCallback, IntPtr.Zero)
            End Sub
    
    
            ''' <summary>  
            ''' This callback will receive the handle for each window that is  
            ''' associated with the current thread. Here we match the drop down window name   
            ''' to the drop down window name and assign the top window to the collection  
            ''' of auto complete windows.  
            ''' </summary>  
            Private Shared Function EnumThreadWindowCallback(hWnd As IntPtr, lParam As IntPtr) As Boolean
                If (GetClassName(hWnd) = "Auto-Suggest Dropdown") Then
                    Dim handle As IntPtr = GetAncestor(hWnd, GA_ROOT)
    
    
                    If (Not ACWindows.ContainsKey(handle)) Then
                        ACWindows.Add(handle, New ACWindow(handle))
                    End If
                End If
    
                Return True
            End Function
    
    
            ''' <summary>  
            ''' Gets the class name for a specific window handle.  
            ''' </summary>  
            Private Shared Function GetClassName(hRef As IntPtr) As String
                Dim lpClassName = New StringBuilder(256)
    
                GetClassName(hRef, lpClassName, 256)
    
                Return lpClassName.ToString()
            End Function
    
    
            ''' <summary>  
            ''' Overrides the NativeWindow's WndProc to handle when the window  
            ''' attributes changes.  
            ''' </summary>  
            Protected Overrides Sub WndProc(ByRef m As Message)
                'If m.Msg = WM_SIZING Then
                '    If owner IsNot Nothing Then
                '        Dim rr As RECT = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(RECT)), RECT)
                '        owner.acDropDownWidth = (rr.Right - rr.Left)
                '        owner.acDropDownHeight = (rr.Bottom - rr.Top)
                '    End If
                'End If
                Console.WriteLine(m.Msg.ToString())
                If (m.Msg = WM_WINDOWPOSCHANGED) Then
                    ' If the owner has not been set we need to find the ComboBoxEx that  
    
                    ' is associated with this dropdown window. We do it by checking if  
    
                    ' the upper-left location of the drop-down window is within the   
    
                    ' ComboxEx client rectangle.   
    
                    If (owner Is Nothing) Then
                        Dim ownerRect As Rectangle = Nothing
    
                        Dim acRect = New RECT()
    
                        For Each cbo As TextBoxEx In owners
                            GetWindowRect(Handle, acRect)
    
                            ownerRect = cbo.RectangleToScreen(cbo.ClientRectangle)
    
                            'If (ownerRect.Contains(acRect.Location)) Then
                            owner = cbo
    
                            ' TODO: might not be correct. Was : Exit For
                            'Exit For
                            ' End If
                        Next
    
                        owners.Remove(owner)
                    End If
    
    
                    If ((owner IsNot Nothing)) Then
                        SetWindowPos(Handle, IntPtr.Zero, -5, 0, owner.AutoCompleteDropDownWidth, owner.AutoCompleteDropDownHeight, _
                            SWP_NOMOVE Or SWP_NOZORDER Or SWP_NOACTIVATE)
                    End If
                End If
    
    
                If (m.Msg = WM_NCDESTROY) Then
                    ACWindows.Remove(Handle)
                End If
    
    
                MyBase.WndProc(m)
            End Sub
        End Class
    
    End Class
  • 相关阅读:
    noi.ac NOI挑战营模拟赛1-5
    TJOI2015 弦论
    CQOI2018 破解D-H协议
    NOI2013 矩阵游戏
    NOI2015 荷马史诗
    NOI2015 寿司晚宴
    SDOI2014 重建
    NOI1999 生日蛋糕
    NOI2015 程序自动分析
    ZJOI2008 泡泡堂
  • 原文地址:https://www.cnblogs.com/tony-MSDN/p/4488520.html
Copyright © 2011-2022 走看看