Seite 1 von 2

Combobox und Autocomplete

Verfasst: 25.10.2008 20:56
von Andi
Hi, ich benutze die Autocomplete-Prozedur für Comboboxen, die von Karl in diesem Forum gepostet wurde. Die Texteingabe wird durch diese Prozedur automatisch ergänzt. Außerdem wird das auf diese Weise ergänzte Item auch noch am Anfang der durch die Combobox dargestellten Einträge angezeigt. So weit, so gut. Meine Frage ist jetzt, wie man erreichen kann, dass dieser Eintrag noch markiert wird. Vielleicht hat ja jemand eine Idee.

Verfasst: 25.10.2008 23:21
von Kai
Ich weiß nicht was genau du meinst, das der gefundene Eintrag in der Combobox ausgewählt wird?
Auf jeden Fall kann ich diesen Forum Thread im Englischen Forum empfehlen, benutze ich ebenfalls und funktioniert perfekt.

http://www.purebasic.fr/english/viewtop ... 2862#32862

Verfasst: 25.10.2008 23:24
von Falko
Ich verstehe nun nicht, was markiert sein soll. Bei mir unter
Vista, nachdem ich diesen Source auf PB 4.3b4 angepasst hatte,
funktioniert unter der Auswahl die Selektierte Markierung als auch
der oben in der Combobox geschriebene String wird markiert bzw. selectiert.

Kann aber auch sein, das ich das falsch verstanden habe :freak:

Hier der angepasste Source, wenn du diesen von Karl meintest:

Code: Alles auswählen

;PB 3.94
;Der Karl
;updated 12.10.2006
;Updated to PB 4.3b4 by Falko

#comboTest = 0


