Lupo73 Posted January 21, 2014 Share Posted January 21, 2014 I found different solutions to do it and I finally decided to merge them in a single "optimal" code. During the typing it checks each new word (from the previous whitespace to the current pointer) and proposes to complete it with words included in a array. Predicted words are shown in a list under the input field and can be selected with mouse or with up/down/enter keys. These are the sources considered to create this code: '?do=embed' frameborder='0' data-embedContent>> '?do=embed' frameborder='0' data-embedContent>> '?do=embed' frameborder='0' data-embedContent>> '?do=embed' frameborder='0' data-embedContent>> '?do=embed' frameborder='0' data-embedContent>> '?do=embed' frameborder='0' data-embedContent>> And this is the code: expandcollapse popup#include <GUIConstantsEx.au3> #include <WinAPI.au3> #Include <GuiListBox.au3> #include <WindowsConstants.au3> Global $asKeyWords[21] = [20, "fight", "first", "fly", "third", "fire", "wall", "hi", "hello", "world", "window", _ "window 1", "window 2", "window 3", "window 4", "window 5", "window 6", "window 7", "window 8", "window 9", "window 10"] _Main() Func _Main() Local $hGUI, $hList, $hInput, $aSelected, $sChosen, $hUP, $hDOWN, $hENTER, $hESC Local $sCurrInput = "", $aCurrSelected[2] = [-1, -1], $iCurrIndex = -1, $hListGUI = -1 $hGUI = GUICreate("AutoComplete Input Text", 300, 100) GUICtrlCreateLabel('Start to type words like "window" or "fire" to test it:', 10, 10, 280, 20) $hInput = GUICtrlCreateInput("", 10, 40, 280, 20) GUISetState(@SW_SHOW, $hGUI) $hUP = GUICtrlCreateDummy() $hDOWN = GUICtrlCreateDummy() $hENTER = GUICtrlCreateDummy() $hESC = GUICtrlCreateDummy() Dim $AccelKeys[4][2] = [["{UP}", $hUP], ["{DOWN}", $hDOWN], ["{ENTER}", $hENTER], ["{ESC}", $hESC]] GUISetAccelerators($AccelKeys) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $hESC If $hListGUI <> -1 Then ; List is visible. GUIDelete($hListGUI) $hListGUI = -1 Else ExitLoop EndIf Case $hUP If $hListGUI <> -1 Then ; List is visible. $iCurrIndex -= 1 If $iCurrIndex < 0 Then $iCurrIndex = 0 EndIf _GUICtrlListBox_SetCurSel($hList, $iCurrIndex) EndIf Case $hDOWN If $hListGUI <> -1 Then ; List is visible. $iCurrIndex += 1 If $iCurrIndex > _GUICtrlListBox_GetCount($hList) - 1 Then $iCurrIndex = _GUICtrlListBox_GetCount($hList) - 1 EndIf _GUICtrlListBox_SetCurSel($hList, $iCurrIndex) EndIf Case $hENTER If $hListGUI <> -1 And $iCurrIndex <> -1 Then ; List is visible and a item is selected. $sChosen = _GUICtrlListBox_GetText($hList, $iCurrIndex) EndIf Case $hList $sChosen = GUICtrlRead($hList) EndSwitch Sleep(10) $aSelected = _GetSelectionPointers($hInput) If GUICtrlRead($hInput) <> $sCurrInput Or $aSelected[1] <> $aCurrSelected[1] Then ; Input content or pointer are changed. $sCurrInput = GUICtrlRead($hInput) $aCurrSelected = $aSelected ; Get pointers of the string to replace. $iCurrIndex = -1 If $hListGUI <> -1 Then ; List is visible. GUIDelete($hListGUI) $hListGUI = -1 EndIf $hList = _PopupSelector($hGUI, $hListGUI, _CheckInputText($sCurrInput, $aCurrSelected)) ; ByRef $hListGUI, $aCurrSelected. EndIf If $sChosen <> "" Then GUICtrlSendMsg($hInput, 0x00B1, $aCurrSelected[0], $aCurrSelected[1]) ; $EM_SETSEL. _InsertText($hInput, $sChosen) $sCurrInput = GUICtrlRead($hInput) GUIDelete($hListGUI) $hListGUI = -1 $sChosen = "" EndIf WEnd GUIDelete($hGUI) EndFunc ;==>_Main Func _CheckInputText($sCurrInput, ByRef $aSelected) Local $sPartialData = "" If (IsArray($aSelected)) And ($aSelected[0] <= $aSelected[1]) Then Local $aSplit = StringSplit(StringLeft($sCurrInput, $aSelected[0]), " ") $aSelected[0] -= StringLen($aSplit[$aSplit[0]]) If $aSplit[$aSplit[0]] <> "" Then For $A = 1 To $asKeyWords[0] If StringLeft($asKeyWords[$A], StringLen($aSplit[$aSplit[0]])) = $aSplit[$aSplit[0]] And $asKeyWords[$A] <> $aSplit[$aSplit[0]] Then $sPartialData &= $asKeyWords[$A] & "|" EndIf Next EndIf EndIf Return $sPartialData EndFunc ;==>_CheckInputText Func _PopupSelector($hMainGUI, ByRef $hListGUI, $sCurr_List) Local $hList = -1 If $sCurr_List = "" Then Return $hList EndIf $hListGUI = GUICreate("", 280, 160, 10, 62, $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) GUISetControlsVisible($hListGUI) ; To Make Control Visible And Window Invisible. GUISetState(@SW_SHOWNOACTIVATE, $hListGUI) Return $hList EndFunc ;==>_PopupSelector Func _InsertText(ByRef $hEdit, $sString) #cs Description: Insert A Text In A Control. Returns: Nothing #ce Local $aSelected = _GetSelectionPointers($hEdit) GUICtrlSetData($hEdit, StringLeft(GUICtrlRead($hEdit), $aSelected[0]) & $sString & StringTrimLeft(GUICtrlRead($hEdit), $aSelected[1])) Local $iCursorPlace = StringLen(StringLeft(GUICtrlRead($hEdit), $aSelected[0]) & $sString) GUICtrlSendMsg($hEdit, 0x00B1, $iCursorPlace, $iCursorPlace) ; $EM_SETSEL. EndFunc ;==>_InsertText 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 Any advice to improve the code is welcome. yutijang, mikell, babullika and 1 other 4 SFTPEx, AutoCompleteInput, _DateTimeStandard(), _ImageWriteResize(), _GUIGraduallyHide(): some AutoIt functions. Lupo PenSuite: all-in-one and completely free selection of portable programs and games. DropIt: a personal assistant to automatically manage your files. ArcThemALL!: application to multi-archive your files and folders. Link to comment Share on other sites More sharing options...
mikell Posted February 20, 2014 Share Posted February 20, 2014 Nice compact code I appreciate the very handy 'select with mouse' feature, it's a lack in Phoenix' PredictText udf May I suggest something like this (raw) to make the list auto-resizable Func _PopupSelector ; ... StringReplace($sCurr_List, "|", "|") Local $iCurrHeight = @extended*GUICtrlSendMsg($hList, $LB_GETITEMHEIGHT, 0, 0)+10 WinMove($hListGUI, "", Default, Default, Default, $iCurrHeight) GUICtrlSetPos($hList, 0, 0, 150, $iCurrHeight) Link to comment Share on other sites More sharing options...
PhoenixXL Posted February 20, 2014 Share Posted February 20, 2014 (edited) I appreciate the very handy 'select with mouse' feature, it's a lack in Phoenix' PredictText udf Mikell, Maybe you have missed the update that I made on 1st Feb. Do check it out, if you use the PredictText UDF. Edit : It was due to a bug, now is cleared. Regards Edited February 20, 2014 by PhoenixXL My code: PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners. MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression. Link to comment Share on other sites More sharing options...
mikell Posted February 20, 2014 Share Posted February 20, 2014 Much nicer Phoenix, thanks However to fit my personal needs I managed to use this slight modif of Lupo's code for working with several inputs in the same gui expandcollapse popup; http://www.autoitscript.com/forum/topic/158070-autocomplete-input-text/ #include <GUIConstantsEx.au3> #include <WinAPI.au3> #include <ListBoxConstants.au3> #include <WindowsConstants.au3> #include <EditConstants.au3> Global $Words1[20] = ["fight", "first", "fly", "third", "fire", "wall", "hi", "hello", "world", "window", _ "window 1", "window 2", "window 3", "window 4", "window 5", "window 6", "window 7", "window 8", "window 9", "window 10"] Global $Words2[6] = ["Alain", "Aline", "Bernard", "Beatrice", "Chloe", "Caroline"] Global $hGUI, $hList Global $sChosen, $idCurInput, $sCurrInput = "", $hListGUI = -1 $hGUI = GUICreate("AutoComplete Input Text", 300, 200) GUICtrlCreateLabel('lettres "w, f" ', 10, 10, 280, 20) $hInput = GUICtrlCreateInput("", 10, 40, 280, 20) GUICtrlCreateLabel('lettres "a, b, c" ', 10, 70, 280, 20) $hInput2 = GUICtrlCreateInput("", 10, 100, 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) Local $IdFrom = BitAnd($wParam, 0x0000FFFF) Local $iCode = BitShift($wParam, 16) Switch $IdFrom Case $hInput, $hInput2 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 = $Words1 Case $hInput2 $_array = $Words2 EndSwitch $hList = _PopupSelector($hGUI, $hListGUI, $_Input, _CheckInputText($_Input, $_array)) EndIf If $hList <> -1 Then $sChosen = GUICtrlRead($hList) If $sChosen <> "" Then GuiCtrlSetData($_Input, $sChosen) $sCurrInput = GUICtrlRead($_Input) GUIDelete($hListGUI) $hListGUI = -1 $sChosen = "" EndIf 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(0x00100000, 0x00200000)) StringReplace($sCurr_List, "|", "|") Local $iCurrHeight = @extended*GUICtrlSendMsg($hList, $LB_GETITEMHEIGHT, 0, 0)+10 WinMove($hListGUI, "", Default, Default, Default, $iCurrHeight) GUICtrlSetPos($hList, 0, 0, 150, $iCurrHeight) GUICtrlSetData($hList, $sCurr_List) GUISetControlsVisible($hListGUI) ; To Make Control Visible And Window Invisible. GUISetState(@SW_SHOWNOACTIVATE, $hListGUI) Return $hList EndFunc ;==>_PopupSelector Func _CheckInputText($_Input, $array) Local $sPartialData = "" $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 Link to comment Share on other sites More sharing options...
hyperjase Posted November 28, 2014 Share Posted November 28, 2014 This looks like it fits my needs perfectly but I'm having an issue. I have to create the list dynamically from Active Directory. When I alter the code to use the array (and also count of array) it doesn't work ... I'm quite new with AutoIT but I thought this would work? $Array = Chr(34) & $objRecordSet.Fields ("displayName").Value & Chr(34) $Count = 1 While Not $objRecordSet.EOF $Array = $Array & ", " & Chr(34) & $objRecordSet.Fields ("displayName").Value & Chr(34) $Count = $Count + 1 $objRecordSet.MoveNext WEnd $objConnection.Close $objConnection = "" $objCommand = "" $objRecordSet = "" Global $asKeyWords[($Count + 1)] = [$Count, $Array] This is only the part where it creates the $Array, adds the required comma and double quotes for each one (outputting the $Array to console shows it's correct and checking the $Count also shows there is a valid figure). What am I missing here? Link to comment Share on other sites More sharing options...
z0iid Posted March 11, 2015 Share Posted March 11, 2015 I like the script, and I've found a good use for it. One enhancement I'm struggling to add, is the ability to either autocomplete based on any matching (e.g., word in dictionary: dictionary -- typing starts out with "ary", I would want it to match) OR if there are two words, that it would also match based on the second word. I imagine with the two words, I would be doing a string split based on a space as the delimiter, and edit the _checkinputtext function accordingly to check both parts of the string split. Any thoughts on the best way to approach this? Link to comment Share on other sites More sharing options...
satanico64 Posted November 27, 2015 Share Posted November 27, 2015 Very nice. You save me a lot of time.Thank you. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now