Sign in to follow this  
Followers 0
qwert

How to regain focus following Auto Insert?

16 posts in this topic

This is my third attempt at building an example to clearly show my problem and to express it in the simplest terms.

I have a button that, when clicked, inserts text into a input field -- an input field that normally receives keyboard input. The insert works fine, but the action disables the field for further key entry. This latest example tries to use _GUICtrlEdit_SetSel($ctrlInput, 0, -1) to reactivate the field and position the cursor -- but it doesn't work. Nor have the 20 other methods I've tried.

;   After clicking button (which inserts text into the field),
;   focus is lost and further key entry is blocked
;
#include <GUIConstants.au3>
#Include <GuiEdit.au3>

GUICreate("Example", 300, 277, -1, 240, $WS_SIZEBOX + $WS_SYSMENU)

$ctrlInput = GUICtrlCreateInput("", 20, 60, 260, 30, $ES_RIGHT)
GUICtrlSetFont($ctrlInput, 16, 600)

$Graphic1 = GUICtrlCreateButton("X", 33, 14, 100, 30);, $SS_NOTIFY + $SS_WHITEFRAME)

$clear = GUICtrlCreateButton("Clear", 50, 160, 40, 20)

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

While 1
    $msg = GUIGetMsg()
        Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $clear
            GUICtrlSetData( $ctrlInput, "" )
            ControlFocus("", "", $ctrlInput )   ; <<<<< this works to enable keyboard entry after "Clear"
        EndSwitch
WEnd

Func On_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iNotifyCode = BitShift($wParam, 16), $iID = BitAnd($wParam, 0x0000FFFF)
    If $iID = $Graphic1 Then
        Switch $iNotifyCode
            Case 0, 1; STN_CLICKED, STN_DBLCLK
                GUICtrlSetData( $ctrlInput, GUICtrlRead( $ctrlInput )  & "X" )
                _GUICtrlEdit_SetSel($ctrlInput, -1, -1)   ;<<<<<<<<<<<<  THIS DOESN'T WORK.  WHY NOT?
        EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

Some one suggested that I change to an Edit field. But my application works fine, except for this one problem, so I don't want to make any changes that lead me to other problems. Surely there's a way to do this. I can't help but believe it's a very common situation that been solved before -- and that my many searches and tests just haven't found it.

Thanks for listening and a solution will be greatly appreciated.

Share this post


Link to post
Share on other sites



Not really sure what you are trying to do here. Your code isn't well commented either. I looked at it and the only person it makes sense to is you. What are you trying to accomplish here? Your button is inserting text back into an input field that you are typing in? That doesn't make any sense. If your concern is just about focus then here:

;    After clicking button (which inserts text into the field),
;    focus is lost and further key entry is blocked
;
#include <GUIConstants.au3>
#Include <GuiEdit.au3>

GUICreate("Example", 300, 277, -1, 240, $WS_SIZEBOX + $WS_SYSMENU)

$ctrlInput = GUICtrlCreateInput("", 20, 60, 260, 30, $ES_RIGHT)
GUICtrlSetFont($ctrlInput, 16, 600)

$Graphic1 = GUICtrlCreateButton("X", 33, 14, 100, 30, $BS_DEFPUSHBUTTON);, $SS_NOTIFY + $SS_WHITEFRAME)

$clear = GUICtrlCreateButton("Clear", 50, 160, 40, 20)

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

While 1
    $msg = GUIGetMsg()
        Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $clear
            GUICtrlSetData( $ctrlInput, "" )
            ControlFocus("", "", $ctrlInput )   ; <<<<< this works to enable keyboard entry after "Clear"
        EndSwitch
WEnd

Func On_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iNotifyCode = BitShift($wParam, 16), $iID = BitAnd($wParam, 0x0000FFFF)
    If $iID = $Graphic1 Then
        Switch $iNotifyCode
            Case 0, 1; STN_CLICKED, STN_DBLCLK
                GUICtrlSetData( $ctrlInput, GUICtrlRead( $ctrlInput )  & "X" )
                ControlClick("","",$ctrlInput,-1,2)
        EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

I set your button behavior differently so you can just click the enter key and it automatically pushes. I used controlclick to shift focus back to the input box. However, again, not sure what you are trying to accomplish here and a lot of what you are doing in this code doesn't make much sense to me.


