Jump to content

Identify Control that contains cursor BEFORE button is pressed


JasonDW
 Share

Recommended Posts

HI,

I am a newbie to AutoIT but am finding it very easy to use.

I have created a GUI that has multiple input boxes where users can input directories. I would like to have a browse button that allows the user to browse and select the directory for each box.

The problem comes because I would like to have only 1 browse button for all input boxes. The user puts the cursor in the input box they want to change and then clicks browse and the resulting directory selected replaces the data in the input box.

The problem I have is finding out which input box the user had the cursor in BEFORE the button was clicked (since the button steals the focus).

I had hoped that everytime the user clicked in a different input box the GUIGetMsg() would catch that and I could simply record the last clicked input box....unfortunately GUIGetMsg() doesn't register unless the user makes a change in the inputbox.

The code is below...any thoughts??

The obvious work around is to have multiple browse buttons...or when $GUI_EVENT_PRIMARYDOWN happens, find which inputbox was clicked in and save that!! A bit long winded.....is there a better way???

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

_gui_global_defaults()

Func _GUI_Global_Defaults()
    #Region ### START Koda GUI section ### Form=F:\Documents\AutoIT\frmGlobalDefaults.kxf
    $frmGlobalDefaults = GUICreate("Global Defaults", 620, 558, 371, 125)
    $inptbxRegFileName = GUICtrlCreateInput("inptbxRegFileName", 160, 24, 300, 21)
    GUICtrlSetTip(-1, "Enter the filename for the registry entries to be saved to")
    $Label1 = GUICtrlCreateLabel("Registry File Name", 24, 24, 130, 17, $SS_RIGHT)
    GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
    $Label2 = GUICtrlCreateLabel("Base Directory", 24, 72, 130, 17, $SS_RIGHT)
    GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
    $inptbxDirBase = GUICtrlCreateInput("inptbxDirBase", 160, 80, 300, 21)
    GUICtrlSetTip(-1, "Enter the base directory for local storage of frame pics / settings etc")
    $Label3 = GUICtrlCreateLabel("Album Directory", 24, 136, 130, 17, $SS_RIGHT)
    GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
    $inptbxDirAlbum = GUICtrlCreateInput("inptbxDirAlbum", 160, 136, 300, 21)
    GUICtrlSetTip(-1, "Enter the Album directory (offset from Base Directory)")
    $Label4 = GUICtrlCreateLabel("Settings Directory", 24, 192, 130, 17, $SS_RIGHT)
    GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
    $inptbxDirSettings = GUICtrlCreateInput("inptbxDirSettings", 160, 192, 300, 21)
    GUICtrlSetTip(-1, "Enter the Settings directory (offset from Base Directory)")
    $Label5 = GUICtrlCreateLabel("High Priority Directory", 24, 248, 130, 17, $SS_RIGHT)
    GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
    $inptbxDirHP = GUICtrlCreateInput("inptbxDirHP", 160, 248, 300, 21)
    GUICtrlSetTip(-1, "Enter the directory to be used for High Priority pictures. (offset from Base Directory)")
    $Label6 = GUICtrlCreateLabel("Random File Directory", 24, 304, 130, 17, $SS_RIGHT)
    GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
    $inptbxDirRandoms = GUICtrlCreateInput("inptbxDirRandoms", 160, 304, 300, 21)
    GUICtrlSetTip(-1, "Enter the directory for Random Files (ie not in albums). (offset from Base Directory)")
    $Label7 = GUICtrlCreateLabel("Frame Network Path", 24, 360, 130, 17, $SS_RIGHT)
    GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
    $inptbxDirFrame = GUICtrlCreateInput("inptbxDirFrame", 160, 360, 300, 21)
    GUICtrlSetTip(-1, "Enter the network path for the frame directory. (Full path required to frame Base Directory)")
    $Label8 = GUICtrlCreateLabel("Picasa Settings Path", 24, 416, 130, 17, $SS_RIGHT)
    GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
    $inptbxPicasaSettings = GUICtrlCreateInput("inptbxPicasaSettings", 160, 416, 300, 21)
    GUICtrlSetTip(-1, "Picassa settings path. After UserProfile directory.")
    $btnApply = GUICtrlCreateButton("&Apply", 8, 520, 75, 25, 0)
    GUICtrlSetTip(-1, "Appl;y settings above.")
    $btnReset = GUICtrlCreateButton("&Reset", 88, 520, 75, 25, 0)
    GUICtrlSetTip(-1, "Resets form back to start of session")
    $btnLoadDefault = GUICtrlCreateButton("Load &Defaults", 168, 520, 90, 25, 0)
    GUICtrlSetTip(-1, "Loads Program Defaults")
    $btnSetAsDefault = GUICtrlCreateButton("&Set as Default", 264, 520, 90, 25, 0)
    GUICtrlSetTip(-1, "Sets above information as Program Default")
    $btnSaveAsIni = GUICtrlCreateButton("Save as &INI", 360, 520, 90, 25, 0)
    GUICtrlSetTip(-1, "Sets above information as Program Default")
    $btnLoadIni = GUICtrlCreateButton("&Load INI", 456, 520, 75, 25, 0)
    $btnCancel = GUICtrlCreateButton("&Cancel", 536, 520, 75, 25, 0)
    $Label9 = GUICtrlCreateLabel("eg. gphotoshow.reg", 160, 56, 98, 17)
    $Label10 = GUICtrlCreateLabel("eg. D:\Digital Frame", 160, 112, 99, 17)
    $Label11 = GUICtrlCreateLabel("eg. \Album Directory", 160, 168, 101, 17)
    $Label12 = GUICtrlCreateLabel("eg. \Settings", 160, 224, 65, 17)
    $Label13 = GUICtrlCreateLabel("eg. \HP", 160, 280, 42, 17)
    $Label14 = GUICtrlCreateLabel("eg. \", 160, 336, 27, 17)
    $Label15 = GUICtrlCreateLabel("eg. ", 160, 392, 22, 17)
    $Label16 = GUICtrlCreateLabel("eg. \Local Settings\Application Data\Google\Picasa2Albums", 160, 448, 293, 17)
    $btnBrowse = GUICtrlCreateButton("&Browse", 480, 24, 107, 425, 0)
    GUICtrlSetFont(-1, 16, 400, 0, "MS Sans Serif")
    GUICtrlSetTip(-1, "Click to browse for folder. Will use previously selected inputbox.")
    $Label17 = GUICtrlCreateLabel("Loaded INI File", 24, 472, 130, 17, $SS_RIGHT)
    GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
    $inptbxLoadedINI = GUICtrlCreateInput("nil", 160, 472, 300, 21)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUICtrlSetTip(-1, "Picassa settings path. After UserProfile directory.")
    $btnCheckPaths = GUICtrlCreateButton("Check Paths", 480, 464, 75, 25, 0)
    GUICtrlSetTip(-1, "Will check all paths as specified.")
    $chkbxCheck = GUICtrlCreateCheckbox("Check on Apply", 480, 496, 97, 17)
    GUICtrlSetState(-1, $GUI_CHECKED)
    GUICtrlSetTip(-1, "Run path check on Apply.")
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

    Local $iLastInptBox
    Local $sDirTemp
    Local $sInitialDir

    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE, $btnCancel
                MsgBox(0, "Exiting...", "Changes will not be applied. Exiting....")
                Exit
            Case $inptbxDirAlbum, $inptbxDirBase, $inptbxDirFrame, $inptbxDirHP, $inptbxDirRandoms, $inptbxDirSettings, $inptbxRegFileName, $inptbxPicasaSettings
                $iLastInptBox = $nMsg
                ConsoleWrite("$nmsg " & $nMsg & Chr(13))
;~              the idea was that each time an input box was clicked I would record it and when browse was clicked I would know the last input box..
            Case $btnBrowse
                $sInitialDir = "C:\Temp"
                ConsoleWrite($iLastInptBox)
                If FileExists(GUICtrlRead($iLastInptBox)) Then $sInitialDir = GUICtrlRead($iLastInptBox)
                $sDirTemp = FileSelectFolder("Select folder", "",1,$sInitialDir)
                If $sDirTemp <> "" Then GUICtrlSetData($iLastInptBox, $sDirTemp)
;~          need to open file dialog box, allow user to select directory, store the directory in the inptbox.
;~          the starting directory should be the current base directory
;~          once a directory is selected by the user it should be checked that it starts with the base directory AND
            Case $btnApply
;~          run path check if "Check on Apply" is true. If errors highlight on form...do not apply.
;~          save each of the inputbox settings to each of the variables.
            Case $btnReset
;~          call in settings when form was loaded. This will be based on information in Main.ini...either program defaults, loaded ini file or last saved settings
            Case $btnLoadDefault
;~          load program defaults from main.ini
            Case $btnSetAsDefault
;~          set the current setting as the Program Defaults
            Case $btnSaveAsIni
;~          save the current settings to an ini file. Need to open a file save as dialog box or similar.
;~          if the file exists ask user if they want to overwrite or merge / add...allows same .ini file to be used for gphotoshow settings.
            Case $btnLoadIni
;~          load a user selected ini file into the input boxes
            Case $btnCheckPaths
;~          do a fileexists on all paths
;~          if path does not exist ask user if they want to create it...if not highlight it on the form (make inputbox red)...could do this live too.
        EndSwitch
    WEnd


EndFunc  ;==>GUI_Global_Defaults
Link to comment
Share on other sites

  • Moderators

JasonLA,

Welcome to the AutoIt forums.

You have certianly grasped the essentials for getting a reply here - some code to work on and a clear question! I wish others would follow your lead.

The following will do what you want. I have based it in your code, but I have removed a lot of the lines for clarity:

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#Include <WinAPI.au3>

Global $aHandles[6]
Global $hInputFocus

_gui_global_defaults()

Func _GUI_Global_Defaults()
    
    $frmGlobalDefaults = GUICreate("Global Defaults", 620, 558, 371, 125)
    
    $inptbxRegFileName = GUICtrlCreateInput("inptbxRegFileName", 160, 24, 300, 21)
        $aHandles[1] = ControlGetHandle($frmGlobalDefaults, "", $inptbxRegFileName)
    $inptbxDirBase = GUICtrlCreateInput("inptbxDirBase", 160, 80, 300, 21)
        $aHandles[2] = ControlGetHandle($frmGlobalDefaults, "", $inptbxDirBase)
    $inptbxDirAlbum = GUICtrlCreateInput("inptbxDirAlbum", 160, 136, 300, 21)
        $aHandles[3] = ControlGetHandle($frmGlobalDefaults, "", $inptbxDirAlbum)
    $inptbxDirSettings = GUICtrlCreateInput("inptbxDirSettings", 160, 192, 300, 21)
        $aHandles[4] = ControlGetHandle($frmGlobalDefaults, "", $inptbxDirSettings)
    $inptbxDirHP = GUICtrlCreateInput("inptbxDirHP", 160, 248, 300, 21)
        $aHandles[5] = ControlGetHandle($frmGlobalDefaults, "", $inptbxDirHP)
        
    $btnBrowse = GUICtrlCreateButton("&Browse", 480, 24, 107, 425, 0)
    
    GUISetState()
    
    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE
                Exit
            Case $btnBrowse
            ; See which input last had keyboard focus
                For $i = 1 To 5
                    If $aHandles[$i] = $hInputFocus Then MsgBox(0,"Result", "You had the cursor in Input " & $i)
                Next
        EndSwitch
        
    ; See if an input has keyboard focus
        $hFocus = _WinAPI_GetFocus()
        For $i = 1 To 5
            If $hFocus = $aHandles[$i] Then $hInputFocus = $hFocus
        Next
            
    WEnd

EndFunc

To ease the task of finding the ControlID of the correct input box once you have the index, you might like to put the ControlIDs of the inputs into another array as you create them.

Ask if anything is unclear.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

And another way, similar but different, without the array of control handles:

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

Global $hInputFocus

_GUI_Global_Defaults()

Func _GUI_Global_Defaults()

    $frmGlobalDefaults = GUICreate("Global Defaults", 620, 558, 371, 125)
    $inptbxRegFileName = GUICtrlCreateInput("inptbxRegFileName", 160, 24, 300, 21)
    $inptbxDirBase = GUICtrlCreateInput("inptbxDirBase", 160, 80, 300, 21)
    $inptbxDirAlbum = GUICtrlCreateInput("inptbxDirAlbum", 160, 136, 300, 21)
    $inptbxDirSettings = GUICtrlCreateInput("inptbxDirSettings", 160, 192, 300, 21)
    $inptbxDirHP = GUICtrlCreateInput("inptbxDirHP", 160, 248, 300, 21)

    $btnBrowse = GUICtrlCreateButton("&Browse", 480, 24, 107, 425, 0)

    GUISetState()

    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE
                Exit
            Case $btnBrowse
            ; See which input last had keyboard focus
                For $i = $inptbxRegFileName To $inptbxDirHP
                    If $i = $hInputFocus Then MsgBox(0, "Result", "You had the cursor in Input " & $i - $inptbxRegFileName + 1)
                Next

        EndSwitch

    ; See if an input has keyboard focus
        $hFocus = _GuiCtrlGetFocus()
        Switch $hFocus
            Case $inptbxRegFileName To $inptbxDirHP
                $hInputFocus = $hFocus
        EndSwitch


    WEnd

EndFunc  ;==>_GUI_Global_Defaults


Func _GuiCtrlGetFocus($frmGui = "")
;http://www.autoitscript.com/forum/index.php?s=&showtopic=84500&view=findpost&p=605389 by AoRaToS
    Local $InputID = ControlGetHandle($frmGui, "", ControlGetFocus($frmGui))
    Return _ControlGetGuiID($InputID)
EndFunc  ;==>_GuiCtrlGetFocus

Func _ControlGetGuiID($hCtrl)
    Local $Result = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hCtrl)
    Return $Result[0]
