Jump to content

Recommended Posts

Posted

Dear friends of the forum, I've been trying to do an autocompletion filtering the results for days, disabling the characters that are not part of the result, but without success. Some friends could give me a start, the gif image shows what I'm trying to do, any start would help me. thanks.

 

AN0HtPxu_o.gif

  • Developers
Posted

Moved to the appropriate AutoIt General Help and Support forum, as the AutoIt Example Scripts forum very clearly states:

  Quote

Share your cool AutoIt scripts, UDFs and applications with others.


Do not post general support questions here, instead use the AutoIt Help and Support forums.

Expand  

Moderation Team

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Posted

Keyboard layout.

  Reveal hidden contents

 

Posted (edited)

Hi @mutleey,

looks promising, but I guess it's still a long way 😅 . How do you plan to disable each key? One by one like this:

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $BTN[1]
            GUICtrlSetBkColor($BTN[1], 0xD1E0FF)
        Case $BTN[2]
            GUICtrlSetBkColor($BTN[2], 0xD1E0FF)
    EndSwitch
WEnd

Wouldn't be pretty handy I guess. Any specific questions? Out of your first post I can't see a concrete issue or something.

Best regards
Sven

Edited by SOLVE-SMART

==> AutoIt related: 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet

  Reveal hidden contents
Posted

The idea is to do as this script does, but disabling the keys that are not part of the result.

  Reveal hidden contents

 

Posted

I will later have a deeper look into it.

Best regards
Sven

==> AutoIt related: 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet

  Reveal hidden contents
Posted

Ok, I think I now understand what you want.  You have a list of keyword, and you want the user to enter only valid entry by disabling keys that cannot be part of the words left as the user enters characters in an input field.  Is that it ?

Posted (edited)
  On 1/6/2023 at 6:46 PM, Nine said:

Ok, I think I now understand what you want.  You have a list of keyword, and you want the user to enter only valid entry by disabling keys that cannot be part of the words left as the user enters characters in an input field.  Is that it ?

Expand  

Based on the script above, when typing the letter X in the search, all keys with the exception of C, P, W, L (which are the possible options) would be disabled, and so on until one option remains. The gif above shows the example well.

search.jpg

Edited by mutleey
Posted (edited)

This is an example script on how to filter from an array:

#include <Array.au3>
Dim $tt[0]

$words="test|teaser|teatime|tension|Best|beaser|beatime|bension"
_ArrayAdd($tt,$words,0,"|")

$words=StringReplace(StringReplace($words,"|B",@CRLF & "b",0,1),"|"," ")
While 1
$in=InputBox ("Enter a text to show the available next chars","From these words:" & @CRLF &@CRLF & $words &  @CRLF & @CRLF & "Enter end to stop","","",320)
If $in="end" then Exit

CW(@crlf & "******************" & @crlf & "Input string = " & $in & @CRLF)

for $x=0 to UBound($tt)-1
    if StringMid($tt[$x],1,StringLen($in))=$in Then
        $nl=StringMid($tt[$x],StringLen($in)+1,1)
    CW("Available next letter= '" & $nl & "' from " & $tt[$x],1)
    EndIf
Next

Wend

Func CW($txt,$crlf=1)
    Local $nl=""
    if $crlf=1 then $nl=@CRLF
    ConsoleWrite ($txt & $nl)
EndFunc

it should give you an idea on how to proceed. 
p.s. the last 4 test words are the same as the 1st just with the t swapped with a b, for testing purpose.

Edited by Dan_555

Some of my script sourcecode

Posted

Here my take on your request.  Instead of using your keyboard, I have use a hook that disables unauthorized keys.

#include <Constants.au3>
#include <GUIConstants.au3>
#include <WinAPISys.au3>
#include <WinAPIConstants.au3>
#include <WinAPIProc.au3>
#include <Array.au3>

Opt("MustDeclareVars", True)

Global $aKeyWords[] = ["fight", "first", "fly", "third", "fire", "wall", "hi", "high", "hello", "world", "window", _
          "window 1", "window 2", "window 3", "window 4", "window 5", "window 6", "window 7", "window 8", "window 9", "window 10"]
Global $aAllowedChar = EnumerateChar(1, $aKeyWords)
Global $hHook, $idList, $idDummy, $bAllowed

