Au fur et à mesure de la frappe une liste de mots est suggérée et proposée pour compléter automatiquement la chaîne entrée dans l'input
Plusieurs listes peuvent être codées en arrays et assignées ensuite à plusieurs inputs
► Afficher le texte
Code : Tout sélectionner
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <ListBoxConstants.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
Global $aPrenoms[8] = ["Alain", "André", "Albert", "Bernard", "Beatrice", "Antoine", "Charles", "Caroline"]
Global $aNoms[8] = ["Dupont", "David", "Martin", "Morin", "Dubois", "Lagrange", "Laborie", "Legrand"]
Global $hList, $idCurInput, $sCurrInput = "", $hListGUI = -1
$hGUI = GUICreate("AutoComplete Input Text", 300, 200)
GUICtrlCreateLabel('test avec les lettres "a, b, c" ', 10, 10, 280, 20)
$hInput = GUICtrlCreateInput("", 10, 30, 280, 20)
GUICtrlCreateLabel('test avec les lettres "a, b, c" ', 10, 70, 280, 20)
$hInput2 = GUICtrlCreateInput("", 10, 90, 280, 20)
GUICtrlCreateLabel('test avec les lettres "d, l, m" ', 10, 130, 280, 20)
$hInput3 = GUICtrlCreateInput("", 10, 150, 280, 20)
GUISetState(@SW_SHOW, $hGUI)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
EndSwitch
WEnd
Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
#forceref $hWnd, $Msg, $lParam
Local $IdFrom = BitAnd($wParam, 0x0000FFFF)
Local $iCode = BitShift($wParam, 16)
Switch $IdFrom
Case $hInput, $hInput2, $hInput3
Switch $iCode
Case $EN_UPDATE
$idCurInput = $IdFrom
_Update($idCurInput)
EndSwitch
Case $hList
_Update($idCurInput)
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
Func _Update($_input)
If GUICtrlRead($_Input) <> $sCurrInput Then
$sCurrInput = GUICtrlRead($_Input)
If $hListGUI <> -1 Then ; List is visible.
GUIDelete($hListGUI)
$hListGUI = -1
EndIf
Local $_array
Switch $_input
Case $hInput
$_array = $aPrenoms
Case $hInput2
$_array = $aPrenoms
Case $hInput3
$_array = $aNoms
EndSwitch
$hList = _PopupSelector($hGUI, $hListGUI, $_Input, _CheckInputText($_Input, $_array))
EndIf
Local $sChosen
If $hList <> -1 Then $sChosen = GUICtrlRead($hList)
If $sChosen <> "" Then
GuiCtrlSetData($_Input, $sChosen)
$sCurrInput = GUICtrlRead($_Input)
GUIDelete($hListGUI)
$hListGUI = -1
EndIf
EndFunc ;==>_Update
Func _PopupSelector($hMainGUI, ByRef $hListGUI, $_Input, $sCurr_List)
Local $hList = -1
If $sCurr_List = "" Then Return $hList
Local $pos = ControlGetPos($hMainGUI, "", $_Input)
$hListGUI = GUICreate("", 280, 160, $pos[0], $pos[1]+$pos[3], $WS_POPUP, _
BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST, $WS_EX_MDICHILD), $hMainGUI)
$hList = GUICtrlCreateList("", 0, 0, 280, 150, BitOR(0x00100000, 0x00200000))
GUICtrlSetData($hList, $sCurr_List)
Local $count = GUICtrlSendMsg($hList, $LB_GETCOUNT, 0, 0)
Local $iCurrHeight = $count * GUICtrlSendMsg($hList, $LB_GETITEMHEIGHT, 0, 0) + 10
WinMove($hListGUI, "", Default, Default, Default, $iCurrHeight)
GUICtrlSetPos($hList, 0, 0, 150, $iCurrHeight)
GUISetControlsVisible($hListGUI) ; To Make Control Visible And Window Invisible.
GUISetState(@SW_SHOWNOACTIVATE, $hListGUI)
Return $hList
EndFunc ;==>_PopupSelector
Func _CheckInputText($_Input, $array)
Local $sPartialData = ""
Local $aSelected = _GetSelectionPointers($_Input)
If (IsArray($aSelected)) And ($aSelected[0] <= $aSelected[1]) Then
$sCurrInput = GUICtrlRead($_Input)
Local $aSplit = StringSplit(StringLeft($sCurrInput, $aSelected[0]), " ")
$aSelected[0] -= StringLen($aSplit[$aSplit[0]])
If $aSplit[$aSplit[0]] <> "" Then
For $A = 0 To UBound($array)-1
If StringLeft($array[$A], StringLen($aSplit[$aSplit[0]])) = $aSplit[$aSplit[0]] _
And $array[$A] <> $aSplit[$aSplit[0]] Then
$sPartialData &= $array[$A] & "|"
EndIf
Next
EndIf
EndIf
Return $sPartialData
EndFunc ;==>_CheckInputText
Func _GetSelectionPointers($hEdit)
Local $aReturn[2] = [0, 0]
Local $aSelected = GUICtrlRecvMsg($hEdit, 0x00B0) ; $EM_GETSEL.
If IsArray($aSelected) Then
$aReturn[0] = $aSelected[0]
$aReturn[1] = $aSelected[1]
EndIf
Return $aReturn
EndFunc ;==>_GetSelectionPointers
Func GUISetControlsVisible($hWnd) ; By Melba23.
Local $aControlGetPos = 0, $hCreateRect = 0, $hRectRgn = _WinAPI_CreateRectRgn(0, 0, 0, 0)
Local $iLastControlID = _WinAPI_GetDlgCtrlID(GUICtrlGetHandle(-1))
For $i = 3 To $iLastControlID
$aControlGetPos = ControlGetPos($hWnd, '', $i)
If IsArray($aControlGetPos) = 0 Then ContinueLoop
$hCreateRect = _WinAPI_CreateRectRgn($aControlGetPos[0], $aControlGetPos[1], _
$aControlGetPos[0] + $aControlGetPos[2], $aControlGetPos[1] + $aControlGetPos[3])
_WinAPI_CombineRgn($hRectRgn, $hCreateRect, $hRectRgn, 2)
_WinAPI_DeleteObject($hCreateRect)
Next
_WinAPI_SetWindowRgn($hWnd, $hRectRgn, True)
_WinAPI_DeleteObject($hRectRgn)
EndFunc ;==>GUISetControlsVisible
Edit
Code adapté pour fonctionner avec les touches TAB et ENTER, et pour simplifier l'association input/array
Il est en mode évènementiel mais peut facilement être modifié pour le mode GuiGetMsg
Une seule précaution, s'il est intégré à un script qui utilise un GUIRegisterMsg($WM_COMMAND, "fonction") il faut adapter la fonction
► Afficher le texte
Code : Tout sélectionner
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <ListBoxConstants.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
Opt("GUIOnEventMode", 1)
Global $aPrenoms[8] = ["Alain", "André", "Albert", "Bernard", "Beatrice", "Antoine", "Charles", "Caroline"]
Global $aNoms[8] = ["Dupont", "David", "Martin", "Morin", "Dubois", "Lagrange", "Laborie", "Legrand"]
$hGUI = GUICreate("AutoComplete Input Text", 500, 200)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
GUICtrlCreateLabel('test avec les lettres "a, b, c" ', 10, 10, 280, 20)
$hInput = GUICtrlCreateInput("", 10, 30, 280, 20)
_Associate($hInput, $aPrenoms)
GUICtrlCreateLabel('test avec les lettres "a, b, c" ', 10, 70, 280, 20)
$hInput2 = GUICtrlCreateInput("", 10, 90, 280, 20)
_Associate($hInput2, $aPrenoms)
GUICtrlCreateLabel('test avec les lettres "d, l, m" ', 10, 130, 280, 20)
$hInput3 = GUICtrlCreateInput("", 10, 150, 280, 20)
_Associate($hInput3, $aNoms)
$edit = GuiCtrlCreateEdit("tralala", 310, 20, 180, 120)
$ok = GuiCtrlCreateButton("OK", 380, 150, 40, 25)
GUICtrlSetOnEvent(-1, "_ok")
GUISetState(@SW_SHOW, $hGUI)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
While 1
Sleep(10)
WEnd
Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
; #forceref $hWnd, $Msg, $lParam
Local $IdFrom = BitAnd($wParam, 0x0000FFFF)
Local $iCode = BitShift($wParam, 16)
Switch $iCode
Case $EN_UPDATE
GUISetAccelerators($AccelKeys)
$iCurrIndex = -1
$idCurInput = $IdFrom
_Update($idCurInput)
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
Func _ok()
Local $txt
If GuiCtrlRead($hInput)<>"" Then $txt &= GuiCtrlRead($hInput) &" "
If GuiCtrlRead($hInput2)<>"" Then $txt &= GuiCtrlRead($hInput2) &" "
If GuiCtrlRead($hInput3)<>"" Then $txt &= GuiCtrlRead($hInput3)
GuiCtrlSetData($edit, GuiCtrlRead($edit) &@crlf& $txt)
EndFunc
;============== fonctions internes ===================================
Func _Associate($_input, $_array)
Local Static $ub = 0
If $ub = 0 Then
Global $hListGUI = -1, $hList = -1, $idCurInput = "", $iCurrIndex = -1
Global $assoc[1][2] = [["0", "0"]]
_SetAccelerators()
EndIf
$ub += 1
Redim $assoc[$ub+1][2]
$assoc[$ub][0] = $_input
$assoc[$ub][1] = $_array
$assoc[0][0] = $ub
EndFunc
Func _SetAccelerators()
Global $hTAB, $hENTER, $AccelKeys
$hTAB = GUICtrlCreateDummy()
GUICtrlSetOnEvent(-1, "_Accelerators")
$hENTER = GUICtrlCreateDummy()
GUICtrlSetOnEvent(-1, "_Accelerators")
Dim $AccelKeys[2][2] = [["{TAB}", $hTAB], ["{ENTER}", $hENTER]]
EndFunc
Func _Accelerators()
Switch @GUI_CtrlId
Case $hTAB
If $hListGUI <> -1 Then
Local $count = GUICtrlSendMsg($hList, $LB_GETCOUNT, 0, 0)
If $count = 1 Then
GUICtrlSendMsg($hList, $LB_SETCURSEL, 0, 0)
_SetInput()
Else
$iCurrIndex = ($iCurrIndex > $count-2) ? 0 : ($iCurrIndex+1)
GUICtrlSendMsg($hList, $LB_SETCURSEL, $iCurrIndex, 0)
EndIf
Else
GUISetAccelerators("", $hGUI)
EndIf
Case $hENTER
If $hListGUI <> -1 Then
If $iCurrIndex = -1 Then GUICtrlSendMsg($hList, $LB_SETCURSEL, 0, 0)
_SetInput()
EndIf
EndSwitch
EndFunc
Func _Update($_input)
Local Static $sCurrInput = ""
If GUICtrlRead($_Input) <> $sCurrInput Then
$sCurrInput = GUICtrlRead($_Input)
If $hListGUI <> -1 Then ; List is visible.
GUIDelete($hListGUI)
$hListGUI = -1
EndIf
Local $_array
For $i = 1 to $assoc[0][0]
If $assoc[$i][0] = $_input Then $_array = $assoc[$i][1]
Next
$hList = _PopupSelector($hGUI, $hListGUI, $_Input, _CheckInputText($_Input, $_array))
If $hList <> -1 Then GUICtrlSetOnEvent($hList, "_SetInput")
EndIf
Local $sChosen
If $hList <> -1 Then
$sChosen = GUICtrlRead($hList)
If $sChosen <> "" Then
GuiCtrlSetData($_Input, $sChosen)
$sCurrInput = GUICtrlRead($_Input)
GUIDelete($hListGUI)
$hListGUI = -1
EndIf
EndIf
EndFunc ;==>_Update
Func _SetInput()
GuiCtrlSetData($idCurInput, GUICtrlRead($hList))
GUIDelete($hListGUI)
$hListGUI = -1
GUISetAccelerators("", $hGUI)
EndFunc
Func _PopupSelector($hMainGUI, ByRef $hListGUI, $_Input, $sCurr_List)
Local $hList = -1
If $sCurr_List = "" Then Return $hList
Local $pos = ControlGetPos($hMainGUI, "", $_Input)
$hListGUI = GUICreate("", 280, 160, $pos[0], $pos[1]+$pos[3], $WS_POPUP, _
BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST, $WS_EX_MDICHILD), $hMainGUI)
$hList = GUICtrlCreateList("", 0, 0, 280, 150, BitOR($LBS_STANDARD, $WS_HSCROLL))
GUICtrlSetData($hList, $sCurr_List)
Local $count = GUICtrlSendMsg($hList, $LB_GETCOUNT, 0, 0)
Local $iCurrHeight = $count * GUICtrlSendMsg($hList, $LB_GETITEMHEIGHT, 0, 0) + 10
WinMove($hListGUI, "", Default, Default, Default, $iCurrHeight)
GUICtrlSetPos($hList, 0, 0, 150, $iCurrHeight)
GUISetControlsVisible($hListGUI) ; To Make Control Visible And Window Invisible.
GUISetState(@SW_SHOWNOACTIVATE, $hListGUI)
Return $hList
EndFunc ;==>_PopupSelector
Func _CheckInputText($_Input, $array)
Local $sPartialData = ""
Local $aSelected = _GetSelectionPointers($_Input)
If (IsArray($aSelected)) And ($aSelected[0] <= $aSelected[1]) Then
Local $s_CurrInput = GUICtrlRead($_Input)
Local $aSplit = StringSplit(StringLeft($s_CurrInput, $aSelected[0]), " ")
$aSelected[0] -= StringLen($aSplit[$aSplit[0]])
If $aSplit[$aSplit[0]] <> "" Then
For $A = 0 To UBound($array)-1
If StringLeft($array[$A], StringLen($aSplit[$aSplit[0]])) = $aSplit[$aSplit[0]] _
And $array[$A] <> $aSplit[$aSplit[0]] Then
$sPartialData &= $array[$A] & "|"
EndIf
Next
EndIf
EndIf
Return $sPartialData
EndFunc ;==>_CheckInputText
Func _GetSelectionPointers($hEdit)
Local $aReturn[2] = [0, 0]
Local $aSelected = GUICtrlRecvMsg($hEdit, 0x00B0) ; $EM_GETSEL.
If IsArray($aSelected) Then
$aReturn[0] = $aSelected[0]
$aReturn[1] = $aSelected[1]
EndIf
Return $aReturn
EndFunc ;==>_GetSelectionPointers
Func GUISetControlsVisible($hWnd) ; By Melba23.
Local $aControlGetPos = 0, $hCreateRect = 0, $hRectRgn = _WinAPI_CreateRectRgn(0, 0, 0, 0)
Local $iLastControlID = _WinAPI_GetDlgCtrlID(GUICtrlGetHandle(-1))
For $i = 3 To $iLastControlID
$aControlGetPos = ControlGetPos($hWnd, '', $i)
If IsArray($aControlGetPos) = 0 Then ContinueLoop
$hCreateRect = _WinAPI_CreateRectRgn($aControlGetPos[0], $aControlGetPos[1], _
$aControlGetPos[0] + $aControlGetPos[2], $aControlGetPos[1] + $aControlGetPos[3])
_WinAPI_CombineRgn($hRectRgn, $hCreateRect, $hRectRgn, 2)
_WinAPI_DeleteObject($hCreateRect)
Next
_WinAPI_SetWindowRgn($hWnd, $hRectRgn, True)
_WinAPI_DeleteObject($hRectRgn)
EndFunc ;==>GUISetControlsVisible
Func _Exit()
Exit
EndFunc