Dans mon projet,j'avais besoin d'un StringGadget avec auto-complétion comme dans l'éditeur PureBasic . Après avoir trouvé sur le forum un code avec un ComboBox, je l'ai adapté a mes besoins .
Le code est pleinement fonctionnel avec PB4.61 Vista et Seven . Il a quelques défauts que je comblerais au fur et à mesure
AC_StringGadget.pbi :
Code : Tout sélectionner
;/////////////////////////////////////////////////////////////////////
;/ AC_String_Gadget
;/
;/ StringGadget avec autocomplétion
;/
;/ Date : 28/06/2012
;/
;/ Auteurs : Ebs,LSI,Nico,Wood51
;/
;/ Bricolage : Wood51
;/ Procedure d'autocomplétion : Ebs réadapter par LSI
;/ Astuce pour les callbacks : Nico
;/
;////////////////////////////////////////////////////////////////////
;- TODO
;{
; Gestion des touches ---- OK
; Gestion click dans le ListView ---- OK
; Cacher Afficher ListView ---- OK
; Timer pour affichage de la listbox
; Reverifier variable pour activé EnableExplicite ---- OK
; Déclaration des procedures ---- OK
; Commenter le code
; Faire Fichier PBI ---- OK
;
; PROBLEMES
; Selection text string lors du déplacement avec les flèches
; Redonner le focus au stringgadget après click sur listview
;}
EnableExplicit
;- Structure
;{
Structure Lst
Text.s
Affiche.i
EndStructure
Structure ACStringInfo
ID_Edit.i
ID_List.i
ListHeight.i
EndStructure
;}
;- Variables
;{
Global NewList Liste.Lst()
Global ACS.ACStringInfo
Global Keep_EN_CHANGE = 0
Global oldEditProc.i,oldListProc.i
;}
;- Declaration des procedures
;{
Declare LoWord(value)
Declare HiWord(value)
Declare AddToList(String.s)
Declare UpdateListView()
Declare SearchInList()
Declare ListProc(hWnd.i, uMsg.i, wParam.i, lParam.i)
Declare EditProc(hWnd.i, uMsg.i, wParam.i, lParam.i)
Declare AC_StringGadgetProc(hWnd.i,uMsg.i,wParam.i,lParam.i)
Declare AC_StringGadget(Gadget,x,y,w,h,lh)
;}
;- Procedure
;{
Procedure LoWord(value)
ProcedureReturn value & $FFFF
EndProcedure
Procedure HiWord(value)
ProcedureReturn value >> 16 & $FFFF
EndProcedure
Procedure AddToList(String.s)
Protected Result.i
If ACS\ID_List
Result=AddElement(Liste())
If Result
Liste()\Text = String
Liste()\Affiche = 1
SortStructuredList(Liste(), #PB_Sort_Ascending, OffsetOf(Lst\Text), #PB_Sort_String)
EndIf
EndIf
UpdateListView()
EndProcedure
Procedure UpdateListView()
ClearGadgetItems(ACS\ID_List)
ResetList(Liste())
While NextElement(Liste())
If Liste()\Affiche = 1
AddGadgetItem(ACS\ID_List,-1,Liste()\Text)
EndIf
Wend
EndProcedure
Procedure SearchInList()
Protected.s TextTyped,ItemText
Protected.i LenTextSave,LenTextTyped,ItemCount,Item
Protected.i Selection_Start,Selection_End
Keep_EN_CHANGE = 1 ; pour éviter l'auto apel avec le message #EN_CHANGE
;Texte tapé et sa longueur
TextTyped = GetGadgetText(ACS\ID_Edit)
LenTextTyped = Len(TextTyped)
;Maj Liste chainée
ResetList(Liste())
While NextElement(Liste())
If UCase(Left(TextTyped,LenTextTyped)) = UCase(Left(Liste()\Text,LenTextTyped))
Liste()\Affiche = 1
Else
Liste()\Affiche = 0
EndIf
Wend
;Maj du ListView
ClearGadgetItems(ACS\ID_List)
ResetList(Liste())
While NextElement(Liste())
If Liste()\Affiche = 1
AddGadgetItem(ACS\ID_List,-1,Liste()\Text)
EndIf
Wend
LenTextSave = GetGadgetData(ACS\ID_Edit)
If LenTextTyped <= LenTextSave
SetGadgetData(ACS\ID_Edit, LenTextTyped)
Else
;Selection dans le ListView
ItemCount = CountGadgetItems(ACS\ID_List)
For Item = 0 To ItemCount - 1
ItemText.s = GetGadgetItemText(ACS\ID_List,Item)
If UCase(TextTyped) = UCase(Left(ItemText,LenTextTyped))
SetGadgetState(ACS\ID_List,Item)
Selection_Start = LenTextTyped
Selection_End = Len(ItemText)
SetGadgetText(ACS\ID_Edit,ItemText)
SendMessage_(GadgetID(ACS\ID_Edit), #EM_SETSEL, Selection_Start, Selection_End)
SetGadgetData(ACS\ID_Edit, LenTextTyped)
Break
EndIf
Next
EndIf
Keep_EN_CHANGE = 0
EndProcedure
;- Event Loop (List)
Procedure ListProc(hWnd.i, uMsg.i, wParam.i, lParam.i)
Protected OriginProc.i
Protected Item.i
OriginProc = GetProp_(hWnd, "OriginProc")
Select uMsg
Case #WM_LBUTTONUP
;Debug "Click"
Keep_EN_CHANGE = 1
SetActiveGadget(ACS\ID_List)
Item=GetGadgetState(ACS\ID_List)
SetGadgetText(ACS\ID_Edit,GetGadgetItemText(ACS\ID_List,Item))
HideGadget(ACS\ID_List,1)
Keep_EN_CHANGE = 0
Case #WM_NCDESTROY
SetWindowLong_(Hwnd, #GWL_WNDPROC, OriginProc)
RemoveProp_(Hwnd, "OriginProc")
EndSelect
ProcedureReturn CallWindowProc_(OriginProc, Hwnd, uMsg, wParam, lParam)
EndProcedure
;- Event Loop (Edit)
Procedure EditProc(hWnd.i, uMsg.i, wParam.i, lParam.i)
Protected OriginProc.i
Protected ItemText.s
Static Item.i = 0
OriginProc = GetProp_(hWnd, "OriginProc")
Select uMsg
Case #WM_KEYDOWN
Select wParam
Case #VK_DOWN
If Item < CountGadgetItems(ACS\ID_List)-1
Item = Item + 1
;Debug Item
EndIf
SetGadgetState(ACS\ID_List,Item)
If CountGadgetItems(ACS\ID_List) = 0
HideGadget(ACS\ID_List,1)
Else
HideGadget(ACS\ID_List,0)
EndIf
Keep_EN_CHANGE = 1
ItemText.s=GetGadgetItemText(ACS\ID_List,Item)
SetGadgetText(ACS\ID_Edit,ItemText)
Keep_EN_CHANGE = 0
Case #VK_UP
If Item > 0
Item = Item - 1
;Debug Item
EndIf
SetGadgetState(ACS\ID_List,Item)
HideGadget(ACS\ID_List,0)
Keep_EN_CHANGE = 1
ItemText.s=GetGadgetItemText(ACS\ID_List,Item)
SetGadgetText(ACS\ID_Edit,ItemText)
Keep_EN_CHANGE = 0
Case #VK_RETURN
SetGadgetText(ACS\ID_Edit,GetGadgetText(ACS\ID_List))
HideGadget(ACS\ID_List,1)
Case #VK_ESCAPE
SetGadgetText(ACS\ID_Edit,"")
SetGadgetState(ACS\ID_List,0)
HideGadget(ACS\ID_List,1)
EndSelect
Case #WM_KEYDOWN
ProcedureReturn CallWindowProc_(OriginProc, hWnd, uMsg, wParam, lParam)
Case #WM_NCDESTROY
SetWindowLong_(hWnd, #GWL_WNDPROC, OriginProc)
RemoveProp_(hWnd, "OriginProc")
EndSelect
ProcedureReturn CallWindowProc_(OriginProc, hWnd, uMsg, wParam, lParam)
EndProcedure
;- Event Loop (AC_StringGadget)
Procedure AC_StringGadgetProc(hWnd,uMsg,wParam,lParam)
Protected result.i
result = #PB_ProcessPureBasicEvents
Select uMsg
Case #WM_COMMAND
If (HiWord(wParam) = #EN_CHANGE) And (lParam = GadgetID(ACS\ID_Edit))
;Debug "#EN_CHANGE"
If Keep_EN_CHANGE = 0
HideGadget(ACS\ID_List,0)
SearchInList()
If CountGadgetItems(ACS\ID_List) = 0
HideGadget(ACS\ID_List,1)
EndIf
EndIf
EndIf
EndSelect
ProcedureReturn result
EndProcedure
Procedure AC_StringGadget(Gadget,x,y,w,h,lh)
ACS\ID_Edit=Gadget
If StringGadget(Gadget,x,y,w,h,"")
ACS\ID_List=ListViewGadget(#PB_Any,x,y+GadgetHeight(Gadget),w,lh,#LBS_NOTIFY)
If ACS\ID_List
SetActiveGadget(ACS\ID_Edit)
SetGadgetState(ACS\ID_List,0)
HideGadget(ACS\ID_List,1)
oldEditProc=SetWindowLong_(GadgetID(ACS\ID_Edit),#GWL_WNDPROC,@EditProc())
SetProp_(GadgetID(ACS\ID_Edit), "OriginProc", oldEditProc)
oldListProc=SetWindowLong_(GadgetID(ACS\ID_List),#GWL_WNDPROC,@ListProc())
SetProp_(GadgetID(ACS\ID_List), "OriginProc", oldListProc)
SetWindowCallback(@AC_StringGadgetProc())
EndIf
EndIf
EndProcedure
;}
DisableExplicit
Code : Tout sélectionner
XIncludeFile "AC_StringGadget.pbi"
If OpenWindow(0,0,0,300,150,"StringGadgetEx",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
AC_StringGadget(1,50,10,200,20,100)
EndIf
AddToList("AS250M150V3")
AddToList("AS250L250V2")
AddToList("AS250/100V2")
AddToList("AS250M130-16V4")
AddToList("AS250M160")
AddToList("AB100V2")
AddToList("AC100")
AddToList("AS280L240-28V6")
AddToList("AS280L240-28V5")
AddToList("AS280L240-28V8")
AddToList("AB100V3")
AddToList("AS180L170")
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = 0
CloseWindow(0)
Break
EndIf
EndSelect
ForEver
Code : Tout sélectionner
AC_StringGadget(x,y,width,height,hauteur_listview) // Création du gadget
AddToList(texte) // Ajout à la liste pour l'auto-complétion
@+ David