Sign in to follow this  
Followers 0
JohnBailey

GUI Input on focus change invokes action

15 posts in this topic

What is the best way to allow the user to type information in an input guictrl and then when the user clicks off the input, an action is invoked (either updating an edit field or a line in a GUICTRLLISTVIEW) ?


A decision is a powerful thing

Share this post


Link to post
Share on other sites



something that will ControlGetFocus () and wait until focus has changed, then update whatever.

Do you have code to post that I could help you with?

Share this post


Link to post
Share on other sites

Run this :whistle:

#include <GUIConstants.au3>

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("AForm1", 363, 83, 193, 115)
$Input1 = GUICtrlCreateInput("", 40, 16, 273, 21)
$Label1 = GUICtrlCreateLabel("", 40, 48, 275, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        
    Case $Input1
        GUICtrlSetData( $Label1, "You Entered: "&GUICtrlRead($Input1) )
    EndSwitch
WEnd

[font="Verdana"]Keith (Kogmedia)[/font]My ScriptQuick Search - Internet / Hard Drive Search

Share this post


Link to post
Share on other sites

something that will ControlGetFocus () and wait until focus has changed, then update whatever.

good idea I'll try that

Do you have code to post that I could help you with?

yeah, I'll strip it down. there is a lot in it. also, this method would be awesome to know anyway


A decision is a powerful thing

Share this post


Link to post
Share on other sites

Run this :lmao:

#include <GUIConstants.au3>

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("AForm1", 363, 83, 193, 115)
$Input1 = GUICtrlCreateInput("", 40, 16, 273, 21)
$Label1 = GUICtrlCreateLabel("", 40, 48, 275, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        
    Case $Input1
        GUICtrlSetData( $Label1, "You Entered: "&GUICtrlRead($Input1) )
    EndSwitch
WEnd
I'm an idiot! I didn't mention that I'm using Opt ("GUIOnEventMode", 1)

sorry Kogmedia, but that won't work with what I'm using :whistle:


A decision is a powerful thing

Share this post


Link to post
Share on other sites

Opt("TrayIconDebug", 1)
Opt("WinSearchChildren", 1)
HotKeySet("{ESC}", "Terminate")
Func Terminate()
    WinMinimizeAllUndo()
    Exit
EndFunc

#include <GUIConstants.au3>
#include <GuiListView.au3>
#include <File.au3>
#include <Array.au3>

Opt ("GUIOnEventMode", 1)

Global Const $WM_NOTIFY = 0x004E
Global Const $NM_FIRST = 0
Global Const $NM_CLICK = ($NM_FIRST - 2)

Global $n = 0
Global $newFileArray



$fileName = @ScriptDir&"\FullList.txt"

#Region ### START Koda GUI section ### Form=
$Parent = GUICreate("Testing", 503, 447, 193, 115)
$ListView1 = GUICtrlCreateListView("Entry|Activity", 48, 24, 297, 369)
$Add = GUICtrlCreateButton("Add", 376, 24, 89, 25, 0)
$Save = GUICtrlCreateButton("Save", 379, 62, 89, 25, 0)
$Remove = GUICtrlCreateButton("Remove", 379, 92, 89, 25, 0)
$EditName = GUICtrlCreateInput("", 360, 192, 120, 25, 0)
$ActivityCH = GUICtrlCreateCheckbox("Activity", 379, 220, 97, 17)
$Edit = GUICtrlCreateButton("Edit", 379, 282, 89, 25, 0)
$NoticeLabel = GUICtrlCreateLabel("", 116, 400, 185, 17, $SS_CENTER)

GUIRegisterMsg($WM_NOTIFY, "WM_Notify_Events")

GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")
GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents")
GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents")

GUICtrlSetOnEvent($Add, "AddPressed")
GUICtrlSetOnEvent($Save, "SavePressed")
GUICtrlSetOnEvent($Remove, "RemovePressed")
GUICtrlSetOnEvent($Edit, "EditPressed")

GUICtrlSetOnEvent($ActivityCH,"ButtonPress")

GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
    Sleep(10)
WEnd

Func AddPressed()
    $n = $n +1
    GUICtrlCreateListViewItem("Entry"&$n&"|", $ListView1)
EndFunc
    
Func SavePressed()
    ;not present for simplicity's sake
EndFunc

Func RemovePressed()
    _GUICtrlListViewDeleteItem ($ListView1, Int(_GUICtrlListViewGetCurSel ($ListView1)))
EndFunc
    
Func EditPressed()
    $selected = _GUICtrlListViewGetCurSel($ListView1)
    _GUICtrlListViewSetItemText($ListView1, $selected, 0, GUICtrlRead($EditName))
EndFunc

Func ButtonPress()
    Switch @GUI_CTRLID
        Case $ActivityCH
            $selected = _GUICtrlListViewGetCurSel($ListView1)
            If BitAND(GUICtrlRead($ActivityCH), $GUI_CHECKED) = $GUI_CHECKED Then
                _GUICtrlListViewSetItemText($ListView1, $selected, 1, "")
            Else
                _GUICtrlListViewSetItemText($ListView1, $selected, 1, " ")
            EndIf
            ConsoleWrite("Read: "&GUICtrlRead($ActivityCH, $GUI_CHECKED)&@CRLF) 
    EndSwitch
EndFunc




Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
    Local $tagNMHDR, $event
    $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code)
    If @error Then Return
    $event = DllStructGetData($tagNMHDR, 3)
    Select
        Case $wParam = $ListView1
            Select
                Case $event = $NM_CLICK
                    ConsoleWrite(_GUICtrlListViewGetItemText($ListView1)&@CRLF)
                    $seltxt = StringSplit(_GUICtrlListViewGetItemText($ListView1), '|')
                    If UBound($seltxt) - 1 = 2 Then
                        GUICtrlSetData($EditName, $seltxt[1])
                        If NOT ($seltxt[2] = " ") Then 
                            GUICtrlSetState($ActivityCH,$GUI_Checked)
                        Else
                            GUICtrlSetState($ActivityCH,$GUI_Unchecked)
                        EndIf
                    EndIf
            EndSelect
    EndSelect
    $tagNMHDR = 0
    $event = 0
    $lParam = 0
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_Notify_Events

Func SpecialEvents()
    Select
        Case @GUI_CTRLID = $GUI_EVENT_CLOSE
            Terminate()        
            
        Case @GUI_CTRLID = $GUI_EVENT_MINIMIZE
            MsgBox(0, "Window Minimized", "ID=" & @GUI_CTRLID & " WinHandle=" & @GUI_WINHANDLE)
            
        Case @GUI_CTRLID = $GUI_EVENT_RESTORE
            MsgBox(0, "Window Restored", "ID=" & @GUI_CTRLID & " WinHandle=" & @GUI_WINHANDLE)
            
    EndSelect
    
EndFunc

As you can see right now I have to click "edit" to change the "Entry" column for each item. It would be better to skip this step and just after the user clicks in the input area, types something, and then clicks anywhere else (or at least another entry) the Entry column updates with the stuff in input.


A decision is a powerful thing

Share this post


Link to post
Share on other sites

sorry it's so messy. it's a strip version, so I had to quickly add simpler things and build a crummy gui appearance.


A decision is a powerful thing

Share this post


Link to post
Share on other sites

The following doesn't work because when an item is selected, the item flashes until the input area is focused. Not to mention while an item is selected other buttons do not work (eg close X).

Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam)
    If ControlGetFocus('Testing') <> 'Edit1' Then
        $selected = _GUICtrlListViewGetCurSel($ListView1)
        If GUICtrlRead($EditName) <> '' THen
            _GUICtrlListViewSetItemText($ListView1, $selected, 0, GUICtrlRead($EditName))
        Else
            GUICtrlSetData($EditName,'')
        EndIf
    #forceref $hWndGUI, $MsgID, $wParam
    Local $tagNMHDR, $event
    $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code)
    If @error Then Return
    $event = DllStructGetData($tagNMHDR, 3)
    Select
        Case $wParam = $ListView1
            Select
                Case $event = $NM_CLICK
                    ConsoleWrite(_GUICtrlListViewGetItemText($ListView1)&@CRLF)
                    $seltxt = StringSplit(_GUICtrlListViewGetItemText($ListView1), '|')
                    If UBound($seltxt) - 1 = 2 Then
                        GUICtrlSetData($EditName, $seltxt[1])
                        If NOT ($seltxt[2] = " ") Then 
                            GUICtrlSetState($ActivityCH,$GUI_Checked)
                        Else
                            GUICtrlSetState($ActivityCH,$GUI_Unchecked)
                        EndIf
                    EndIf
            EndSelect
    EndSelect
    $tagNMHDR = 0
    $event = 0
    $lParam = 0
    Return $GUI_RUNDEFMSG
    EndIF