EndFunc  ;==>_ControlGetGuiID

[

Link to comment
Share on other sites

@JasonLA

use on event notification messages from the edit controls

that way you don't need to continually check in the main loop in either message or on-event modes

The EN_KILLFOCUS edit control message indicates an edit control has just lost focus

the low word of the $wParam parameter is the Edit control ID

set a global variable to that value and you have your last Input control selected.

Search forum for 'EN_CHANGE' and 'EN_UPDATE' messages for other things you can do with Input (Edit) controls

you could set focus by default to the first Input control or set your $cLastInputFocus variable to controlID

Edit left out wParam description

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

Global $cLastInputFocus = 0; last Edit control ID buffer

_GUI_Global_Defaults()

Func _GUI_Global_Defaults()

    $frmGlobalDefaults = GUICreate("Global Defaults", 620, 558, 371, 125)
    $btnBrowse = GUICtrlCreateButton("&Browse", 480, 24, 107, 425, 0)
    GUICtrlSetState(-1, $GUI_FOCUS);set focus to button
    $inptbxRegFileName = GUICtrlCreateInput("inptbxRegFileName " & $btnBrowse+1, 160, 24, 300, 21)
;GUICtrlSetState(-1, $GUI_FOCUS)     ; set default control focus
;$cLastInputFocus = $inptbxRegFileName; set default last Edit control ID
    $inptbxDirBase = GUICtrlCreateInput("inptbxDirBase " & $btnBrowse+2, 160, 80, 300, 21)
    $inptbxDirAlbum = GUICtrlCreateInput("inptbxDirAlbum " & $btnBrowse+3, 160, 136, 300, 21)
    $inptbxDirSettings = GUICtrlCreateInput("inptbxDirSettings " & $btnBrowse+4, 160, 192, 300, 21)
    $inptbxDirHP = GUICtrlCreateInput("inptbxDirHP " & $btnBrowse+5, 160, 248, 300, 21)

    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
    GUISetState()

    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE
                Exit
            Case $btnBrowse
                If $cLastInputFocus Then
                    MsgBox(262144, "Result", "You had the cursor in Input control ID: " & $cLastInputFocus)
                Else
                    MsgBox(262144, "Result", "Select Input control with mouse cursor or keyboard")
                EndIf
                
        EndSwitch
    WEnd

EndFunc;==>_GUI_Global_Defaults

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    Local $nNotifyCode = BitShift($wParam, 16)
    Local $nID = BitAND($wParam, 0x0000FFFF)
    If $nNotifyCode = $EN_KILLFOCUS Then $cLastInputFocus = $nID

;~  Switch $nNotifyCode; Edit control event messages only
;~      Case $EN_SETFOCUS; Edit (Input) control has focus
;~  ;ConsoleWrite('+$nID = ' & $nID & @crlf); control ID of Input edit control with focus
;~  ;ConsoleWrite('+ControlGetFocus = ' & ControlGetFocus($hWnd) & @crlf); the ClassNameNN of control 'Edit#'
;~  ;If $nID <> $cLastInputFocus Then
;~      ;$cLastInputFocus = $nID
;~  ;EndIf
;~      Case $EN_KILLFOCUS; Edit (Input) control lost focus
;~          $cLastInputFocus = $nID
;~  ;ConsoleWrite('+$nID = ' & $nID & @crlf); control ID of Input edit control with focus
;~  ;ConsoleWrite('+ControlGetFocus = ' & ControlGetFocus($hWnd) & @crlf); the ClassNameNN of control 'Edit#'
;~  EndSwitch
    
    Return $GUI_RUNDEFMSG
EndFunc
Edited by rover

I see fascists...

Link to comment
Share on other sites

  • Moderators

ResNullius and rover,

Thank you for sharing those improved versions.

I was searching for a way to get the ControlID from the handle - rather more complicated than I imagined.

And I was sure there was some kind of notification - I now know which (and how to code for it!)

Thanks again for the much appreciated tutorial.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
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
 Share

  • Recently Browsing   0 members

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