ComboBox
コントロールの数とリストを取得したいので、コードを変更できません。SendMessage APIを使用してComboBoxの数とアイテムを取得する
たとえば、SendMessage
APIを使用すると、ターゲットアプリケーションを制御できます。
しかし、どのようにフックすることでターゲットコントロールのリスト全体を取得できますか?
ComboBox
コントロールの数とリストを取得したいので、コードを変更できません。SendMessage APIを使用してComboBoxの数とアイテムを取得する
たとえば、SendMessage
APIを使用すると、ターゲットアプリケーションを制御できます。
しかし、どのようにフックすることでターゲットコントロールのリスト全体を取得できますか?
あなたがここにComboBox
制御メッセージのリストを見つけることができます:アイテムを取得するために
あなたがCB_GETCOUNT
メッセージを使用すると、アイテムあなたのテキストを取得する必要があります数えますメッセージCB_GETLBTEXT
を使用できます。ここで
例
私はあなたがComboBox
のHandle
を渡すことによって、そのインスタンスを作成し、そのプロパティを使用することができますComboBoxHelper
クラス作成:Integer
として
SelectedIndex
:インデックスを選択し返し、リターンを - 項目が選択されていない場合は1です。Selectedtext
String
:選択した項目のテキストを返し、項目が選択されていない場合はString.Empty
を返します。ItemsCount
としてInteger
:はアイテムの数を返します。Items(index)
String
として:List(of String)
として指定された項目(指定されたインデックスの項目)Items
の戻りテキスト:コンボボックスの項目のリストを返します。項目がない場合は、空のリストを返します。ここで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あまりにも急いで答えを落とさないでください。最初にそれらをテストします。私はそれを2つの異なるプロセスを使ってテストしました。それは正常に動作します:) –
@IInspectable 2つの異なるアプリケーションを使ってテストすることができます.1つはコンボボックス、もう1つはアイテムのテキストとカウントを取得するための 'ComboBoxHelper'です。あなたがそれを試した後、あなたが答えが好きなら、アップヴォートをキャストしてください。私はあなたの投票を変更するための答えにダミーの変更を保存します;) –
あなたは[GetComboBoxInfo](https://msdn.microsoft.com/en-us UIオートメーション –
を使用することができます/library/windows/desktop/bb775939(v=vs.85).aspx)、[COMBOBOXINFO](https://msdn.microsoft.com/en-us/library/windows/desktop/bb775798から「hwndList」を使用してくださいv = vs.85).aspx)? – RbMm
問題の説明に提案されたソリューションをインタリーブしました。解決しようとしている問題についてのみ質問してください。これは、* "' SendMessage' "*と*" hooking "*への参照をすべて削除することを意味します。 – IInspectable