问题
I have TextBox
controls and associated Timers that restarts on each KeyDown
or MouseClick
event, and performs queries based on typed text after 3 seconds without those events. So far so good.
But some of my TextBoxes also have AutoComplete lists which user can browse in, but even if they do using keyboard arrow keys, timer is not halted and an unexpected query is fired in the middle of user browsing the list.
Question: is there a way of detecting when autocomplete list is showing, so that I can suspend timer or ignoring its tick?
Thank you very much!
回答1:
You can use EnumThreadWindows to find all auto complete dropdown windows and check if any of them is visible. The Auto-complete dropdown window class name is Auto-Suggest Dropdown
. You can use GetClassName method to get class name of enumerated windows and then using IsWindowVisible method check if the window is visible.
Example
In below example, I used a timer like you have in your code in the question, and in tick event of the timer, I've checked if there is an auto-complete window open I showed "Open" in title of form, otherwise showed "close":
Delegate Function EnumThreadDelegate(hWnd As IntPtr, lParam As IntPtr) As Boolean
<System.Runtime.InteropServices.DllImport("user32.dll")> _
Shared Function EnumThreadWindows(dwThreadId As Integer, _
lpfn As EnumThreadDelegate, lParam As IntPtr) As Boolean
End Function
<System.Runtime.InteropServices.DllImport("user32.dll")> _
Shared Function GetClassName(ByVal hWnd As System.IntPtr,
lpClassName As System.Text.StringBuilder, _
nMaxCount As Integer) As Integer
End Function
<System.Runtime.InteropServices.DllImport("kernel32.dll")> _
Shared Function GetCurrentThreadId() As Integer
End Function
<System.Runtime.InteropServices.DllImport("user32.dll")> _
Shared Function IsWindowVisible(hWnd As IntPtr) As Boolean
End Function
Const AutoCompleteClassName As String = "Auto-Suggest Dropdown"
Function EnumThreadCallback(hWnd As IntPtr, lParam As IntPtr) As Boolean
Dim className As New System.Text.StringBuilder("", 256)
GetClassName(hWnd, className, 256)
If className.ToString() = AutoCompleteClassName AndAlso IsWindowVisible(hWnd) Then
AnAutoCOmpleteIsOpen = True
End If
Return True
End Function
Dim AnAutoCOmpleteIsOpen As Boolean = False
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
AnAutoCOmpleteIsOpen = False
EnumThreadWindows(GetCurrentThreadId(), _
New EnumThreadDelegate(AddressOf Me.EnumThreadCallback), IntPtr.Zero)
If (AnAutoCOmpleteIsOpen) Then
Me.Text = "Open"
Else
Me.Text = "Close"
End If
End Sub
来源:https://stackoverflow.com/questions/40912233/detect-when-textbox-autocomplete-list-is-showing