Sign in to follow this  
Followers 0
therks

Test specific control for focus

18 posts in this topic

Anybody have suggestions or methods on how I can test to see if a control currently has the focus? I ask because I'd like to have the Enter key hotkeyed to do something different if the focus is in one of two different fields. Does that make sense?

Share this post


Link to post
Share on other sites



ControlGetFocus


Who else would I be?

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Well, okay, but that returns things like "Edit1" and "Button2"

I need to translate that into GUI control ID's. Plus, that function doesn't work so well if I have two windows with the same name. I was kind of hoping there was a GUI specific function that did what I was looking for...

I guess I'm just too used to HTML/Javascript's onfocus event handler :)

Edited by Saunders

Share this post


Link to post
Share on other sites

Do you want something like "On Click"?

Use GUIGetMsg in a loop.

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

No see, in HTML/Javascript there are many event handlers. onfocus, onblur, onmouseover, onload, and yes, even onclick (there's even ondblclick) among many others. I was only using that as an example. And in fact, the ControlGetFocus function would work fine, if I could only translate the return values into GUI Control IDs. (And actually, by rights, even using it the way it is now will work, I just have to hard code that Edit1 and Edit2 corresponds to my control IDs).

I've attached a picture to show the GUI I've created, and hopefully explains exactly what it is I'm after.

Edited by Saunders

Share this post


Link to post
Share on other sites

Was there ever an answer to this q?

I have been searching forums.

I have AutoIt GUI; I want Enter to "Simulate Tab" on most controls, but to "Submit" on one or two controls.

I use Simulate Tab technique of CyberSlug. But when it tabs over to the "Submit" button, I don't know how to make AutoIt recognize that a particular control is focussed.

Here is Simulate Tab as I have tweaked it up from CyberSlug:

;^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v

Func SimulateTab()
  If WinActive($g_ThisProgID) And ((ControlGetFocus($g_ThisProgID) = $SendBtn) Or (ControlGetFocus($g_ThisProgID) = $QuitBtn)) Then
    HotKeySet("{Enter}");unregister hotkey in case we call a MsgBox
    MsgBox(4096, "Info", "Send or Quit pressed")
  Else
    Send("{Tab}")
  EndIf
EndFunc  ;==>SimulateTab
;^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v

It does not work as desired.

J


If I am too verbose, just say so. You don't need to run on and on.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

I don't know, but maybe a workaround is possible without using the focus thing.

My idea is that when the user click on the the either the "Username" or the

"Password" input-controls, then you can make it set a variable that says that ENTER

simulates clicking the "Switch User"-button.

Though this requires that GUIGetMsg is able to receive clicks from "Input"-controls,

and I can't remember if it does that..

Would this work ?

(Unable to test myself)

Edited by Helge

Share this post


Link to post
Share on other sites

I know I've brought up the request for a GuiGetFocus or something function.... but I never knew about the GetDlgCtrlID until now! Here's a UDF for you:

; Sample gui has buttons whose names reflect the Ctrl ID #
; Gui title tells us the control with focus

#include <GuiConstants.au3>
$GUI = GuiCreate("Has focus:")

$one = GuiCtrlCreateButton("", 10, 10, 100, 50)
    GuiCtrlSetData(-1, "ButtonID " & $one)
$two = GuiCtrlCreateButton("two", 10, 110, 100, 50)
    GuiCtrlSetData(-1, "ButtonID " & $two)
$three = GuiCtrlCreateButton("three", 10, 210, 100, 50)
    GuiCtrlSetData(-1, "ButtonID " & $three)
    
GuiSetState()
While GuiGetMsg() <> $GUI_EVENT_CLOSE
; Constantly update title; I'm too lazy to prevent the flicker
    WinSetTitle($GUI, "", "Has focus: " & _GuiCtrlGetFocus($GUI))
WEnd


Func _GuiCtrlGetFocus($GuiRef)
    Local $hwnd = ControlGetHandle($GuiRef, "", ControlGetFocus($GuiRef))
    Local $result = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hwnd)
    Return $result[0]
EndFunc

Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!

Share this post


Link to post
Share on other sites

I know I've brought up the request for a GuiGetFocus or something function.... but I never knew about the GetDlgCtrlID until now!  Here's a UDF for you:

; Sample gui has buttons whose names reflect the Ctrl ID #
; Gui title tells us the control with focus

#include <GuiConstants.au3>
$GUI = GuiCreate("Has focus:")

$one = GuiCtrlCreateButton("", 10, 10, 100, 50)
    GuiCtrlSetData(-1, "ButtonID " & $one)
$two = GuiCtrlCreateButton("two", 10, 110, 100, 50)
    GuiCtrlSetData(-1, "ButtonID " & $two)
