Hallo,
der Standardfall unter Windows ist ja, dass man bei fokussiertem ComboBoxGadget durch Tastendruck direkt zum
ersten Item mit dem eingegebenen Anfangsbuchstaben springen kann. Ich würde diese Funktion gern ausweiten,
sodass beim weiteren Tippen die Items markiert werden, die mit der seit der Fokussierung eingegebenen Zeichenkette
beginnen.
Ich habe das bei einem anderen, nicht-PB-Programm, gesehen, habe aber per Suche keinen passenden Ansatz gefunden.
Es geht mir nicht um Editable-ComboBoxen, da ich keine freie Auswahl erlauben kann.
ComboBox: Aktuelles Item durch Eingabe ändern
ComboBox: Aktuelles Item durch Eingabe ändern
Win11 x64 | PB 6.10 (x64)
Re: ComboBox: Aktuelles Item durch Eingabe ändern
Der Vollständigkeit halber: ich habe eine Lösung gefunden:
Code: Alles auswählen
Import ""
PB_Object_EnumerateStart(*object)
PB_Object_EnumerateNext(*object,*id.Integer)
PB_Object_EnumerateAbort(*object)
PB_Gadget_Objects.i
EndImport
Structure COMBOSEARCH
iID.i
iState.i
zText.s
EndStructure
Global.i ActiveControl
Procedure.i PBGadget(hWnd)
Protected.i iResult,
iGadget
iResult = -1
PB_Object_EnumerateStart(PB_Gadget_Objects)
While PB_Object_EnumerateNext(PB_Gadget_Objects, @iGadget)
If hWnd = GadgetID(iGadget)
iResult = iGadget
Break
EndIf
Wend
PB_Object_EnumerateAbort(PB_Gadget_Objects)
ProcedureReturn iResult
EndProcedure
Procedure.i ComboSearch(piGadget.i, piKey.i)
Protected.i i,
iFound,
iState,
iAnzLine
Protected.s zText
Static NewList sllCombo.COMBOSEARCH()
; --------------------------
; ComboBox suchen oder Eintrag anlegen
iFound = 0
ForEach sllCombo()
If sllCombo()\iID = piGadget
iFound = 1
Break
EndIf
Next
If iFound = 0
AddElement(sllCombo())
sllCombo()\iID = piGadget
EndIf
; Status vergleichen, um zwischenzeitiche manuelle Änderungen
; zu erkennen und den Text zurückzusetzen
iState = GetGadgetState(piGadget)
If sllCombo()\iState <> iState
sllCombo()\zText = ""
EndIf
If piKey = 8
; Text: Key ist Backspace, dann letztes Zeichen löschen
sllCombo()\zText = Left(sllCombo()\zText, Len(sllCombo()\zText) - 1)
ElseIf piKey = 32
; Text: Key ist Leertaste, Suche komplett löschen
sllCombo()\zText = ""
SetGadgetState(piGadget, 0)
ProcedureReturn 1
Else
; Text: Key ist A-Z oder 0-9, dann Zeichen anhängen
sllCombo()\zText + Chr(piKey)
EndIf
iAnzLine = CountGadgetItems(piGadget) - 1
For i = 0 To iAnzLine
zText = RemoveString(GetGadgetItemText(piGadget, i), " ")
If FindString(zText, sllCombo()\zText, 0, #PB_String_NoCase)
SetGadgetState(piGadget, i)
sllCombo()\iState = i
PostEvent(#PB_Event_Gadget, 0, piGadget, #PB_EventType_Change)
ProcedureReturn 1
EndIf
Next i
ProcedureReturn 0
EndProcedure
Procedure WindowCB(hWnd, msg, wParam, lParam)
Protected.i iResult
iResult = #PB_ProcessPureBasicEvents
Select msg
Case #WM_COMMAND
Select (wParam >> 16) & $FFFF
Case #CBN_SETFOCUS
ActiveControl = PBGadget(lParam)
Case #CBN_KILLFOCUS
ActiveControl = -1
EndSelect
EndSelect
ProcedureReturn iResult
EndProcedure
Procedure.l KbdHook(nCode, wParam, *p.KBDLLHOOKSTRUCT)
Protected.i iKey,
iGadget,
iType
If wParam = #WM_KEYDOWN
iKey = MapVirtualKey_(*p\vkCode, 2)
Select iKey
Case 8, 32, 48 To 57, 65 To 90, 223, 228, 246, 252
; //
; Backspace, Space, 0-9, A-Z, ß, ä, ö, ü
; //
iGadget = ActiveControl
If IsGadget(iGadget)
iType = GadgetType(iGadget)
If iType = #PB_GadgetType_ComboBox
ComboSearch(iGadget, iKey)
ProcedureReturn 1
EndIf
EndIf
EndSelect
EndIf
ProcedureReturn CallNextHookEx_(0, nCode, wParam, *p)
EndProcedure
; A-Z, 0-9 mgl. ohne Leerzeichen
; Backspace löscht letztes eingebenes Zeichen
; Leertaste löscht ganzen Filter
If OpenWindow(0, 0, 0, 270, 180, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ComboBoxGadget(0, 10, 70, 250, 21)
AddGadgetItem(0, -1, "Brauhaus")
AddGadgetItem(0, -1, "Brauhausplatz")
AddGadgetItem(0, -1, "Braustolz")
AddGadgetItem(0, -1, "Xylophon")
AddGadgetItem(0, -1, "Xylophonbauer")
AddGadgetItem(0, -1, "Ameise")
AddGadgetItem(0, -1, "Ameisenbär")
AddGadgetItem(0, -1, "Amerika")
AddGadgetItem(0, -1, "Butterbrot")
AddGadgetItem(0, -1, "Burschenschaftler")
AddGadgetItem(0, -1, "Ammenmärchen")
AddGadgetItem(0, -1, "Risikobewertung")
SetGadgetState(0, 0)
SetWindowCallback(@WindowCB(), 0)
SetWindowsHookEx_(#WH_KEYBOARD_LL, @KbdHook(), GetModuleHandle_(0), 0)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Win11 x64 | PB 6.10 (x64)