My Projects: [topic="89413"]GoogleHack Search[/topic], [topic="67095"]Swiss File Knife GUI[/topic], [topic="69072"]Mouse Location Pointer[/topic], [topic="86040"]Standard Deviation Calculator[/topic]

Share this post


Link to post
Share on other sites

Why are you using functions that are made for Edit controls?

You also don't need ControlFocus(). All you need is GUICtrlSetState($Input, $GUI_FOCUS)


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Why are you using functions that are made for Edit controls?

You also don't need ControlFocus(). All you need is GUICtrlSetState($Input, $GUI_FOCUS)

GEO that doesn't always work, especially in some edit controls. But, I agree with you that he should be using an edit control as it doesn't make much sense to me why he's not, or what he's trying to accomplish here. If you use $GUI_FOCUS in an edit control after placing text back into that edit control, the entire text will become "highlighted" (default behavior) and therefore, you would erase everything you type (if he's trying to keep the information). Therefore ControlClick does the same thing but you can designate a number of clicks to remove the highlight.

By the way here's a function I use in my own scripts:

Func _ControlFocus($hGUI, $cID, $cBTN)
    ControlClick($hGUI, "", $cID)
    GUICtrlSetState($cID, $GUI_FOCUS)
EndFunc   ;==>_ControlFocus
Edited by Ealric

My Projects: [topic="89413"]GoogleHack Search[/topic], [topic="67095"]Swiss File Knife GUI[/topic], [topic="69072"]Mouse Location Pointer[/topic], [topic="86040"]Standard Deviation Calculator[/topic]

Share this post


Link to post
Share on other sites

GEO that doesn't always work, especially in some edit controls. But, I agree with you that he should be using an edit control as it doesn't make much sense to me why he's not, or what he's trying to accomplish here. If you use $GUI_FOCUS in an edit control after placing text back into that edit control, the entire text will become "highlighted" (default behavior) and therefore, you would erase everything you type (if he's trying to keep the information). Therefore ControlClick does the same thing but you can designate a number of clicks to remove the highlight.

GUICtrlSetData($ctrlInput, GUICtrlRead($ctrlInput) & "X") will also save the data and add in what he wants or

GUICtrlSetState($ctrlInput, $GUI_FOCUS)

Send("{END"})

Will also do it.


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

GUICtrlSetData($ctrlInput, GUICtrlRead($ctrlInput) & "X") will also save the data and add in what he wants or

GUICtrlSetState($ctrlInput, $GUI_FOCUS)

Send("{END"})

Will also do it.

Yep, that's a good option to. I wrote a really large Macro Creator application for WoW that has extensive edit control features and controls. I might release it sometime soon to the forums so that people can see some examples. And, that is exactly what I do to maintain the ability for people to edit the edit control manually and still remember the data that was placed without accidentally having it overwritten at a future time.

Edit controls are "fun".


My Projects: [topic="89413"]GoogleHack Search[/topic], [topic="67095"]Swiss File Knife GUI[/topic], [topic="69072"]Mouse Location Pointer[/topic], [topic="86040"]Standard Deviation Calculator[/topic]

Share this post


Link to post
Share on other sites

Thanks to both of you for taking a look at this.

I keep trying to simplify my statement of intent, but I can see how it's confusing.

I have a simple input field -- that the user normally types into from the keyboard. But there are some common "operator codes" that are defined as buttons.

When users are typing into the field, they can click one of the buttons to insert an op code -- and then they expect to keep on typing. But the field is deactivated after the button action. They have to click back into the field to resume typing.

How can I place focus back on the input field -- with the cursor at the correct (end) position?

A good analogy would be a calculator, where the operators are the plus, minus, multiply, divide actions. Only in my application they're special "action verbs" for another process. Those are inserted by button clicks. All other input is from the keyboard.

Share this post


Link to post
Share on other sites

Thanks to both of you for taking a look at this.

I keep trying to simplify my statement of intent, but I can see how it's confusing.

I have a simple input field -- that the user normally types into from the keyboard. But there are some common "operator codes" that are defined as buttons.

When users are typing into the field, they can click one of the buttons to insert an op code -- and then they expect to keep on typing. But the field is deactivated after the button action. They have to click back into the field to resume typing.

How can I place focus back on the input field -- with the cursor at the correct (end) position?

A good analogy would be a calculator, where the operators are the plus, minus, multiply, divide actions. Only in my application they're special "action verbs" for another process. Those are inserted by button clicks. All other input is from the keyboard.