EndFunc   ;==>WM_Notify_Events

A decision is a powerful thing

Share this post


Link to post
Share on other sites

As you can see right now I have to click "edit" to change the "Entry" column for each item. It would be better to skip this step and just after the user clicks in the input area, types something, and then clicks anywhere else (or at least another entry) the Entry column updates with the stuff in input.

If I was forced to use a GUI like that, I would look for opportunities to meet the programmer and abuse him badly with partially cooked pasta. :whistle:

From years of custom and use, users expect to be able to go do other things (perhaps to get a copy/paste going for the input) and come back to an edit control without the GUI engaging is precipitous self-automation that changes data.

:lmao:


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

If I was forced to use a GUI like that, I would look for opportunities to meet the programmer and abuse him badly with partially cooked pasta. :whistle:

From years of custom and use, users expect to be able to go do other things (perhaps to get a copy/paste going for the input) and come back to an edit control without the GUI engaging is precipitous self-automation that changes data.

;)

PsaltyDS, first of all hi, and haha! :lmao: Secondly, I'm sure what you're saying is SO very wise (in my experience it always is), but I didn't really follow what you said (I read it several times - I could just not be mentally with it today). What are you saying I should/shouldn't do?

Basically I have a little program (made to the requests of a worker here) that allows him to change a whole bunch of data (so it really looks NOTHING like what I posted here). He wanted to be able select an item in the list view. Then it updates the input fields, thus allowing him to change what he needs. Currently, he has to click save which then updates the listview and saves to the file. If he could just click in the input area, change what he wants, then click another item, change what he wants, and then click save whenever he wants, that would be amazing (gee possibly the worst sentence I've ever wrote). there is a fabulous Edit ListView elements inPlace class somehwere on here. However, it's not exactly what he wants and is WAY over my head (john <<--- not really smart).

Hope that helps describe better what I'm doing and why. I'm also wanting to learn this concept in general. Again, PsaltyDS you're probably giving me a WONDERFUL bit of wisdom and telling me to change something / or not and I just don't get it.


A decision is a powerful thing

Share this post


Link to post
Share on other sites

I could have been way off base. I pictured (imagined) something like, say, the new user properties GUI, where as soon as you tabbed to a different field on the dialog, it saved the value without waiting for you to click Apply or OK, leaving no option to hit Cancel and forget the whole thing. That would make me cuss Microsoft in many colorful ways (well, more than I already do).

But you would certainly know better than anyone on this forum, especially me, what your own users would like your script to do.

:whistle:


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

I could have been way off base. I pictured (imagined) something like, say, the new user properties GUI, where as soon as you tabbed to a different field on the dialog, it saved the value without waiting for you to click Apply or OK, leaving no option to hit Cancel and forget the whole thing. That would make me cuss Microsoft in many colorful ways (well, more than I already do).

But you would certainly know better than anyone on this forum, especially me, what your own users would like your script to do.

:whistle:

No you're right that would be WAY annoying! I actually had it setup with a Apply/Save Changes button, but the guy who is primarily using that feature of the app wants to move faster and not have to click any buttons.

Don't give up on giving me great advise and pointing out where I'm probably missing something. Seriously it soooooo helpful! It's part of the reason I come here.


A decision is a powerful thing

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

Is this what you want, or have I misunderstood?

Opt("TrayIconDebug", 1)
Opt("WinSearchChildren", 1)
Opt("MouseCoordMode",0);relative to current window
HotKeySet("{ESC}", "Terminate")
Func Terminate()
    WinMinimizeAllUndo()
    Exit
EndFunc

#include <GUIConstants.au3>
#include <GuiListView.au3>
#include <File.au3>
#include <Array.au3>

Opt ("GUIOnEventMode", 1)

Global Const $WM_NOTIFY = 0x004E
Global Const $NM_FIRST = 0
Global Const $NM_CLICK = ($NM_FIRST - 2)

Global $n = 0
Global $newFileArray



$fileName = @ScriptDir&"\FullList.txt"

#Region ### START Koda GUI section ### Form=
$Parent = GUICreate("Testing", 503, 447, 193, 115)
$ListView1 = GUICtrlCreateListView("Entry|Activity", 48, 24, 297, 369)
$Add = GUICtrlCreateButton("Add", 376, 24, 89, 25, 0)
$Save = GUICtrlCreateButton("Save", 379, 62, 89, 25, 0)
$Remove = GUICtrlCreateButton("Remove", 379, 92, 89, 25, 0)
$EditName = GUICtrlCreateInput("", 360, 192, 120, 25, 0)
$ActivityCH = GUICtrlCreateCheckbox("Activity", 379, 220, 97, 17)
$Edit = GUICtrlCreateButton("Edit", 379, 282, 89, 25, 0)
$NoticeLabel = GUICtrlCreateLabel("", 116, 400, 185, 17, $SS_CENTER)

GUIRegisterMsg($WM_NOTIFY, "WM_Notify_Events")

GUISetOnEvent($GUI_EVENT_CLOSE, "leave");SpecialEvents")
Func Leave()
    Exit
EndFunc

;GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents")
;GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents")
$edding = ''
$editem = -1
$lastselcol = -1
GUICtrlSetOnEvent($Add, "AddPressed")
GUICtrlSetOnEvent($Save, "SavePressed")
GUICtrlSetOnEvent($Remove, "RemovePressed")
GUICtrlSetOnEvent($Edit, "EditPressed")

GUICtrlSetOnEvent($ActivityCH,"ButtonPress")

GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
$colwid = _GUICtrlListViewGetColumnWidth($ListView1,0)
While 1
    Sleep(10)
WEnd

Func AddPressed()
    $n = $n +1
    GUICtrlCreateListViewItem("Entry"&$n&"| extra info", $ListView1)
EndFunc

Func SavePressed()
    ;not present for simplicity's sake
EndFunc

Func RemovePressed()
    _GUICtrlListViewDeleteItem ($ListView1, Int(_GUICtrlListViewGetCurSel ($ListView1)))
EndFunc

Func EditPressed()
    $selected = _GUICtrlListViewGetCurSel($ListView1)
    _GUICtrlListViewSetItemText($ListView1, $selected, 0, GUICtrlRead($EditName))
EndFunc

Func ButtonPress()
    Switch @GUI_CTRLID
        Case $ActivityCH
            $selected = _GUICtrlListViewGetCurSel($ListView1)
            If BitAND(GUICtrlRead($ActivityCH), $GUI_CHECKED) = $GUI_CHECKED Then
                _GUICtrlListViewSetItemText($ListView1, $selected, 1, "")
            Else
                _GUICtrlListViewSetItemText($ListView1, $selected, 1, " ")
            EndIf
            ConsoleWrite("Read: "&GUICtrlRead($ActivityCH, $GUI_CHECKED)&@CRLF)
    EndSwitch
EndFunc


Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam)
    If ControlGetFocus('Testing') <> 'Edit1' Then
        #forceref $hWndGUI, $MsgID, $wParam
        Local $tagNMHDR, $event
        $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code)
        If @error Then Return
        $event = DllStructGetData($tagNMHDR, 3)
        Select
            Case $wParam = $ListView1
                
                Select
                    Case $event = $NM_CLICK
                        $mp = MouseGetPos()
                        $selcol = 0
                        $lvpos = ControlGetPos("Testing","",$ListView1)
                        ConsoleWrite("mouse x = " & $mp[0] & ',  lv pos = ' & $lvpos[0] & 'colwid = ' & $colwid  & @CRLF)
                        If $mp[0] > $lvpos[0] + $colwid + 7 Then $selcol = 1
                        ConsoleWrite("sel col = " & $selcol & @CRLF)
                        $selected = _GUICtrlListViewGetCurSel($ListView1)
                        ConsoleWrite(_GUICtrlListViewGetItemText($ListView1)&@CRLF)
                        $seltxt = _GUICtrlListViewGetItemText($ListView1,$selected,$selcol)
                            If $editem >= 0 Then
                                If GUICtrlRead($EditName) <> '' Then
                                    _GUICtrlListViewSetItemText($ListView1, $editem, $lastselcol, GUICtrlRead($EditName))
                                EndIf
                                
                            EndIf
                            $editem = $selected
                            $lastselcol = $selcol
                            
                            GUICtrlSetData($EditName, $seltxt)
                EndSelect
        EndSelect
        $tagNMHDR = 0
        $event = 0
        $lParam = 0
        Return $GUI_RUNDEFMSG
    EndIF
EndFunc   ;==>WM_Notify_Events
Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Exactly!!!! that's crazy I didn't even think about doing it that way! Thanks martin you ROCK !!!! Cool to know how to do this!! I could actually use this method for different applications. Thanks so much! Great idea


A decision is a powerful thing

Share this post


Link to post
Share on other sites

Exactly!!!! that's crazy I didn't even think about doing it that way! Thanks martin you ROCK !!!! Cool to know how to do this!! I could actually use this method for different applications. Thanks so much! Great idea

Glad I could help. Getting one right makes up for all the rubbish I post!


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

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
Sign in to follow this  
Followers 0