.net - 使用 SendMessage API 检索 ComboBox 计数和项目

标签 .net vb.net winforms winapi combobox

我想获取不属于我的 ComboBox 控件的计数和列表,以便我无法修改代码。

例如,可以使用 SendMessage API 来控制目标应用。

但是,如何通过 Hook 检索目标控件的整个列表?

最佳答案

您可以在此处找到 ComboBox 控件消息列表:

要获取项目数量,您需要使用 CB_GETCOUNT消息并获取项目的文本,您可以使用 CB_GETLBTEXT消息。

示例

在这里,我创建了一个 ComboBoxHelper 类,您可以通过传递 ComboBoxHandle 来创建其实例并使用其属性:

  • SelectedIndex as Integer:返回所选索引,如果未选择任何项目,则返回 -1。
  • Selectedtext as String:返回所选项目的文本,如果未选择任何项目,则返回 String.Empty
  • ItemsCount as Integer:返回项目计数。
  • Items(index) as String:返回指定项目的文本(指定索引处的项目)
  • Items as 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))

关于.net - 使用 SendMessage API 检索 ComboBox 计数和项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42311818/

相关文章:

MYSQL - 2个组合表之间的搜索条件

VB.NET Winforms DataGridView 在排序的 DataGridView 上选择新行

c# - ObjectListView 嵌套对象

c# - 在 C# 中缩放窗口窗体

c# - 保存 1 位深度的 TIF 的最佳 Web 可视格式是什么?

c# - 在 C# 中,如何检查 File.Delete() 是否会在不尝试的情况下成功?

c# - 控制台应用程序中的 .NET 全局异常处理程序

c# - 使用 RegularExpressionValidator 上传文件不适用于 Firefox only IE

.net - 如何将调试器附加到 WebService?

.NET 实现 : Double conversion in Math. Min(float, float)