$three = GuiCtrlCreateButton("three", 10, 210, 100, 50)
    GuiCtrlSetData(-1, "ButtonID " & $three)
    
GuiSetState()
While GuiGetMsg() <> $GUI_EVENT_CLOSE
; Constantly update title; I'm too lazy to prevent the flicker
    WinSetTitle($GUI, "", "Has focus: " & _GuiCtrlGetFocus($GUI))
WEnd
Func _GuiCtrlGetFocus($GuiRef)
    Local $hwnd = ControlGetHandle($GuiRef, "", ControlGetFocus($GuiRef))
    Local $result = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hwnd)
    Return $result[0]
EndFunc

<{POST_SNAPBACK}>

Interesting info. Thanks.

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

That's the ticket, CyberSlug.

A useful fn, I think.

Thanks.

J :lmao:

PS I couldn't get it to work right out of the box. I keep getting the "tab number" back for the result of _GuiCtrlGetFocus. Mind you I altered your original stuff, and I am rushing, thus I show you this kludge which works, though I don't have time to make a meaningful example -- this is right out of my script:

This gets the IDs that AutoIt really wants:

CreateGUI ("OrigGUI")
    GUICtrlSetState($SendBtn, $GUI_FOCUS)
    $SendBtnID = _GuiCtrlGetFocus($GUI)
;   MsgBox(0, "", String($SendBtnID))
    GUICtrlSetState($QuitBtn, $GUI_FOCUS)
    $QuitBtnID = _GuiCtrlGetFocus($GUI)
;   MsgBox(0, "", String($QuitBtnID))
    GUICtrlSetState($PartNumEdit, $GUI_FOCUS)

Then when user hits enter:

;^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v

Func SimulateTab()
  If WinActive($g_ThisProgID) And (_GuiCtrlGetFocus ($GUI) = $SendBtnID) Then
    HotKeySet("{Enter}");unregister hotkey in case we call a MsgBox
    SendBtnClick()
  Else
    If WinActive($g_ThisProgID) And (_GuiCtrlGetFocus ($GUI) = $QuitBtnID) Then
      HotKeySet("{Enter}");unregister hotkey in case we call a MsgBox
      QuitBtnClick()
    Else
      Send("{Tab}")
    EndIf
  EndIf
EndFunc  ;==>SimulateTab
;^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v

J

Edited by jdickens

If I am too verbose, just say so. You don't need to run on and on.

Share this post


Link to post
Share on other sites

Very very useful function Cyberslug.. Thanks for sharing!!

; Constantly update title; I'm too lazy to prevent the flicker

Btw: I don't get/see any flicker on mine.

Dell Optiplex GX240

XP Pro, SP2, 256M Ram, ATI Rage 128 Pro Ultra GL AGP

AutoIt Version: 3.0.103.168

RocTx

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

I came across this topic via search to find out which control the text cursor was in. I don't know what the problem is in my case but I have a listview control which is ALWAYS returned as the control with focus. I tried the code above but was getting the same issue.

I changed it around as follows and it works perfect. (For any looking for the same thing)

_API_GetFocus() is a function included in A3Library

Func _GuiCtrlGetFocus($GuiRef)
    $hwnd = _API_GetFocus()
    Local $result = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hwnd)
    Return $result[0]
EndFunc
Edited by jfisher

Share this post


Link to post
Share on other sites

Actually there is a bit of a flaw with this function still. Valik helped me out with this one. Test out your function when you are focussed on a combo control. You'll notice that the control ID it returns is not what you were expecting. This is because the edit area of the combo is a separate control, and the function is returning the ID for that edit specifically. The solution for this situation is to perform an extra check, basically using the following algorithm:

Get classname of focussed control.
  If classname is EDIT then check parent control's classname.
    If parent control classname is COMBO then return parent control's handle.
    If parent control classname is NOT COMBO then return original control's handle.
  If classname is NOT EDIT then return control's handle.
Done

All that is wrapped up in a UDF I have here: http://www.therks.com/autoit/udfs/_GUIGetFocus.au3

Share this post


Link to post
Share on other sites

Actually there is a bit of a flaw with this function still. Valik helped me out with this one. Test out your function when you are focussed on a combo control. You'll notice that the control ID it returns is not what you were expecting. This is because the edit area of the combo is a separate control, and the function is returning the ID for that edit specifically. The solution for this situation is to perform an extra check, basically using the following algorithm:

Get classname of focussed control.
  If classname is EDIT then check parent control's classname.
    If parent control classname is COMBO then return parent control's handle.
    If parent control classname is NOT COMBO then return original control's handle.
  If classname is NOT EDIT then return control's handle.