Local $sSelected = SelectWord()
MsgBox($MB_SYSTEMMODAL, "You have selected", $sSelected)

Func SelectWord()
  Local $hGui = GUICreate("Select Word")
  $idList = GUICtrlCreateInput("", 10, 10, 100, 20)
  $idDummy = GUICtrlCreateDummy()
  Local $idKey = GUICtrlCreateDummy()
  Local $hStub = DllCallbackRegister(WH_KEYBOARD, "LRESULT", "int;wparam;lparam")
  $hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD, DllCallbackGetPtr($hStub), 0, _WinAPI_GetCurrentThreadId())
  Local $aAccelKeys[1][2] = [["{ENTER}", $idKey]]
  GUISetAccelerators($aAccelKeys)

  GUIRegisterMsg($WM_COMMAND, WM_COMMAND)
  GUISetState()

  Local $aWordsLeft = $aKeyWords, $sWordSelected
  While True
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        $sWordSelected = ""
        ExitLoop
      Case $idDummy
        $aWordsLeft = WordsLeft(GUICtrlRead($idList), $aKeyWords)
        _ArrayDisplay($aWordsLeft)
        If UBound($aWordsLeft) = 1 Then
          $sWordSelected = $aWordsLeft[0]
          ExitLoop
        EndIf
        $aAllowedChar = EnumerateChar(StringLen(GUICtrlRead($idList)) + 1, $aWordsLeft)
        ;_ArrayDisplay($aAllowedChar)
      Case $idKey
        $sWordSelected = GUICtrlRead($idList)
        ExitLoop
    EndSwitch
  WEnd
  GUIDelete($hGui)
  _WinAPI_UnhookWindowsHookEx($hHook)
  DllCallbackFree($hStub)
  Return $sWordSelected
EndFunc

Func WH_KEYBOARD($iMsg, $wParam, $lParam)
  ;ConsoleWrite("wm_keyb " & Chr($wParam) & "/" & Hex($wParam, 2) & "/" & $wParam & @CRLF)
  If $iMsg = 0 And $wParam <> 27 And $wParam <> 8 And $wParam <> 13 Then
    $bAllowed = _ArraySearch($aAllowedChar, Chr($wParam)) >= 0
    If Not $bAllowed Then Return 1
  EndIf
  Return _WinAPI_CallNextHookEx($hHook, $iMsg, $wParam, $lParam)
EndFunc   ;==>MyProc

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    Local $iIDFrom = _WinAPI_LoWord($wParam)
    Local $iCode = _WinAPI_HiWord($wParam)
  If $iIDFrom = $idList And $iCode = $EN_CHANGE And $bAllowed Then GUICtrlSendToDummy($idDummy)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_COMMAND

Func EnumerateChar($iLen, ByRef $aList)
  Local $aChar[UBound($aList)]
  For $i = 0 To UBound($aList) - 1
    $aChar[$i] = StringMid($aList[$i], $iLen, 1)
  Next
  Return $aChar
EndFunc

Func WordsLeft($sInclude, ByRef $aList)
  Local $aLeft = _ArrayFindAll($aList, "^" & $sInclude, Default, Default, Default, 3)
  For $i = 0 To UBound($aLeft) - 1
    $aLeft[$i] = $aList[$aLeft[$i]]
  Next
  Return $aLeft
EndFunc

 

Posted (edited)

basic structure (msgbox list not coded.... )

#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <Array.au3>

MsgBox(0, '', '1) Create your virtual keyboard' & @Crlf & _
              '2) disable all key' & @Crlf & _
              '3) loop [Enable Key List....] to enable/disable required key'  & @Crlf & _
              '4) press enter to display desired item' )

Global $aKeyWords = __Get_Words()
Global $input1, $input2

__ExampleA()
Func __ExampleA()
    Local $hGUI = GUICreate("Filter key", 300, 150)
    GUICtrlCreateLabel("> Input....", 10, 10)
    GUICtrlCreateLabel("> Enable Key List....", 10, 75)
    $input1 = GUICtrlCreateInput("", 10, 35, 280, 25)
    $input2 = GUICtrlCreateInput('', 10, 100, 280, 30)
    GUICtrlSetFont($input2, 11)
    GUICtrlSetState($input2, $GUI_DISABLE)
    GUICtrlSetData($input2, StringUpper(_ArrayToString(__Get_Char($aKeyWords), ' |  ') & @Tab & '(' & __News(GUICtrlRead($input1)) & ')'))
    GUISetState(@SW_SHOW, $hGUI)
    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd
    GUIDelete($hGUI)
