2017-02-18 5 views
0

ComboBoxコントロールの数とリストを取得したいので、コードを変更できません。SendMessage APIを使用してComboBoxの数とアイテムを取得する

たとえば、SendMessage APIを使用すると、ターゲットアプリケーションを制御できます。

しかし、どのようにフックすることでターゲットコントロールのリスト全体を取得できますか?

+0

あなたは[GetComboBoxInfo](https://msdn.microsoft.com/en-us UIオートメーション –

+0

を使用することができます/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

+0

問題の説明に提案されたソリューションをインタリーブしました。解決しようとしている問題についてのみ質問してください。これは、* "' SendMessage' "*と*" hooking "*への参照をすべて削除することを意味します。 – IInspectable

答えて

2

あなたがここにComboBox制御メッセージのリストを見つけることができます:アイテムを取得するために

あなたがCB_GETCOUNTメッセージを使用すると、アイテムあなたのテキストを取得する必要があります数えますメッセージCB_GETLBTEXTを使用できます。ここで

私はあなたがComboBoxHandleを渡すことによって、そのインスタンスを作成し、そのプロパティを使用することができますComboBoxHelperクラス作成:Integerとして

  • SelectedIndex:インデックスを選択し返し、リターンを - 項目が選択されていない場合は1です。
  • SelectedtextString:選択した項目のテキストを返し、項目が選択されていない場合は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)) 
+0

プロセスの境界(またはそれに関するウィンドウクラスのプライベートメッセージ)を越えて 'CB_GETLBTEXT'を送ることはできません。申し訳ありませんが解決策ではありません。 -1。 – IInspectable

+1

@IInspectableあまりにも急いで答えを落とさないでください。最初にそれらをテストします。私はそれを2つの異なるプロセスを使ってテストしました。それは正常に動作します:) –

+1

@IInspectable 2つの異なるアプリケーションを使ってテストすることができます.1つはコンボボックス、もう1つはアイテムのテキストとカウントを取得するための 'ComboBoxHelper'です。あなたがそれを試した後、あなたが答えが好きなら、アップヴォートをキャストしてください。私はあなたの投票を変更するための答えにダミーの変更を保存します;) –

関連する問題