So, when each person types in the input control and they press a button (the operator button decides where to place the inputted text), then you want the input control "cleared" and focus placed back into the control? Or do you want the focus placed back into the control with existing text, and the cursor placed after the text still there?


My Projects: [topic="89413"]GoogleHack Search[/topic], [topic="67095"]Swiss File Knife GUI[/topic], [topic="69072"]Mouse Location Pointer[/topic], [topic="86040"]Standard Deviation Calculator[/topic]

Share this post


Link to post
Share on other sites

focus placed back into the control with existing text, and the cursor placed after the text still there

And the suggestion of adding a Send("{End}") almost produces the result I need (see example below). The problem is that the field sometimes flickers as a button click is made. The slight flash effect seems to be related to the fact that the contents of a field are highlighted when it receives focus. If you know of a way around that, then the problem is solved.

;   After clicking button (which inserts text into the field),
;   focus is lost and further key entry is blocked
;
#include <GUIConstants.au3>
#Include <GuiEdit.au3>

GUICreate("Example", 300, 277, -1, 240, $WS_SIZEBOX + $WS_SYSMENU)

$ctrlInput = GUICtrlCreateInput("", 20, 60, 260, 30, $ES_RIGHT)
GUICtrlSetFont($ctrlInput, 16, 600)

$Graphic1 = GUICtrlCreateButton("X", 33, 14, 100, 30);, $SS_NOTIFY + $SS_WHITEFRAME)

$clear = GUICtrlCreateButton("Clear", 50, 160, 40, 20)

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

While 1
    $msg = GUIGetMsg()
        Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $clear
            GUICtrlSetData( $ctrlInput, "" )
            ControlFocus("", "", $ctrlInput )   ; <<<<< this works to enable keyboard entry after "Clear"
        EndSwitch
WEnd

Func On_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iNotifyCode = BitShift($wParam, 16), $iID = BitAnd($wParam, 0x0000FFFF)
    If $iID = $Graphic1 Then
        Switch $iNotifyCode
            Case 0, 1; STN_CLICKED, STN_DBLCLK
                GUICtrlSetData( $ctrlInput, GUICtrlRead( $ctrlInput )  & "X" )
                GUICtrlSetState($ctrlInput, $GUI_FOCUS)
                Send("{END}")
        EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

Share this post


Link to post
Share on other sites

Here this will work:

;    After clicking button (which inserts text into the field),
;    focus is lost and further key entry is blocked
;
#include <GUIConstants.au3>
#Include <GuiEdit.au3>

Global $message

Global $parent = GUICreate("Example", 300, 277, -1, 240, $WS_SIZEBOX + $WS_SYSMENU)

Global $ctrlInput = GUICtrlCreateInput("", 20, 60, 260, 30, $ES_RIGHT)
GUICtrlSetFont($ctrlInput, 16, 600)

$Graphic1 = GUICtrlCreateButton("X", 33, 14, 100, 30)

$clear = GUICtrlCreateButton("Clear", 50, 160, 40, 20)

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

While 1
    $msg = GUIGetMsg()
    sleep(0100)
    _readinput()
        Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $clear
            GUICtrlSetData( $ctrlInput, "" )
            ControlFocus("", "", $ctrlInput )   ; <<<<< this works to enable keyboard entry after "Clear"
        EndSwitch
WEnd

Func On_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iNotifyCode = BitShift($wParam, 16), $iID = BitAnd($wParam, 0x0000FFFF)
    If $iID = $Graphic1 Then
        Switch $iNotifyCode
            Case 0, 1; STN_CLICKED, STN_DBLCLK
                _ControlFocus($parent, $ctrlInput)
                GUICtrlSetData( $ctrlInput, $message & "X" )
        EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

Func _readinput()
    $message = GUICtrlRead($ctrlInput)
EndFunc

Func _ControlFocus($hGUI, $cID)
    ControlClick($hGUI, "", $cID)
    GUICtrlSetState($cID, $GUI_FOCUS)
    Send("{END}")
EndFunc   ;==>_ControlFocus

My Projects: [topic="89413"]GoogleHack Search[/topic], [topic="67095"]Swiss File Knife GUI[/topic], [topic="69072"]Mouse Location Pointer[/topic], [topic="86040"]Standard Deviation Calculator[/topic]

Share this post


Link to post
Share on other sites

