ComboboxGadget und Autocomplete

Anfängerfragen zum Programmieren mit PureBasic.
Angelo
Beiträge: 102
Registriert: 20.02.2010 14:47
Wohnort: Berlin

ComboboxGadget und Autocomplete

Beitrag von Angelo »

Wenn ich den folgenden Code unter PB 5.40 kompiliere, bekomme ich das "erwünschte" Verhalten.
Zum Beispiel:
1. Eintippen von 'An' führt zu dem Eintrag 'Andreas', wobei nur der ergänzte Teil, also 'ndreas' markiert ist
2. Anschließendes Cursor-Down um eine Position führt zum Eintrag 'Anna', der vollständig markiert ist
3. Anschließendes Eintippen von 'c' führt zu dem Eintrag 'Carola', wobei nur der ergänzte Teil, also 'arola' markiert ist. (Super, so muss es sein!)

Wenn ich aber den Code unter PB 5.50 oder PB 5.60 kompiliere, bekomme ich ein merkwürdiges Verhalten:
Die Schritte 1. und 2. ergeben das gleiche Verhalten. Aber der 3. Schritt - also Eintippen von 'c' - führt zu dem Eintrag 'Anna'. (Nicht gut, macht keinen Sinn!)

Der Schlüssel für die Lösung des Problems muss in der Autocomplete-Funktion liegen. Ich erkenne aber nichts, was durch die neuen Versionen PB 5.50 bzw. PB 5.60 beeinflusst wäre.

Code: Alles auswählen

Declare ComboboxAutoComplete(WindowID, Message, wParam, lParam)

#window = 0
#combo = 0

Global index_auto ;wird in der ComboxAutoComplete-Prozedur verändert