Procedure cmbAutoComplete(WindowID, Message, wParam, lParam)
 
  Protected comboWert.s, comboIndex.l, comboLang.l, comboStart.l, parameter.l
  Protected start.l, ende.l
  result = #PB_ProcessPureBasicEvents
 
 
  Select Message
    Case #WM_COMMAND
      Select lParam
        Case GadgetID(0)
          Select (wParam >> 16 & $FFFF)
            Case #CBN_EDITUPDATE
              If GetAsyncKeyState_(#VK_BACK) Or GetAsyncKeyState_(#VK_DELETE)
                ;tu nix
              Else
                comboWert = GetGadgetText(#comboTest)
                comboIndex = SendMessage_(lParam, #CB_FINDSTRING, -1, @comboWert)
                comboStart = Len(comboWert)
                ;Länge des eingegebenen Textes
                If comboIndex >= 0
                  SendMessage_(lParam, #CB_SETCURSEL, comboIndex, 0)
                  comboLang = Len(GetGadgetText(#comboTest))
                  ;Länge des gefundenen Textes
                  parameter = (comboLang << 16 & $FFFFFFFF) + comboStart
                  SendMessage_(lParam, #CB_SETEDITSEL, 0, parameter)
                EndIf
              EndIf
          EndSelect
      EndSelect
  EndSelect

  ProcedureReturn result
 
EndProcedure

Procedure InitWindow()
 
  ;Window zeichnen und ComboBox aus einer externen Datei füllen (jede Zeile = ein Eintrag)
 
  If OpenWindow(0, 0, 0, 400, 200, "Test", #PB_Window_SystemMenu)
    If CreateMenu(0, WindowID(0))
      MenuTitle("Datei")
      LoadImage(0, "folder_page.bmp")
      LoadImage(1, "printer.bmp")
        MenuItem(0, "Öffnen" + #TAB$ + "STRG+O")
        MenuItem(1, "Schließen")
        SetMenuItemBitmaps_(MenuID(0), 0, #MF_BYCOMMAND	, ImageID(0), ImageID(1)); hiernmit wird das BMP angezeigt
    EndIf
    ;If CreateGadgetList(WindowID(0))
      ComboBoxGadget(#comboTest, 10, 10, 180, 50, #PB_ComboBox_Editable)
    ;EndIf
    ReadFile(0, "cmb.txt")
    While Not Eof(0)
      AddGadgetItem(0, -1, ReadString(0))
    Wend 
    CloseFile(0)
  EndIf

EndProcedure


InitWindow()
SetWindowCallback(@cmbAutoComplete())

Repeat
 
Until WaitWindowEvent() = #PB_Event_CloseWindow

End  
die cmb.txt mit den einzelnen Strings sowie die BMP-Bilder
kann jeder selbst ausdenken.


Gruß Falko

Verfasst: 25.10.2008 23:37
von Andi
Ich habe mich leider nicht ganz verständlich ausgedrückt - sorry! - und auch vergessen - das ist ein wichtiger Punkt -, dass ich die Combobox mit SendMessage_(GadgetID(#combobox),#CB_SHOWDROPDOWN,1,0) aufklappe. Und da ist eben dann so, dass mit dem Code von Karl, den auch Du, Falko, in Deiner Antwort stehen hast, oben in der Eingabezeile der Text zwar zu einem passenden Item ergänzt wird und dieses Item in der aufgeklappten Liste auch an erster Stelle steht, aber eben leider nicht markiert ist. Meine Hoffnung ist, dass man dieses mit einem SendMessage-Befehl ändern kann.
Gruß Andi

Verfasst: 26.10.2008 18:05
von Falko
Hallo Andi,

leider habe ich keine bessere Antwot, aber evt. könntest du mit SetGadgetState(0, X) das erreichen, nachdem die Combobox geöffnet wird.

So ist z.B. bei mir dann der Zweite Eintrag vormarkiert, als auch in das Combogadget kopiert. Eine andere Lösung wüste ich im Moment nicht :freak:

Code: Alles auswählen

Procedure cmbAutoComplete(WindowID, Message, wParam, lParam)
 
  Protected comboWert.s, comboIndex.l, comboLang.l, comboStart.l, parameter.l
  Protected start.l, ende.l
  result = #PB_ProcessPureBasicEvents
 
 
  Select Message
    Case #WM_COMMAND
      Select lParam
        Case GadgetID(0)
        If GetGadgetState(0)<0
          SetGadgetState(0, 1)
        EndIf
          Select (wParam >> 16 & $FFFF)
            Case #CBN_EDITUPDATE
             
              If GetAsyncKeyState_(#VK_BACK) Or GetAsyncKeyState_(#VK_DELETE)
                ;tu nix
              Else
                comboWert = GetGadgetText(#comboTest)
                comboIndex = SendMessage_(lParam, #CB_FINDSTRING, -1, @comboWert)
                comboStart = Len(comboWert)
                ;Länge des eingegebenen Textes
                SendMessage_(lParam, #CB_SETTOPINDEX, 1, 0)
                If comboIndex >= 0
                  SendMessage_(lParam, #CB_SETCURSEL, comboIndex, 0)
                  comboLang = Len(GetGadgetText(#comboTest))
                  ;Länge des gefundenen Textes
                  parameter = (comboLang << 16 & $FFFFFFFF) + comboStart
                  SendMessage_(lParam, #CB_SETEDITSEL, 0, parameter)
                  
                   
                EndIf
              EndIf
          EndSelect
      EndSelect
  EndSelect

  ProcedureReturn result
 
EndProcedure
Gruß, Falko

Verfasst: 26.10.2008 21:34
von Andi
Vielen Dank, Falko, für Deine Überlegungen. Sie könnten zum Erfolg führen. Ich habe nach der letzten Zeile in Deiner Callback-Prozedur, also nach

Code: Alles auswählen

SendMessage_(lParam, #CB_SETEDITSEL, 0, parameter)
noch Folgendes eingefügt:

Code: Alles auswählen

keybd_event_(#VK_DOWN, 0, 0, 0)
keybd_event_(#VK_END, 0, 0, 0)
Mit diesen beiden keybd-event-Zeilen wird der entsprechende Eintrag in der aufgeklappten Combobox markiert und ans Ende in der Eingabezeile gesprungen. Jetzt müsste ich nur noch vom Ende der Eingabezeile bei gehaltener Shift-Taste x-mal mit dem Cursor nach links gehen, wobei x = (Länge des Eintrags) minus (Anzahl der schon eingegebenen Buchstaben) ist, um auf diese Weise die Markierung des Restes wiederherzustellen. Meine Frage ist, wie kann ich die Cursor-Bewegung nach links bei gedrückter Shift-Taste simulieren. Geht das auch mit keybd_event?
Viele Grüße, Andi

Verfasst: 26.10.2008 22:10
von Falko
Hallo Andy,
ist das nicht so, wie nachfolgend abgebildet, wenn du auf die Combobox klickst?

Wenn nicht, dann könnte es Unterschiede zwischen der PB-Version oder dem OS sein,
weil ich unter Vista mit PB 4.3 Beta 4 das probiert habe.

Bild

Gruß Falko

Verfasst: 26.10.2008 22:22
von Andi
Ich benutze Win XP und PB 4.20 und bekomme leider nicht Dein Ergebnis. Ich musste erst einmal die Abfrage

Code: Alles auswählen

If GetGadgetState(0)<0
     SetGadgetState(0, 1)
EndIf
auskommentieren, damit es überhaupt lief. Und danach war es so wie zuvor, nämlich keine Markierung des entsprechenden Eintrags in der aufgeklappten Combobox-Liste. Schade!

Verfasst: 26.10.2008 23:00
von Falko
Hallo Andy, ich habe nun mal nach PB 4.2 alles umgestellt.
Du müßtest die Pathes umändern, wo sich deine Bilddateien als
auch die Textdatei befinden.

Habe diesen Source auch bei meinem Sohn unter XP-Professional auf seinem
Lappy getestet. Beide Einträge sind dort komplett Markiert.

Ein Fehler ist aber bei der PB 4.3 beta 4 nun zu sehen. Bei PB 4.2, wird die
erste Combobox schön einzeilig angezeigt. Bei der aktuellen Beta komischerweise wurden wohl mehrere Leerzeilen hinzugefügt :freak:

Code: Alles auswählen

;PB 3.94
;Der Karl
;updated 12.10.2006
;Updated to PB 4.2 by Falko

#comboTest = 0


Procedure cmbAutoComplete(WindowID, Message, wParam, lParam)
 
  Protected comboWert.s, comboIndex.l, comboLang.l, comboStart.l, parameter.l
  Protected start.l, ende.l
  result = #PB_ProcessPureBasicEvents
 
 
  Select Message
    Case #WM_COMMAND
      Select lParam
        Case GadgetID(0)
        If GetGadgetState(0)<0
          SetGadgetState(0, 1)
        EndIf
          Select (wParam >> 16 & $FFFF)
            Case #CBN_EDITUPDATE
             
              If GetAsyncKeyState_(#VK_BACK) Or GetAsyncKeyState_(#VK_DELETE)
                ;tu nix
              Else
                comboWert = GetGadgetText(#comboTest)
                comboIndex = SendMessage_(lParam, #CB_FINDSTRING, -1, @comboWert)
                comboStart = Len(comboWert)
                ;Länge des eingegebenen Textes
                SendMessage_(lParam, #CB_SETTOPINDEX, 1, 0)
                If comboIndex >= 0
                  SendMessage_(lParam, #CB_SETCURSEL, comboIndex, 0)
                  comboLang = Len(GetGadgetText(#comboTest))
                  ;Länge des gefundenen Textes
                  parameter = (comboLang << 16 & $FFFFFFFF) + comboStart
                  SendMessage_(lParam, #CB_SETEDITSEL, 0, parameter)
                  ;eybd_event_(#VK_DOWN, 0, 0, 0)
                  ;eybd_event_(#VK_END, 0, 0, 0) 
                EndIf
              EndIf
            EndSelect
      EndSelect
  EndSelect

  ProcedureReturn result
 
EndProcedure

Procedure InitWindow()
 
  ;Window zeichnen und ComboBox aus einer externen Datei füllen (jede Zeile = ein Eintrag)
 
  If OpenWindow(0, 0, 0, 400, 200, "Test", #PB_Window_SystemMenu)
    If CreateMenu(0, WindowID(0))
      MenuTitle("Datei")
      LoadImage(0, "F:\PureBasic_4\Falko\Forum\folder_page.bmp")
      LoadImage(1, "F:\PureBasic_4\Falko\Forum\printer.bmp")
        MenuItem(0, "Öffnen" + #TAB$ + "STRG+O")
        MenuItem(1, "Schließen")
        SetMenuItemBitmaps_(MenuID(0), 0, #MF_BYCOMMAND	, ImageID(0), ImageID(1)); hiernmit wird das BMP angezeigt
    EndIf
    If CreateGadgetList(WindowID(0))
      ComboBoxGadget(#comboTest, 10, 10, 180, 150, #PB_ComboBox_Editable)
    EndIf
    ReadFile(0, "F:\PureBasic_4\Falko\Forum\cmb.txt")
    While  Not Eof(0)
      AddGadgetItem(0, -1, ReadString(0))
    Wend 
     
 
    CloseFile(0)
  EndIf

EndProcedure


InitWindow()
SetWindowCallback(@cmbAutoComplete())

Repeat
 
Until WaitWindowEvent() = #PB_Event_CloseWindow

End 
So müsste es theoretisch dann auch bei dir unter XP aussehen:

Bild

Gruß, Falko

Verfasst: 26.10.2008 23:21
von Falko
Der Fehler liegt nicht an PB 4.3 beta. Ich habe im obigen Source das nochmal korrigiert.

http://www.purebasic.fr/german/viewtopi ... 021#217021

Gruß, Falko