Done

All that is wrapped up in a UDF I have here: http://www.therks.com/autoit/udfs/_GUIGetFocus.au3

Great! Thanks.

I've used it already in my AutoMonit script.


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

Cool, glad someone found it useful. I was kind of afraid of reviving a thread more than a week old. Glad to see it suited some purpose. :)

Share this post


Link to post
Share on other sites

No see, in HTML/Javascript there are many event handlers. onfocus, onblur, onmouseover, onload, and yes, even onclick (there's even ondblclick) among many others. I was only using that as an example. And in fact, the ControlGetFocus function would work fine, if I could only translate the return values into GUI Control IDs. (And actually, by rights, even using it the way it is now will work, I just have to hard code that Edit1 and Edit2 corresponds to my control IDs).

I've attached a picture to show the GUI I've created, and hopefully explains exactly what it is I'm after.

Funny, I am having the same issue....

I would like to know when the GUI goes out of focus to do an auto-save and I was hoping for something simple like

Case $msg = $GUI_EVENT_CLOSE
         exit
     Case $msg = $GUI_EVENT_MINIMIZE
         save()
     Case $msg = $GUI_EVENT_BLUR
         save()

seems the only commands are...

$GUI_EVENT_CLOSE

$GUI_EVENT_MINIMIZE

$GUI_EVENT_RESTORE

$GUI_EVENT_MAXIMIZE

$GUI_EVENT_PRIMARYDOWN

$GUI_EVENT_PRIMARYUP

$GUI_EVENT_SECONDARYDOWN

$GUI_EVENT_SECONDARYUP

$GUI_EVENT_MOUSEMOVE

$GUI_EVENT_RESIZED

$GUI_EVENT_DROPPED

I would love to see

$GUI_EVENT_BLUR

$GUI_EVENT_FOCUS

$GUI_EVENT_MOUSEOVER

and maybe even more

writing all this extra code not so nice <_<

Share this post


Link to post
Share on other sites

I know I've brought up the request for a GuiGetFocus or something function.... but I never knew about the GetDlgCtrlID until now! Here's a UDF for you:

; Sample gui has buttons whose names reflect the Ctrl ID #
; Gui title tells us the control with focus

#include <GuiConstants.au3>
$GUI = GuiCreate("Has focus:")

$one = GuiCtrlCreateButton("", 10, 10, 100, 50)
    GuiCtrlSetData(-1, "ButtonID " & $one)
$two = GuiCtrlCreateButton("two", 10, 110, 100, 50)
    GuiCtrlSetData(-1, "ButtonID " & $two)
$three = GuiCtrlCreateButton("three", 10, 210, 100, 50)
    GuiCtrlSetData(-1, "ButtonID " & $three)
    
GuiSetState()
While GuiGetMsg() <> $GUI_EVENT_CLOSE
; Constantly update title; I'm too lazy to prevent the flicker
    WinSetTitle($GUI, "", "Has focus: " & _GuiCtrlGetFocus($GUI))
WEnd
Func _GuiCtrlGetFocus($GuiRef)
    Local $hwnd = ControlGetHandle($GuiRef, "", ControlGetFocus($GuiRef))
    Local $result = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hwnd)
    Return $result[0]
EndFunc

I just wanted to say thumbs up to this... It took a little tweaking, but now I got my onfocus and onblur to work

this is the sample code. Great for an auto-save, and disable hotkeys (which may interfere with other programs)

$gui = GuiCreate("My Window", 520, 465);------------------ define someGui
HotKeySet("^s", "save") ; use ctrl+s to save
$focus = 1 ;- sets current focus

While 1
    $focusobj = _GuiCtrlGetFocus($gui) ;- this will return the current ClassNameNN of Gui Object, 0 if not in focus
    if $focus = 1 and $focusobj = 0 Then ;- if was in focus, but now not
        $focus=0
        save() ;- design to auto save the in information in the window when blurred
        HotKeySet("^s") ; disables
    EndIf
    if $focus = 0 and $focusobj <> 0 Then ;- if was blurred, but now if focus (its also possible to test for current Gui Object focus)
        $focus=1
        HotKeySet("^s", "save") ; re-enables the hotkey
    EndIf
    $msg = GuiGetMsg()
   Select
    Case $msg = $GUI_EVENT_CLOSE
                Exit
    Case $msg = $button_1
                 some_func()
   EndSelect
WEnd
Exit

Func save()
     ;- some routine
endFunc

Func _GuiCtrlGetFocus($GuiRef)
    Local $hwnd = ControlGetHandle($GuiRef, "", ControlGetFocus($GuiRef))
    Local $result = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hwnd)
    Return $result[0]
EndFunc

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