Lupo73 11 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. mikell, yutijang, 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 post Share on other sites
mikell 1,117 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 post Share on other sites
PhoenixXL 169 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 post Share on other sites
mikell 1,117 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 post Share on other sites
hyperjase 0 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 post Share on other sites
z0iid 0 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 post Share on other sites
satanico64 2 Posted November 27, 2015 Share Posted November 27, 2015 Very nice. You save me a lot of time.Thank you. Link to post Share on other sites
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