Could someone explain why this works?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
cam
Posts: 4
Joined: 08 Dec 2022, 12:47

Could someone explain why this works?

Post by cam » 08 Dec 2022, 13:30

I'm writing a database searcher and wanted it to search-as-you-type for the coolness factor. I had to put a check inside the file reading loop to break and restart the loop if the user typed in something different, and went through a few options, but I landed on the best option (so far; advice is welcomed!) accidentally:

Code: Select all

        GuiControlGet, search, , guisearch
        if (search != guisearch)
           Goto Searcher
My understanding of GuiControlGet is it'll set the output variable to match whatever it finds in the user edit (search) box. So shouldn't 'search' always equal 'guisearch'? Yet if I take away the conditional, suddenly the search function is slow and doesn't respond well to user input. I'm happy but scratching my head a little!

Code: Select all

Searcher:
Gui, Submit, NoHide
LV_Delete()
if not (guisearch = "")
{
    Loop, Read, % RadioCMYK ? CMYK : LabCh             ; checks which radio button is selected to determine which database to load. Defaults to CMYK
    {
        GuiControlGet, search, , guisearch                   ; every iteration of the loop checks the user input to see if it has changed
        if (search != guisearch)                                    ; I don't know why this doesn't always pass, but it works wicked great
           Goto Searcher
        search := Format("{:T}", search)                              ; capitalize first letter of the user input to match the database. Every first letter in the database is capitalized without exception.
        Loop, Parse, A_LoopReadLine, "`t"
        {
            if (A_Index == 2) AND (SubStr(A_LoopField, 1, StrLen(search)) == Format("{:T}", search))          ; looks into the second field (the name), capitalizes the first letter of user input, and checks for match
            {
                c := StrSplit(A_LoopReadLine, "`t")
                LV_Add("",c[1],c[2],c[3],c[4],c[5],c[6],c[7],c[8],c[9],c[10])                   ; the database is formatted to lay out perfectly into the listview columns
                c :=
                break
            }
        }
    }   
}

User avatar
mikeyww
Posts: 26945
Joined: 09 Sep 2014, 18:38

Re: Could someone explain why this works?

Post by mikeyww » 08 Dec 2022, 13:44

Welcome to this AutoHotkey forum!

Search is the output variable, but guisearch is not an input variable. It is the identifying name of the control that "contains" the contents that you seek. This is why the command is needed, instead of a := b. You are saying, "Fetch the contents of this control, and store them in this variable". The way to access the control's contents would be:
1. GuiControlGet as you are doing,
or
2. Submit the GUI.

Using Goto to jump out of a Loop is not a great practice and can even lead to problems in a script's execution. One would typically use other approaches here (e.g., Loop, While, Until, Gosub, Break).

One way to execute a "type-ahead" filter is to call a separate function or subroutine whenever the edit control is changed. That subroutine then filters a list, updates a view, searches a database, etc.
Last edited by mikeyww on 08 Dec 2022, 13:53, edited 1 time in total.

cam
Posts: 4
Joined: 08 Dec 2022, 12:47

Re: Could someone explain why this works?

Post by cam » 08 Dec 2022, 13:52

Aha! I would need a guisubmit to update the variable "guisearch", which restarting the section does.

Thank you for the knowledge and the welcome!

User avatar
mikeyww
Posts: 26945
Joined: 09 Sep 2014, 18:38

Re: Could someone explain why this works?

Post by mikeyww » 08 Dec 2022, 13:57

Another option is a radio group where only one button in the group has a variable, as explained in the documentation. You then don't have to loop through all of the radio options to find the selected one.

cam
Posts: 4
Joined: 08 Dec 2022, 12:47

Re: Could someone explain why this works?

Post by cam » 08 Dec 2022, 14:13

mikeyww wrote:
08 Dec 2022, 13:44
Using Goto to jump out of a Loop is not a great practice and can even lead to problems in a script's execution. One would typically use other approaches here (e.g., Loop, While, Until, Gosub, Break).

One way to execute a "type-ahead" filter is to call a separate function or subroutine whenever the edit control is changed. That subroutine then filters a list, updates a view, searches a database, etc.
I'll work on taking the goto out. I had no idea, but looking at the documentation, it looks like separating the filters into a function would be the best bet. Thank you.

Isn't "searcher" a subroutine? Whenever the user types into the edit box, I run "gSearcher", which gathers the variables via Gui,Submit, updates the view, and searches the database via a filter. In another post you said I'm looping through my radio buttons too, but as far as I understand it I'm using a ternary to determine which of the two radio buttons are selected. I'd like my little program to be as fast as possible, so if there's extra looping or other inefficient things I'm doing, I truly appreciate the corrections.

User avatar
mikeyww
Posts: 26945
Joined: 09 Sep 2014, 18:38

Re: Could someone explain why this works?

Post by mikeyww » 08 Dec 2022, 14:29

"Searcher" is a subroutine, but of course, the reader has no idea what calls it other than what is shown. We do see that you potentially jump out of the loop at an early stage.

Code: Select all

database := ["CMYK", "RGB"]
Gui, Font, s10
Gui, Add, Edit , w230 gSearch vterm
Gui, Add, Radio, wp   gSearch voption, % database.1
Gui, Add, Radio, wp   gSearch        , % database.2
Gui, Show,, Options
Return

Search:
Gui, Submit, NoHide
db := database[option]
ToolTip, Database: %db%`nSearching for: %term%, 0, -60
Return

cam
Posts: 4
Joined: 08 Dec 2022, 12:47

Re: Could someone explain why this works?

Post by cam » 08 Dec 2022, 15:35

Replacing "goto" with "gosub" broke the search functionality. I'm in over my head on the differences between those two so I'm going to make a function instead.

I've attached the program for the reader's perusal. The "guibuilder" subroutine is overcomplicated. I rebuild the entire UI with every action since I'll need that sort of thing for future projects I'm working on. Your latest post helps me a lot with that.

User avatar
mikeyww
Posts: 26945
Joined: 09 Sep 2014, 18:38

Re: Could someone explain why this works?

Post by mikeyww » 08 Dec 2022, 17:11

One idea of my last post is that the search routine would be inserted after the ToolTip command. In any case, there are many ways to slice and dice this.

Post Reply

Return to “Ask for Help (v1)”