OpenWindow(#Window, 0, 0, 400, 200, "Combobox mit AutoComplete",  #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)

ComboBoxGadget(#combo, 40, 40, 260, #Null, #PB_ComboBox_Editable | #CBS_NOINTEGRALHEIGHT)
MoveWindow_(GadgetID(#combo),GadgetX(#combo),GadgetY(#combo),GadgetWidth(#combo), 22, #True)

;Die Combobox mit Namen füllen    
      AddGadgetItem(#combo, -1, "Albert")
      AddGadgetItem(#combo, -1, "Alfred")
      AddGadgetItem(#combo, -1, "Andreas")
      AddGadgetItem(#combo, -1, "Anna")
      AddGadgetItem(#combo, -1, "Barbara")
      AddGadgetItem(#combo, -1, "Bernd")
      AddGadgetItem(#combo, -1, "Berta")
      AddGadgetItem(#combo, -1, "Birgit")
      AddGadgetItem(#combo, -1, "Carola")
      AddGadgetItem(#combo, -1, "Claus")   
   
SetActiveGadget(#combo)      
      
SetWindowCallback(@ComboboxAutoComplete())


Repeat
   
   event = WaitWindowEvent() 

   If event = #PB_Event_CloseWindow
      quit = #True
   EndIf


   If event = #PB_Event_Gadget      
      If EventGadget() = #combo
         
         If GetAsyncKeyState_(#VK_DOWN)
            ind = index_auto + 1
            SetGadgetState(#combo, ind)
            index_auto = ind
         EndIf
         If GetAsyncKeyState_(#VK_UP)
            ind = index_auto - 1
            If ind < 0
               ind = 0
            EndIf
            SetGadgetState(#combo, ind)
            index_auto = ind
         EndIf
         
      EndIf      
   EndIf         
      
Until quit = #True


Procedure ComboboxAutoComplete(WindowID, Message, wParam, lParam)

Protected result.l

Protected comboWert.s, comboLang.l, comboStart.l, parameter.l, start.l, ende.l
Static comboIndex.l 
                    
result = #PB_ProcessPureBasicEvents
 
Select Message
   ;Case #WM_PAINT
    Case #WM_COMMAND
      Select lParam
         Case GadgetID(#combo)
            Select (wParam >> 16 & $FFFF)
               Case #CBN_EDITUPDATE
                  If GetAsyncKeyState_(#VK_BACK) Or GetAsyncKeyState_(#VK_DELETE)
                     comboWert = GetGadgetText(#combo)
                     If comboIndex >= 0 ;da Var beim Aufruf zuvor bestimmt, muss sie als static definiert sein
                        combowert = Left(comboWert, Len(combowert)-1)
                     EndIf
                  Else
                     comboWert = GetGadgetText(#combo)
                  EndIf
                     ;
                     comboIndex = SendMessage_(lParam, #CB_FINDSTRING, -1, @comboWert)
                     comboStart = Len(comboWert) ;Länge des eingegebenen Textes
                     If combostart = 0
                        SetGadgetText(#combo, "")
                     EndIf
                     ;
                     If comboIndex >= 0 ;es gibt einen Match
                        SendMessage_(lParam, #CB_SETCURSEL, comboIndex, 0)
                        comboLang = Len(GetGadgetText(#combo)) ;Länge des gefundenen Textes
                        parameter = (comboLang << 16 & $FFFFFFFF) + comboStart
                        SendMessage_(lParam, #CB_SETEDITSEL, 0, parameter)
                        index_auto = GetGadgetState(#combo)
                     EndIf
            EndSelect
      EndSelect
EndSelect

ProcedureReturn result

EndProcedure

PB 5.50; Win 7
Benutzeravatar
GlassJoe
Beiträge: 108
Registriert: 11.06.2017 20:25
Computerausstattung: 2 x AMD Phenom II x4 945,2x Dell Latitude X300, Dell Latitude D410, Hp Compaq NC4400

Re: ComboboxGadget und Autocomplete

Beitrag von GlassJoe »

Also mir ist aufgefallen das du GetAsyncKeyState benutzt, und der Mist macht oft Ärger (teils werden Key Events von einem Fenster zum anderen einfach mitgenommen, obwohl in der Zwischenzeit schon längt andere Tasten gedrückt wurden) der Befehl EventwParam wäre vorzuziehen :)

Code: Alles auswählen

  If OpenWindow(0,300,300,550,400,"",#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered) 
    
    ;/ Wenn nur eine Taste benutzt wird reicht #WM_KEYDOWN oder #WM_KEYFIRST
    
    ;/ Wenn eine Tastenkombination benutzt wird, dann eine Variable und #WM_KEYDOWN & #WM_KEYUP
    ;/ wie im Beispiel unten. Dann klappt, erst Shift+Taste und wenn mann immer noch auf Shift drauf bleibt
    ;/ und dann wieder Taste drückt, wird wieder Shift+Taste ausgelöst.
    
    Repeat 
      
      Event = WaitWindowEvent()
      
      If Event = #WM_KEYDOWN
        
        Debug ""
        
        Main_KeyCode = EventwParam()
        
        Debug "---DOWN--="+Str(Main_KeyCode)
        
        If Main_ShiftTrue = 0
          
          If Main_KeyCode = #VK_SHIFT
            Debug "Key = Shift"
            Main_ShiftTrue = 1 
          EndIf 
          If Main_KeyCode = #VK_LEFT
            Debug "Key = Left"
          EndIf
          If Main_KeyCode = #VK_RIGHT
            Debug "Key = Right"
          EndIf  
          
        Else 
          
          Debug "--SHIFT EVENT--="+Str(Main_KeyCode)
          
          If Main_KeyCode = #VK_LEFT
            Debug "Key Combo = Shift + Left"
          ElseIf Main_KeyCode = #VK_RIGHT
            Debug "Key Combo = Shift + Right"
          EndIf
          
        EndIf 
        
      EndIf
      
      If Event = #WM_KEYUP
        Debug ""
        Debug "---UP---" 
        If Main_ShiftTrue
          Main_KeyCode = EventwParam()
          If Main_KeyCode = #VK_SHIFT
            Debug "SHIFT RELEASED"
            Main_ShiftTrue = 0 
          Else
            Debug "SHIFT STILL HOLD | RELEASED Key = "+Str(Main_KeyCode)
          EndIf
        EndIf
      EndIf 
      
      
      If Event = #PB_Event_CloseWindow
        Break
      EndIf
      
    ForEver 
    
  EndIf 
Noch was ist mir unter PB 5.60 aufgefallen, wenn du den Namen selbst komplett markierst (Barbara) und dann C drückst funzt es.

Leerst du die Zeile danach komplett und drückst C geht es auch, wenn du aber nachdem du Cursor Down gedrückt hast, die #VK_Back Taste drückst oder ENTF, geht es nicht !

Vl bringt mal wieder das GetAsyncKeyState alles durcheinander.
https://www.geek.com/tech/a-commodore-6 ... s-1672510/
٩(̾●̮̮̃̾•̃̾)۶ __̴ı̴̴̡̡̡ ̡͌l̡̡̡ ̡͌l̡*̡̡ ̴̡ı̴̴̡ ̡̡͡|̲̲̲͡͡͡ ̲▫̲͡ ̲̲̲͡͡π̲̲͡͡ ̲̲͡▫̲̲͡͡ ̲|̡̡̡ ̡ ̴̡ı̴̡̡ ̡͌l̡̡̡̡.___٩(- ̮̮̃-̃)۶
Angelo
Beiträge: 102
Registriert: 20.02.2010 14:47
Wohnort: Berlin

Re: ComboboxGadget und Autocomplete

Beitrag von Angelo »

Danke, GlassJoe, für Deine Antwort.
Der Code funktioniert ja unter PB 5.40. Wenn ich mir die Changes bei den nachfolgenden Versionen 5.50 und 5.60 ansehe, dann fällt mir nur ein Punkt auf, der vielleicht eine Rolle spielen könnte, nämlich dass jetzt in Unicode kompiliert wird. Ich habe das Gefühl, das könnte die Callback-Funktion beeinflussen.
PB 5.50; Win 7
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: ComboboxGadget und Autocomplete

Beitrag von man-in-black »

Hi,

ich vermute, dass es an der Selektion im Combogadget liegt. Bis auf die Pfeiltaste wird die Selektion jedesmal aktualisiert.
Vermutlich hast du in der neuen PB Version einen Sonderzustand, den du durch Drücken einer weiteren Taste verlässt.

AN + Runter + C = Anna
AN + Runter + C + C = Annac <- also wieder sinnvoll

Habe leider keine Zeit zum testen, aber ändere die Selektion beim "Runter" testweise auch mal.

MFG
MIB
(hab alles, kann alles, weiß alles!!^^)

Bild
Angelo
Beiträge: 102
Registriert: 20.02.2010 14:47
Wohnort: Berlin

Re: ComboboxGadget und Autocomplete

Beitrag von Angelo »

Hi, MIB, nach dem zweiten Schritt ist ja der Eintrag Anna vollständig markiert. Wenn ich jetzt im 3. Schritt den Buchstabe c eintippe, dann sollte doch auch C dort stehen plus natürlich das, was durch den Autocomplete-Prozess hinzugefügt wird. Das ist bei der Version 5.40 der Fall.

Was Du geschrieben hast für die Versionen 5.50 bzw. 5.60 ist richtig.: Nach Eintippen von C ist der Eintrag Anna nicht mehr markiert und nach nochmaligem Eintippen von C steht dort: AnnaC. Aber man würde doch erwarten, dass der markierte Text (also Anna) vollständig durch eine neue Eingabe (also C) ersetzt wird (wie es bei PB 5.40 der Fall ist).
PB 5.50; Win 7
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: ComboboxGadget und Autocomplete

Beitrag von man-in-black »

Genau das meine ich ja. Es gibt scheinbar bei den höheren Versionen einen "Sonderzustand".
Es sieht zwar markiert aus, ist es aber nicht. Vielleicht kann man dies umgehen, wenn man die
Selektion nocheinmal setzt.

(ist auch nur ein Schuss ins Blaue)

P.S.:
Oder man ist aus dem "Bearbeitungsmodus" raus und springt erst bei Eingabe eines alphanumerischen Zeichens wieder hinein.
Dann hilft es vielleicht, den Curser umzusetzen?


MFG
MIB
(hab alles, kann alles, weiß alles!!^^)

Bild
Antworten