Frage an die API-Experten
07.06.2019 18:19:06
Martin
Nachdem ich bereits sehr viel Zeit investiert habe und mein Problem dennoch nicht vollständig lösen konnte, hoffe ich auf Unterstützung eines API-Experten unter euch.
Zielstellung: Aus Excel heraus soll in einer fremden Anwendung (ein Delphi-Programm) der Wert einer ComboBox geändert werden, um einen Filtern in der fremden Anwendung zu entfernen (möglichst ohne dabei die ComboBox aufzuklappen und wieder einzufahren).
Problem: Es ist mir gelungen den Wert der ComboBox erfolgreich umzustellen, jedoch wird das ComboBox-Change-Event innerhalb der fremden Anwendung nicht ausgelöst und der Filter bleibt weiterhin aktiv.
(M)eine unschöne Lösung: Nur wenn die ComboBox aufgeklappt und ein LBUTTONDOWN gesendet wird, _ gelingt es (mir) das ComboBox-Event auszulösen und den Filter erfolgreich zu deaktivieren. Das habe ich mit nachfolgendem Code hinbekommen:
Option Explicit
Private Declare Function FindWindowEx Lib "user32" _
Alias "FindWindowExA" ( _
ByVal hWnd1 As Long, _
ByVal hwnd2 As Long, _
ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long
'SendKey als API
'Declare Sub keybd_event Lib "user32.dll" ( _
' ByVal bVk As Byte, _
' ByVal bScan As Byte, _
' ByVal dwFlags As Long, _
' ByVal dwExtraInfo As Long)
'Private Const KEYEVENTF_KEYUP = &H2 'Buchstabe A
'ComboBox
Private Const CB_GETCURSEL = &H147 'CB-Index lesen
Private Const CB_SETCURSEL = &H14E 'CB-Index setzen
Private Const CB_GETCOUNT = &H146 'Anzahl der Einträge
Private Const CB_GETLBTEXT = &H148
Private Const CB_GETLBTEXTLEN = &H149
'Private Const CB_GETITEMDATA = &O150
'Private Const CB_SETITEMDATA = &O151
Private Const CB_SHOWDROPDOWN = &H14F
Private Const WM_LBUTTONDOWN = &H201
Private Const WM_LBUTTONUP = &H202
'Public Declare Function GetDlgCtrlID Lib "user32" _
' (ByVal hWnd As Long) As Long
'Public Const WM_COMMAND = &H111
'Public Const CBN_SELCHANGE = 1
'Public Const CB_SELECTSTRING = &H14D
'Die korrekte ComboBox ermitteln
Public Function GetTTComboBox(hparent As Long) As Long
Dim lngListCount As Long, hWnd As Long
Dim iSelected As Integer
Dim lngTextLen As Long, TmpStr As String
Dim wParam As Long
hWnd = FindWindowEx(hparent, 0&, "TComboBox", vbNullString)
While hWnd 0
' 'WindowsID der ComboBox ermitteln
' Debug.Print "Cbx-Win ID: " & Hwnd
' 'Anzahl der ComboBox-Einträge
' lngListCount = SendMessage(Hwnd, CB_GETCOUNT, 0&, 0&)
' Debug.Print "Einträge: " & lngListCount
lngTextLen = SendMessage(hWnd, CB_GETLBTEXTLEN, 0&, ByVal 0&)
'Debug.Print "Textlänge: " & lngTextLen
TmpStr = Space(lngTextLen)
lngTextLen = SendMessage(hWnd, CB_GETLBTEXT, 0&, ByVal TmpStr)
'Richtige ComboBox ermitteln (Wenn erster Eintrag = "Alle")
If TmpStr = "Alle" Then
'Aktuellen ListIndex der ComboBox ermitteln
iSelected = SendMessage(hWnd, CB_GETCURSEL, 0&, 0&)
'Falls ListIndex noch nicht auf "Alle" gestellt, dann ändern
If Not iSelected = 0 Then
Call SendMessage(hWnd, CB_SHOWDROPDOWN, 1&, 0&) 'ComboBox aufklappen
Call SendMessage(hWnd, CB_SETCURSEL, 0&, 0&) 'Listindex setzen
Call SendMessage(hWnd, WM_LBUTTONDOWN, 0, -1&) 'Button drücken
Call SendMessage(hWnd, WM_LBUTTONUP, 0, -1&) 'Button drücken aufheben
Call SendMessage(hWnd, CB_SHOWDROPDOWN, 0&, 0&) 'ComboBox einklappen
End If
End If
hWnd = FindWindowEx(hparent, hWnd, "TComboBox", vbNullString)
Wend
End Function
Das gleiche Problem hat auch ein anderer User hier beschrieben:
https://www.experts-exchange.com/questions/23961132/Raise-Combobox-change-event-through-an-API.html
Jedoch habe ich die Antwort zur Lösung nicht verstanden und somit ist es mir auch nicht gelungen meinen Code erfolgreich anzupassen.
Könntet ihr mir bitte bei der Anpassung des Codes helfen? Ich verstehe insbesondere die Function "GetDlg" nicht und was als "hChild" übergeben werden soll. Laut WinSpy hat nur die ComboBox selbst eine Handle-ID, die einzelnen Werte jedoch nicht.
Vielleicht noch ein Hinweis: Ich möchte den obersten Eintrag der ComboBox aktivieren (Index = 0), der Wert lautet Alle. Ich kann die ComboBox auch manuell per Tastendruck a umstellen, falls jemand einen anderen (besseren?) Lösungsweg empfehlen würde.
Viele Grüße
Martin