So, when each person types in the input control and they press a button (the operator button decides where to place the inputted text), then you want the input control "cleared" and focus placed back into the control? Or do you want the focus placed back into the control with existing text, and the cursor placed after the text still there?

and I told you how to do it. :)

Create a new script with this code

#include <GUIConstants.au3>
GUICreate("MyGUI", 300, 100)
$Input = GUICtrlCreateInput("", 10, 10, 280, 20)
$Btn = GUICtrlCreateButton("Button 1", 120, 50, 60, 30)
GUISetState()
While 1
   $Msg = GUIGetMsg()
   Switch $Msg
      Case -3
         Exit
      Case $Btn
         GUICtrlSetData($Input, "This is some characters")
         GUICtrlSetState($Input, $GUI_FOCUS) 
        ;Send("{END}");;<<< For the second test uncomment this line
   EndSwitch
Wend

What happens?

Now uncomment line 14 and run it again. What happens now?


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

Thanks again to you both.

The problem now is the flicker -- as demonstrated in the (last) example I posted. The field needs to stay rock solid on the screen. This doesn't seem too much to expect, so I haven't given up -- yet.

Share this post


Link to post
Share on other sites

Thanks again to you both.

The problem now is the flicker -- as demonstrated in the (last) example I posted. The field needs to stay rock solid on the screen. This doesn't seem too much to expect, so I haven't given up -- yet.

I don't get a flicker with the code you posted but I made a couple of changes anyway. Also you forgot to #Include 1 file (depending on version) and I changed 1 of the includes and a change in the code itself.

#include <GUIConstants.au3>
#include <EditConstants.au3>
#include<WindowsConstants.au3>
GUICreate("Example", 300, 277, -1, 240, $WS_SIZEBOX + $WS_SYSMENU)

$ctrlInput = GUICtrlCreateInput("", 20, 60, 260, 30, $ES_RIGHT)
GUICtrlSetFont($ctrlInput, 16, 600)

$Graphic1 = GUICtrlCreateButton("X", 33, 14, 100, 30);, $SS_NOTIFY + $SS_WHITEFRAME)

$clear = GUICtrlCreateButton("Clear", 50, 160, 40, 20)

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

While 1
    $msg = GUIGetMsg()
        Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $clear
            GUICtrlSetData( $ctrlInput, "" )
            GUICtrlSetState($ctrlInput, $GUI_FOCUS)
        EndSwitch
WEnd

Func On_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iNotifyCode = BitShift($wParam, 16), $iID = BitAnd($wParam, 0x0000FFFF)
    If $iID = $Graphic1 Then
        Switch $iNotifyCode
            Case 0, 1; STN_CLICKED, STN_DBLCLK
                GUICtrlSetData( $ctrlInput, GUICtrlRead( $ctrlInput )  & "X" )
                GUICtrlSetState($ctrlInput, $GUI_FOCUS)
                Send("{END}")
        EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

GEOSoft, I just loaded and ran what you posted.

It's a very good result. But I still get an intermittent flicker when the button is clicked repeatedly. Keyboard entry NEVER flashes, it's rock solid. I just need that same result from the button.

To see what I mean, press X on the keyboard ten times rapidly. The click the X button 10 times rapidly.

Do you see it? Any at all?

Share this post


Link to post
Share on other sites

GEOSoft, I just loaded and ran what you posted.

It's a very good result. But I still get an intermittent flicker when the button is clicked repeatedly. Keyboard entry NEVER flashes, it's rock solid. I just need that same result from the button.

To see what I mean, press X on the keyboard ten times rapidly. The click the X button 10 times rapidly.

Do you see it? Any at all?

Only the flicker caused by the cursor refresh. BTW the code I gave does not have the button set as default button so the enter key won't work. I did change that so I could test though. On your actual GUI how many of these buttons to you have?

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

There are currently 8 different ones. BTW, the flicker I'm talking about is probably the "cursor refresh" you referred to. As I said, keyboard input is rock solid. Only characters inserted by the button induce a flash -- a "refresh" where the entire field is highlighted, maybe for only a millisecond or two. But that's never the case with keyboard input. Even if you slowly click the button -- click down/pause/release -- you'll often seen the flash, so it has nothing to do with the repeated clicks "stacking up" in processing.

At this point I think the problem is centered around the fact that "focus" highlights characters in the field as a default behavior. Can that be avoided?

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