我想获得一个计数和列表ComboBox
控制这不是我的,所以我不能修改代码。检索ComboBox通过使用SendMessage API计数和项目
例如,通过使用SendMessage
API可以控制目标应用程序。
但是,如何通过挂钩检索目标控件的整个列表?
我想获得一个计数和列表ComboBox
控制这不是我的,所以我不能修改代码。检索ComboBox通过使用SendMessage API计数和项目
例如,通过使用SendMessage
API可以控制目标应用程序。
但是,如何通过挂钩检索目标控件的整个列表?
你可以找到ComboBox
控制消息在这里的列表:
要获得项目数,您需要使用CB_GETCOUNT
消息,并获得一个项目的文本你可以使用CB_GETLBTEXT
消息。
例
在这里,我创建了一个ComboBoxHelper
类,你可以通过传递ComboBox
的Handle
创建它的实例,并使用其属性:
SelectedIndex
为Integer
:选择指数返回,返回 - 1如果没有选择项目。Selectedtext
作为String
:返回所选项目的文本,如果未选择项目,则返回String.Empty
。ItemsCount
as Integer
:返回项目数。Items(index)
为String
:返回文本中指定的项目(在指定索引的项目)Items
为List(of String)
的:返回组合框的项目列表。如果没有项目,它将返回一个空列表。Public Class ComboBoxHelper
Private hWnd As IntPtr
Const CB_GETCURSEL As Integer = &H147
Const CB_SETCURSEL As Integer = &H14E
Const CB_GETCOUNT As Integer = &H146
Const CB_GETLBTEXT As Integer = &H148
Const CB_GETLBTEXTLEN As Integer = &H149
<System.Runtime.InteropServices.DllImport("user32.dll")> _
Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, _
ByVal wParam As Integer, ByRef lParam As Integer) As IntPtr
End Function
<System.Runtime.InteropServices.DllImport("user32.dll")> _
Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, _
ByVal wParam As Integer, ByVal lParam As System.Text.StringBuilder) As IntPtr
End Function
Public Sub New(handle As IntPtr)
hWnd = handle
End Sub
Public Property SelectedIndex As Integer
Get
Return SendMessage(hWnd, CB_GETCURSEL, 0, 0).ToInt32()
End Get
Set(ByVal value As Integer)
SendMessage(hWnd, CB_SETCURSEL, value, 0).ToInt32()
End Set
End Property
Public ReadOnly Property ItemsCount As Integer
Get
Return SendMessage(hWnd, CB_GETCOUNT, 0, 0).ToInt32()
End Get
End Property
Public ReadOnly Property SelectedText As String
Get
Dim index = Me.SelectedIndex
If (Me.SelectedIndex = -1) Then
Return String.Empty
End If
Return Me.Items(index)
End Get
End Property
Public ReadOnly Property Items() As List(Of String)
Get
If (ItemsCount > 0) Then
Return Enumerable.Range(0, ItemsCount) _
.Select(Function(index) Items(index)).ToList()
Else
Return New List(Of String)
End If
End Get
End Property
Public ReadOnly Property Items(index As Integer) As String
Get
If (index < 0 OrElse index >= ItemsCount) Then
Throw New ArgumentOutOfRangeException("index")
End If
Dim length = SendMessage(hWnd, CB_GETLBTEXTLEN, index, 0).ToInt32()
Dim text As New System.Text.StringBuilder(length)
SendMessage(hWnd, CB_GETLBTEXT, index, text)
Return text.ToString()
End Get
End Property
End Class
下面是类的使用的一个示例:
Dim combo As New ComboBoxHelper(hWnd) 'You have hWnd
MessageBox.Show(combo.ItemsCount.ToString())
MessageBox.Show(combo.SelectedIndex.ToString())
MessageBox.Show(combo.SelectedText.ToString())
combo.Items.ForEach(Function(item) MessageBox.Show(item))
您不能通过进程边界发送'CB_GETLBTEXT'(或任何窗口类私人消息)。对不起,没有解决方案。 -1。 – IInspectable
@IInspectable不要太急于downvote的答案。首先测试它们。我使用两种不同的流程对其进行了测试,并且它可以正常工作:) –
@IInspectable您可以使用2个不同的应用程序对其进行简单测试,其中一个包含组合框,另一个使用我的ComboBoxHelper获取项目文本和计数。在你测试之后,如果你喜欢答案,可以投下赞成票。我会在答案中保存一个虚拟变化,让你改变你的投票;) –
可以使用UI自动化 –
[GetComboBoxInfo](https://msdn.microsoft.com/en-us /library/windows/desktop/bb775939(v=vs.85).aspx)并使用[COMBOBOXINFO]中的'hwndList'(https://msdn.microsoft.com/en-us/library/windows/desktop/bb775798( v = vs.85).aspx)? – RbMm
您已将您建议的解决方案交错到问题描述中。请询问您正在尝试解决的问题。这意味着删除所有对*“'SendMessage'”*和*“hooking”*的引用。 – IInspectable