EndFunc

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    If _WinAPI_LoWord($wParam) = $input1 And _WinAPI_HiWord($wParam) = $EN_CHANGE Then
        Local $k_newList = ''
        $k_newList = _ArrayToString(__Get_Char($aKeyWords, GUICtrlRead($input1)), ' |  ') & @Tab & '(' & __News(GUICtrlRead($input1)) & ')'
        GUICtrlSetData($input2, StringUpper($k_newList))
    EndIf
EndFunc

Func __Get_Words()
    Local $aKeyWords[] = ["fight", "first", "fly", "third", "fire", "wall", "hi", "high", "hello", "world", "win", "winwait", "winclose"]
    Return _ArrayToString($aKeyWords, '|')
EndFunc

Func __News($oWord)
    Local $aItems[] = ["fly high", "Butterfly", "is linux better than window", "win xp", "win 7", "win 10", _
                          "world cup football 2022", "World Peace Day September 21, 2023", "Autoit winwait", "Autoit winclose"]
    If $oWord = '' Then Return UBound($aItems)

    Local $aCount = 0
    For $i = 0 To UBound($aItems) - 1
        If StringInStr($aItems[$i], $oWord) Then $aCount += 1
    Next
    Return $aCount
EndFunc

Func __Get_Char($oString, $oLetter = '')
    If IsArray($oString) Then Return SetError(1)

    Local $iAlphabet = (($oLetter = '') ? _
                    StringRegExpReplace($oString, '^(\S)|(\|\S)|(\s|\w+)', '$1$2') : _
                    StringRegExpReplace($oString, '\b' & $oLetter & '(.)|(\s|\w+)', '$1'))

    $iAlphabet = StringRegExpReplace($iAlphabet, '[\|]+', '|')

    Local $i_Alphabet = StringRegExp($iAlphabet, '([^|\s])(?!.*\1)', 3)
    If StringRegExp($iAlphabet, '\s', 0) Then
        ReDim $i_Alphabet[UBound($i_Alphabet) + 1]
        $i_Alphabet[UBound($i_Alphabet) - 1] = '{SPACE}'
    EndIf

    If ($oLetter <> '') And StringRegExp($oString, '\b' & $oLetter & '\b', 0) Then
        IF IsArray($i_Alphabet) Then
            ReDim $i_Alphabet[UBound($i_Alphabet) + 1]
            $i_Alphabet[UBound($i_Alphabet) - 1] = '{ENTER}'
        Else
            Local $i_Alphabet[1] = ['{ENTER}']
        EndIf
    EndIf

    Return $i_Alphabet
EndFunc

 

Edited by jugador
Posted

Hi folks,

@jugador:
Your example is pretty nice, thank you 👍 . I don't have the same use case as @mutleey has, but I can definitely use this.

@Nine:
Thank you too for your example 😀 .

@mutleey:
I am looking forward how your result will look like, best of luck for it.

Best regards
Sven

==> AutoIt related: 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet

  Reveal hidden contents
Posted (edited)

funny question @mutleey
Here's my 2 cents
the keys on the first row of the virtual keyboard are spare,
as you click on the keys, the list of elements is reduced and the disallowed keys are inhibited
The key to the right of the M key, ( ◄ ) deletes the last character in the input field
the key ( ¶ ) confirms the text present in the input field
p.s.
my "graphics keyboard" is a bit spartan, but take this script as one more possible way to achieve your goal

#include <GUIConstants.au3>

Global $aList = _GetCities() ; create the 1D array
MsgBox(0, 'Result', 'You chose ' & _Example($aList, 'choose a city'))


