Autocompletion

Programmation d'applications complexes
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Autocompletion

Message par Progi1984 »

Aprés avoir utilisé ce code ( http://www.purebasic.fr/english/viewtop ... 10&start=0 ), j'essaie de le passer en PB4 mais je n'y arrive pas :
[COMPILER] Ligne 152: Bad parameter type, number expected instead of string

Code : Tout sélectionner

;
Plus bas !
Dernière modification par Progi1984 le jeu. 13/juil./2006 11:03, modifié 3 fois.
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

Faut pas modifier la structure ainsi ?

Code : Tout sélectionner

Structure s_ACStringStructure
  FakeString.c[0]
EndStructure
???
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Voici le code mais il ne fonctionne àcause d'une IMA line 153

Code : Tout sélectionner

;
;- Coded by Xombie 12/19/2005
;
;- Enumeration
Enumeration ; Control Type Enumeration
   #ac_String
   #ac_Combo
EndEnumeration
;- Structures
Structure s_ACStringStructure
  FakeString.c[0]
EndStructure
Structure s_AutoComplete
   ;
   Gadget.l
   Handle.l
   Parent.l
   CallBack.l
   ; The old callback handle.
   ArrayAddress.l
   ; Only valid for edit controls, this will be the address of the first element in an array of strings.
EndStructure
;- Global Variables
Global NewList _ac_Main.s_AutoComplete()
;- Helper Functions
Procedure.b ac_GetGadgetType(Handle.l)
   ; Return the gadget type based on the classname used in CreateWindowExW_()
   HoldString.s
   ; This will store the length of the wide character string, in characters.
   lCount.l
   ; Used to store the number of character copied.
   HoldString = Space(255)
   ; Allocate size for our string.
   GetClassName_(Handle, @HoldString, 255)
   ; Call our function to retrieve the classname.
   If HoldString = "Edit"
      ProcedureReturn #ac_String
   ElseIf HoldString = "ComboBox"
      ProcedureReturn #ac_Combo
   EndIf
   ;
EndProcedure
Procedure.b ac_GadgetExists(Gadget.l)
   ;
   ResetList(_ac_Main())
   While NextElement(_ac_Main())
      If _ac_Main()\Gadget = Gadget : ProcedureReturn #True : EndIf
   Wend
   ;
   ProcedureReturn #False
   ;
EndProcedure
Procedure.b ac_GetOldCallback(Handle.l)
   ;
   ResetList(_ac_Main())
   While NextElement(_ac_Main())
      If _ac_Main()\Handle = Handle : ProcedureReturn _ac_Main()\CallBack : EndIf
   Wend
   ;
   ProcedureReturn -1
   ;
EndProcedure
;- Callback Functions
Procedure.l ac_HandleEditEvents(HandleWindow.l, Message.l, wParam.l, lParam.l)
   ; Custom callback for edit controls.
   lResult.l
   ;
   CallBack.l
   ;
   Gadget.l
   ;
   ArrayAddress.l
   ;
   iLoop.l
   ;
   HoldTotal.l
   ;
   HoldLength.l
   ;
   HoldCombinedLength.l
   ;
   HoldStart.l
   ;
   HoldEnd.l
   ;
   HoldSelection.l
   ;
   HoldString.s
   ;
   PreText.s
   ;
   PostText.s
   ;
   CombinedText.s
   ;
   MatchText.s
   ;
   *Position.s_ACStringStructure
   ; This will be a pointer to the strings in the array.
   CallBack = ac_GetOldCallback(HandleWindow)
   ; Return the old callback procedure address.
   If CallBack = -1 : ProcedureReturn : EndIf
   ; This should never happen as this callback is only set for autocomplete items.
   ResetList(_ac_Main())
   While NextElement(_ac_Main())
      If _ac_Main()\Handle = HandleWindow : ArrayAddress = _ac_Main()\ArrayAddress : Gadget = _ac_Main()\Gadget : Break : EndIf
   Wend
   ;
   HoldTotal = PeekL(ArrayAddress - 8)
   ; Return the number of items in the array.
   If HoldTotal = 0 : ProcedureReturn : EndIf
   ; No need to complete if 0 items.
   *Position = ArrayAddress
   ; Point to the first element in the array.
   If Message = #WM_CHAR
      ;
      HoldString = GetGadgetText(Gadget)
      ; Store the current text.
      HoldLength = Len(HoldString)
      ;
      SendMessage_(HandleWindow, #EM_GETSEL, @HoldStart, @HoldEnd)
      ; Store the start and end selection values.
      PreText = Mid(HoldString, 1, HoldStart)
      ; The text before the selection.
      PostText = Mid(HoldString, HoldEnd + 1, HoldLength - HoldEnd)
      ; The text after the selection.
      CombinedText = LCase(PreText + PostText + Chr(wParam))
      ;
      HoldCombinedLength = Len(CombinedText)
      ;
      For iLoop = 0 To HoldTotal - 1
         ; Loop through all items in the array.
         MatchText = PeekS(*Position\FakeString[iLoop])
         ; Store the text at index iLoop.  This little trick of getting the items in a array by addresses is thanks (again) to freak ( http://forums.purebasic.com/english/viewtopic.php?t=15366 )
         If LCase(Left(MatchText, HoldCombinedLength)) = CombinedText
            ; Found a matching item in the combobox.
            SetGadgetText(Gadget, MatchText)
            ;
            SendMessage_(HandleWindow, #EM_SETSEL, HoldCombinedLength, -1)
            ;
            wParam = 0
            ;
            Break
            ; Exit the loop.
         EndIf
         ;
      Next iLoop
      ;
      If wParam <> 0 : lResult = CallWindowProc_(CallBack, HandleWindow, Message, wParam, lParam) : EndIf
      ;
   Else
      ;
      lResult = CallWindowProc_(CallBack, HandleWindow, Message, wParam, lParam)
      ;
   EndIf
   ;
   ProcedureReturn lResult
   ;
EndProcedure
Procedure.l ac_HandleComboEvents(HandleWindow.l, Message.l, wParam.l, lParam.l)
   ; Custom callback for combobox controls.
   lResult.l
   ;
   CallBack.l
   ;
   Gadget.l
   ;
   Parent.l
   ;
   iLoop.l
   ;
   HoldTotal.l
   ;
   HoldLength.l
   ;
   HoldCombinedLength.l
   ;
   HoldStart.l
   ;
   HoldEnd.l
   ;
   HoldSelection.l
   ;
   HoldString.s
   ;
   PreText.s
   ;
   PostText.s
   ;
   CombinedText.s
   ;
   MatchText.s
   ;
   CallBack = ac_GetOldCallback(HandleWindow)
   ; Return the old callback procedure address.
   If CallBack = -1 : ProcedureReturn : EndIf
   ; This should never happen as this callback is only set for autocomplete items.
   ResetList(_ac_Main())
   While NextElement(_ac_Main())
      If _ac_Main()\Handle = HandleWindow : Parent = _ac_Main()\Parent : Gadget = _ac_Main()\Gadget : Break : EndIf
   Wend
   ; Retrieve the handle to the combobox and the gadget id.
   If Message = #WM_CHAR
      ;
      HoldTotal = SendMessage_(Parent, #CB_GETCOUNT, 0, 0)
      ; Return the number of items in the combobox.
      If HoldTotal
         ; Only need to check for autocompletion if items exist in the combobox.
         HoldString = GetGadgetText(Gadget)
         ; Store the current combobox text.
         HoldLength = Len(HoldString)
         ;
         SendMessage_(Parent, #CB_GETEDITSEL, @HoldStart, @HoldEnd)
         ; Store the start and end selection values.
         PreText = Mid(HoldString, 1, HoldStart)
         ; The text before the selection.
         PostText = Mid(HoldString, HoldEnd + 1, HoldLength - HoldEnd)
         ; The text after the selection.
         CombinedText = LCase(PreText + PostText + Chr(wParam))
         ;
         HoldCombinedLength = Len(CombinedText)
         ;
         For iLoop = 0 To HoldTotal - 1
            ; Loop through all items in the combo box.
            MatchText = GetGadgetItemText(Gadget, iLoop, 0)
            ; Store the text at index iLoop.
            If LCase(Left(MatchText, HoldCombinedLength)) = CombinedText
               ; Found a matching item in the combobox.
               SetGadgetText(Gadget, MatchText)
               ;
               HoldSelection = HoldCombinedLength | -1 << 16
               ; Convert the start and end selection into an lParam.  The start position is the combined length of the pre
               ; and post text.  The end is set to -1 to select the rest of the text.
               SendMessage_(Parent, #CB_SETEDITSEL, 0, HoldSelection)
               ;
               wParam = 0
               ;
               Break
               ; Exit the loop.
            EndIf
            ;
         Next iLoop
         ;
         If wParam <> 0 : lResult = CallWindowProc_(CallBack, HandleWindow, Message, wParam, lParam) : EndIf
         ;
      Else
         ;
         lResult = CallWindowProc_(CallBack, HandleWindow, Message, wParam, lParam)
         ;
      EndIf
      ;
   Else
      ;
      lResult = CallWindowProc_(CallBack, HandleWindow, Message, wParam, lParam)
      ;
   EndIf
   ;
   ProcedureReturn lResult
   ;
EndProcedure
;- Main Functions
Procedure ac_SetAutocomplete(Gadget.l, EditGadgetArrayAddress.l)
   ; EditGadgetArrayAddress is exactly that.  The address to the first element of a plain string array.  This will be used
   ; for the autocompletion list.  Feel free to modify this to handle linked lists or whatever.  It will be ignored for combobox.
   Type.b
   ;
   Handle.l
   ;
   If ac_GadgetExists(Gadget) : ProcedureReturn : EndIf
   ; Check if the gadget already exists in the autocomplete list.
   Handle = GadgetID(Gadget)
   ;
   Type = ac_GetGadgetType(Handle)
   ;
   If Type = #ac_String
      ; String type.
      If EditGadgetArrayAddress = 0 : ProcedureReturn : EndIf
      ; An edit control must be associated with an array address.
      AddElement(_ac_Main())
      ;
      _ac_Main()\Gadget = Gadget
      _ac_Main()\Handle = Handle
      ; The handle to the edit control.
      _ac_Main()\Parent = 0
      ; An edit control is not like a combobox.  Does not have a parent container.
      _ac_Main()\CallBack = SetWindowLong_(Handle, #GWL_WNDPROC, @ac_HandleEditEvents())
      ; The callback will be set for the edit control, not the combobox.
      _ac_Main()\ArrayAddress = EditGadgetArrayAddress
      ;
   ElseIf Type = #ac_Combo
      ; Combobox type
      AddElement(_ac_Main())
      ;
      _ac_Main()\Gadget = Gadget
      _ac_Main()\Handle = GetWindow_(Handle, #GW_CHILD)
      ; This is the handle to the edit control within the combobox.  I think I got this little tidbit from fr34k but don't quote me on that.
      _ac_Main()\Parent = Handle
      ; This will be the handle to the combobox control.
      _ac_Main()\CallBack = SetWindowLong_(_ac_Main()\Handle, #GWL_WNDPROC, @ac_HandleComboEvents())
      ; The callback will be set for the edit control, not the combobox.
      _ac_Main()\ArrayAddress = 0
      ;
   Else
      ; Not a combo or string type.  Currently, no other controls are supported.
      ProcedureReturn
      ;
   EndIf
   ;
EndProcedure
Procedure ac_RemoveAutocomplete(Gadget.l)
   ;
   Handle.l
   ;
   If ac_GadgetExists(Gadget) : ProcedureReturn : EndIf
   ; Check if the gadget already exists in the autocomplete list.
   Handle = GadgetID(Gadget)
   ;
   ResetList(_ac_Main())
   While NextElement(_ac_Main())
      If _ac_Main()\Gadget = Gadget : SetWindowLong_(Handle, #GWL_WNDPROC, _ac_Main()\CallBack) : Break : EndIf
   Wend
   ;
EndProcedure
Procedure ac_DestroyAutocomplete()
   ; Remove all autocomplete items.
   If CountList(_ac_Main()) = 0 : ProcedureReturn : EndIf
   ; No need to destroy if no items in the list.
   ResetList(_ac_Main())
   While NextElement(_ac_Main())
      SetWindowLong_(Handle, #GWL_WNDPROC, _ac_Main()\CallBack)
   Wend
   ;
EndProcedure

;By Xombie - 12/12/2005
;
Enumeration ; Window List
   #WindowMain
EndEnumeration
Enumeration ; Menu List
   #MenuMain
EndEnumeration
Enumeration ; Control List
   #ButtonTest
   #StringTest
   #StringTest2
   #ComboTest
EndEnumeration
;- Global Variables
Dim Array01.s(10)
Dim array02.s(20)
;- Includes

;- Main Program
DoQuit.b
;
If OpenWindow(#WindowMain, 100, 300, 300, 200, "Test", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
   ;
   If CreateGadgetList(WindowID(#WindowMain))
      ;AdvancedGadgetEvents(#True)
      StringGadget(#StringTest, 0, 0, 100, 20, "")
      StringGadget(#StringTest2, 0, 21, 100, 20, "")
      ComboBoxGadget(#ComboTest, GadgetX(#StringTest2), GadgetY(#StringTest2) + GadgetHeight(#StringTest2) + 1, 100, 200, #PB_ComboBox_Editable)
      ButtonGadget(#ButtonTest, GadgetX(#ComboTest), GadgetY(#ComboTest) + GadgetHeight(#ComboTest) + 1, 100, 20, "Test")
   EndIf
   ;
   ;{ Create autocomplete lists
   ;
   ;/ Create items for the combobox.
   AddGadgetItem(#ComboTest, -1, "One")
   AddGadgetItem(#ComboTest, -1, "Two")
   AddGadgetItem(#ComboTest, -1, "Three")
   AddGadgetItem(#ComboTest, -1, "Four")
   AddGadgetItem(#ComboTest, -1, "Five")
   AddGadgetItem(#ComboTest, -1, "Six")
   AddGadgetItem(#ComboTest, -1, "Seven")
   AddGadgetItem(#ComboTest, -1, "Eight")
   AddGadgetItem(#ComboTest, -1, "Nine")
   AddGadgetItem(#ComboTest, -1, "Ten")
   AddGadgetItem(#ComboTest, -1, "The")
   AddGadgetItem(#ComboTest, -1, "quick")
   AddGadgetItem(#ComboTest, -1, "brown")
   AddGadgetItem(#ComboTest, -1, "fox")
   AddGadgetItem(#ComboTest, -1, "jumped")
   AddGadgetItem(#ComboTest, -1, "over")
   AddGadgetItem(#ComboTest, -1, "the")
   AddGadgetItem(#ComboTest, -1, "two")
   AddGadgetItem(#ComboTest, -1, "lazy")
   AddGadgetItem(#ComboTest, -1, "dogs")
   ;/ Create items for the first string
   Array01(0) = "Jack"
   Array01(1) = "and"
   Array01(2) = "Jill"
   Array01(3) = "went"
   Array01(4) = "up"
   Array01(5) = "the"
   Array01(6) = "hill"
   Array01(7) = "to"
   Array01(8) = "fetch"
   Array01(9) = "a"
   Array01(10) = "pail"
   ;/ Create items for the second string
   array02(0) = "Jack"
   array02(1) = "Sprat"
   array02(2) = "could"
   array02(3) = "eat"
   array02(4) = "no"
   array02(5) = "fat"
   array02(6) = "and"
   array02(7) = "his"
   array02(8) = "wife"
   array02(9) = "could"
   array02(10) = "eat"
   array02(11) = "no"
   array02(12) = "lean"
   array02(13) = "but"
   array02(14) = "between"
   array02(15) = "the"
   array02(16) = "both"
   array02(17) = "of"
   array02(18) = "them"
   array02(19) = "they"
   array02(20) = "licked"
   ;}
   ;
   ac_SetAutocomplete(#StringTest, @Array01())
   ;
   ac_SetAutocomplete(#StringTest2, @array02())
   ;
   ac_SetAutocomplete(#ComboTest, 0)
   ;
   Repeat
      ;
      EventID.l = WaitWindowEvent()
      ;
      If EventID = #PB_Event_CloseWindow  ; If the user has pressed on the close button
         ;
         DoQuit = #True
         ;
      ElseIf EventID = #PB_Event_Gadget
         ;
         If EventGadget() = #ButtonTest
            ;
            If EventType() = #PB_EventType_LeftClick
               ;
               ;
            EndIf
            ;
         EndIf
         ;
      EndIf
      ;
   Until DoQuit = #True

EndIf

ac_DestroyAutocomplete()
; Remove all autocompleting items.
End
Répondre