2017-02-18 1 views
0

Ich möchte eine Anzahl und eine Liste von ComboBox Steuerelement erhalten, die nicht mir gehört, so dass ich den Code nicht ändern kann.Abrufen einer ComboBox zählt und Elemente mithilfe von SendMessage API

Zum Beispiel kann die Zielapplikation über die API gesteuert werden.

Aber wie kann ich eine vollständige Liste des Zielsteuerelements durch Anhaken abrufen?

+0

Sie UI Automation verwenden können –

+0

[GetComboBoxInfo] (https://msdn.microsoft.com/en-us /library/windows/desktop/bb775939(v=vs.85).aspx) und verwenden Sie 'hwndList' aus [COMBOBOXINFO] (https://msdn.microsoft.com/en-us/library/windows/desktop/bb775798 (v = vs.85) .aspx)? – RbMm

+0

Sie haben Ihre vorgeschlagene Lösung in Ihre Problembeschreibung eingefügt. Bitte fragen Sie nach dem Problem, das Sie nur lösen möchten. Das bedeutet, dass alle Referenzen auf * "' SendMessage' "* und *" hooking "* entfernt werden. – IInspectable

Antwort

2

Sie eine Liste der ComboBox Steuernachrichten finden Sie hier:

Einzelteile zu erhalten zählen Sie CB_GETCOUNT Nachricht verwenden müssen und Sie Text eines Artikels zu erhalten kann CB_GETLBTEXT Nachricht verwenden.

Beispiel

Hier habe ich eine ComboBoxHelper Klasse, die Sie seine Instanz, indem Handle des ComboBox und verwenden seine Eigenschaften schaffen:

  • SelectedIndex als Integer: Kehrt ausgewählten Index, kehrt - 1 wenn kein Gegenstand ausgewählt ist.
  • Selectedtext als String: Gibt den Text des ausgewählten Elements zurück, gibt String.Empty zurück, wenn kein Element ausgewählt ist.
  • ItemsCount wie Integer: Gibt die Anzahl der Elemente zurück.
  • Items(index) als String: Gibt den Text des angegebenen Elements (der Artikel zu bestimmten Index)
  • Items als List(of String): gibt die Liste der Elemente der Combo-Box. Wenn keine Elemente vorhanden sind, wird eine leere Liste zurückgegeben.
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 

Hier ist ein Beispiel für die Verwendung der Klasse:

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

Sie können 'CB_GETLBTEXT' nicht über Prozessgrenzen hinweg senden (oder irgendeine private Fenster-Klassen-Nachricht). Entschuldigung, keine Lösung. -1. – IInspectable

+1

@Intspectable Seien Sie nicht zu schnell, um Antworten zu verwerfen. Testen Sie sie zuerst. Ich habe es mit zwei verschiedenen Prozessen getestet und es funktioniert einwandfrei :) –

+1

@Intspectable Sie können es einfach mit 2 verschiedenen Anwendungen testen, eine enthielt die Combobox, und eine andere benutzte meine 'ComboBoxHelper', um Text und Zählung zu erhalten. Nachdem du es getestet hast, wirf eine Einladung, wenn dir die Antwort gefallen hat. Ich werde eine Dummy-Änderung in der Antwort speichern, damit Sie Ihre Stimme ändern können;) –

Verwandte Themen