; Pass a 1D array with a list of entries to choose from
Func _Example(ByRef $asKeyWords, $sTitle = '')
    ;                                  00000000001111111111222222222233333333334444444444
    ;                                  01234567890123456789012345678901234567890123456789
    Local Static $aKeys = StringSplit('☺☻♥♦♣♠•◘♪♫1234567890QWERTYUIOPASDFGHJKL ZXCVBNM◄ ¶', '', 2)
    Local Static $aToggleableKey = StringSplit('00000000001111111111111111111111111111111111111000', '', 2)
    Local $aMyMatrix[UBound($aKeys)]
    Local $sString, $hInput, $hList, $bFlag
    Local $sPartialInp, $iPartialLen, $sAllowed, $iNumRows, $sReturn

    $hGUI = GUICreate($sTitle, 401, 600)

    $hInput = GUICtrlCreateInput("", 5, 5, 392, 20, $ES_READONLY) ;  0x0800 )
    GUICtrlSetBkColor(-1, 0XFFFFFF)

    ; Virtual Custom Keyboard
    Local $xPanelPos = 0, $yPanelPos = 30, $nrPerLine = 10, $nrOfLines = 5, $ctrlWidth = 39, $ctrlHeight = 39, $xSpace = 1, $ySpace = 1, $xBorder = 1, $yBorder = 1, $style = -1, $exStyle = -1
    For $i = 0 To $nrPerLine * $nrOfLines - 1
        ; coordinates 1 based
        $col = Mod($i, $nrPerLine) + 1 ; Horizontal position within the grid (column)
        $row = Int($i / $nrPerLine) + 1 ;  Vertical position within the grid (row)
        $left = $xPanelPos + ((($ctrlWidth + $xSpace) * $col) - $xSpace) - $ctrlWidth + $xBorder
        $top = $yPanelPos + ((($ctrlHeight + $ySpace) * $row) - $ySpace) - $ctrlHeight + $yBorder
        $text = $aKeys[$i] ;  + 1 ; "*" ; "." ; "(*)"
        ; create the control(s)
        $aMyMatrix[$i] = GUICtrlCreateButton($text, $left, $top, $ctrlWidth, $ctrlHeight, $style, $exStyle)
    Next

    $hList = GUICtrlCreateList('', 1, 233, 400, 370, BitOR($WS_BORDER, $WS_VSCROLL, $LBS_NOSEL))
    GUICtrlSetFont(-1, 12, 0, 0, 'Courier New')
    For $i = 0 To UBound($asKeyWords) - 1
        GUICtrlSetData($hList, $asKeyWords[$i])
    Next

    GUISetState()

    While 1
        $Msg = GUIGetMsg()
        Switch $Msg
            Case $GUI_EVENT_CLOSE
                $sReturn = GUICtrlRead($hInput)
                GUIDelete($hGUI)
                Return $sReturn
            Case $hList
                GUICtrlSetData($hInput, GUICtrlRead($hList))
        EndSwitch

        If $bFlag Then
            $bFlag = False
            $sPartialInp = GUICtrlRead($hInput)
            $iPartialLen = StringLen($sPartialInp)

            ; empty the list
            GUICtrlSetData($hList, "")
            $iNumRows = 0

            ; refill the list
            $sAllowed = ""
            For $i = 0 To UBound($asKeyWords) - 1
                If StringLeft($asKeyWords[$i], $iPartialLen) = $sPartialInp Then
                    GUICtrlSetData($hList, $asKeyWords[$i])
                    $iNumRows += 1
                    $sAllowed &= StringMid($asKeyWords[$i], $iPartialLen + 1, 1)
                EndIf
            Next

            ; enable or disable keys
            For $i = 0 To UBound($aKeys) - 1
                If $aToggleableKey[$i] = "1" Then
                    If StringInStr($sAllowed, $aKeys[$i]) Then
                        GUICtrlSetState($aMyMatrix[$i], 64) ; $GUI_ENABLE (64) Control will be enabled.
                    Else
                        GUICtrlSetState($aMyMatrix[$i], 128) ; $GUI_DISABLE (128) Control will be greyed out.
                    EndIf
                EndIf
            Next
        EndIf

        ; 00000000001111111111222222222233333333334444444444
        ; 01234567890123456789012345678901234567890123456789
        ; ☺☻♥♦♣♠•◘♪♫1234567890QWERTYUIOPASDFGHJKL ZXCVBNM◄ ¶
        ;
        ; check if and which key was pressed
        ; and manage actions to be taken accordingly
        For $iKey = 0 To UBound($aMyMatrix) - 1
            If $Msg = $aMyMatrix[$iKey] Then
                Switch $iKey
                    Case 0 To 7
                        ConsoleWrite("Debug: Spare key" & @CRLF)
                    Case 8
                        Beep(500, 70)
                    Case 9
                        Beep(750, 70)
                        Beep(500, 70)
                    Case 47 ; delete rightmost char
                        GUICtrlSetData($hInput, StringTrimRight(GUICtrlRead($hInput), 1))
                    Case 48
                        ConsoleWrite("Debug: Spare key" & @CRLF)
                    Case 49 ; return virtual key ¶
                        ; If $iNumRows = 1 Then
                            $sReturn = GUICtrlRead($hInput)
                            GUIDelete($hGUI)
                            Return $sReturn
                        ; EndIf
                    Case 10 To 46 ; numbers, letters, space
                        GUICtrlSetData($hInput, GUICtrlRead($hInput) & $aKeys[$iKey])
                EndSwitch
            EndIf
        Next

        If $sString <> GUICtrlRead($hInput) Then
            $sString = GUICtrlRead($hInput)
            $bFlag = True
        EndIf
    WEnd
EndFunc   ;==>_Example

Func _GetCities()
    ; source: https://simplemaps.com/data/world-cities
    ;         ----------------------------------------
    ; here a reduced list of the top 159 most populous cities
    ; (for fun I also added my little town (Imperia) just to have a total of 160 cities)
    Local $sCities = ''
    $sCities &= "Tokyo,New York,Mexico City,Mumbai,Sao Paulo,Delhi,Shanghai,Kolkata,Los Angeles,Dhaka,Buenos Aires,Karachi,Cairo,Rio de Janeiro,Osaka,Beijing,"
    $sCities &= "Manila,Moscow,Istanbul,Paris,Seoul,Lagos,Jakarta,Guangzhou,Chicago,London,Lima,Tehran,Kinshasa,Bogota,Shenzhen,Wuhan,"
    $sCities &= "Hong Kong,Tianjin,Chennai,Taipei,Bangalore,Bangkok,Lahore,Chongqing,Miami,Hyderabad,Dallas,Santiago,Philadelphia,Belo Horizonte,Madrid,Houston,"
    $sCities &= "Ahmedabad,Ho Chi Minh City,Washington,Atlanta,Toronto,Singapore,Luanda,Baghdad,Barcelona,Haora,Shenyeng,Khartoum,Pune,Boston,Sydney,St. Petersburg,"
    $sCities &= "Chittagong,Dongguan,Riyadh,Hanoi,Guadalajara,Melbourne,Alexandria,Chengdu,Rangoon,Phoenix,Xian,Porto Alegre,Surat,Hechi,Abidjan,Brasilia,"
    $sCities &= "Ankara,Monterrey,Yokohama,Nanjing,Montreal,Guiyang,Recife,Seattle,Harbin,San Francisco,Fortaleza,Zhangzhou,Detroit,Salvador,Busan,Johannesburg,"
    $sCities &= "Berlin,Algiers,Rome,Pyongyang,Medellin,Kabul,Athens,Nagoya,Cape Town,San Diego,Changchun,Casablanca,Dalian,Kanpur,Kano,Tel Aviv-Yafo,"
    $sCities &= "Addis Ababa,Curitiba,Zibo,Jeddah,Nairobi,Hangzhou,Benoni,Caracas,Milan,Stuttgart,Kunming,Dar es Salaam,Minneapolis,Jaipur,Taiyuan,Frankfurt,"
    $sCities &= "Qingdao,Surabaya,Lisbon,Tampa,Jinan,Fukuoka,Campinas,Denver,Kaohsiung,Quezon City,Katowice,Aleppo,Durban,Kiev,Lucknow,El Giza,"
    $sCities &= "Zhengzhou,Taichung,Brooklyn,Ibadan,Faisalabad,Fuzhou,Dakar,Changsha,Izmir,Xiangtan,Lanzhou,Incheon,Sapporo,Xiamen,Guayaquil,Imperia"
    Return StringSplit($sCities, ',', 2) ; $STR_NOCOUNT (2) = disable the return count in the first element
EndFunc   ;==>_GetCities

 

Edited by Gianni

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Posted

This is what I was trying to do, thanks to all the friends who helped, with the help of the dear friends I can now adjust the script for my project.

But once thanks @SOLVE-SMART, @Nine, @Dan_555, @jugador, @Gianni.

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...