Sign in to follow this  
Followers 0
jacQues

Setting focus with inputs and buttons.

13 posts in this topic

I have a GUI with multiple inputs and multiple buttons.

When an input value is changed this triggers GUIGetMsg() = input control

Then the program acts depending on the new value (using GUICtrlRead()).

It will change the focus using GUICtrlSetState() to a specific other input.

However, when I edit an input and then use the mouse to click a button, the button doesn't "work".

This is because GUIGetMsg() will pass the values in order, e.g. 1) input control, 2) mouse down, 3) button check.

The weird thing is that when the focus is set to another input after 1), the button press isn't send by GUIGetMsg().

HELP! How can I get a workaround? GUIGetMsg(1) doesn't give me any usable info.

There is no function (AFAIK) to check where the focus is at, GUICtrlGetState() never returns BitAnd($GUI_FOCUS).

jacQues

Share this post


Link to post
Share on other sites



if i am getting you right you have problems with your buttons?

why not simply have your GuiGetMsg() listen to the button as well?

Share this post


Link to post
Share on other sites

if i am getting you right you have problems with your buttons?

why not simply have your GuiGetMsg() listen to the button as well?

I do that, but it doesn't always work. E.G. Edit input field, then click button yields:

1) GUIGetMsg() returns input control, my loop examines the input and changes focus.

2) GUIGetMsg() returns mousedown and/or other stuff.

3) GUIGetMsg() returns button control.

3) never happens if the focus is changed.

jacQues

Share this post


Link to post
Share on other sites

would you post your source or the GuiGetMSG() + button/input box part of it?

Share this post


Link to post
Share on other sites

would you post your source or the GuiGetMSG() + button/input box part of it?

Uhm, its HUGE! (over 200K) I tried to cut it down but its not easy. Simplistic version of just the loop:

FUNC EditStuff()
; Create GUI with loads of input boxes and some buttons...
GuiSetState()
$n1_focus = 0
WHILE TRUE
   $msg = GUIGetMsg()
   SWITCH $msg
   CASE $GUI_EVENT_MOUSEMOVE
   CASE $n1_ok
      EXITLOOP
   CASE $n1_stuff
      MsgBox(0,"test","stuff")
     ; Do stuff - but the loop only gets here when clicked without editing an input box directly before clicking...
   CASE $n1_cancel, $GUI_EVENT_CLOSE
      RETURN
   CASE 0
      IF $n1_focus THEN
         GUICtrlSetState($n1_focus,$GUI_FOCUS)
         $n1_focus = 0
      ENDIF
   CASE ELSE
      FOR $x = 1 TO $inputbox[0]
         IF $msg=$inputbox[$x] THEN
           ; Code here that checks ALL inputs.
            IF $x<$inputbox[0] THEN
               $n1_focus = $inputbox[$x+1]
            ENDIF
            CONTINUELOOP 2
         ENDIF
      NEXT
   ENDSWITCH
WEND
; Save data...
ENDFUNC

Share this post


Link to post
Share on other sites

Uhm, its HUGE! (over 200K) I tried to cut it down but its not easy. Simplistic version of just the loop:

FUNC EditStuff()
; Create GUI with loads of input boxes and some buttons...
GuiSetState()
$n1_focus = 0
WHILE TRUE
   $msg = GUIGetMsg()
   SWITCH $msg
   CASE $GUI_EVENT_MOUSEMOVE
   CASE $n1_ok
      EXITLOOP
   CASE $n1_stuff
      MsgBox(0,"test","stuff")
    ; Do stuff - but the loop only gets here when clicked without editing an input box directly before clicking...
   CASE $n1_cancel, $GUI_EVENT_CLOSE
      RETURN
   CASE 0
      IF $n1_focus THEN
         GUICtrlSetState($n1_focus,$GUI_FOCUS)
         $n1_focus = 0
      ENDIF
   CASE ELSE
      FOR $x = 1 TO $inputbox[0]
         IF $msg=$inputbox[$x] THEN
          ; Code here that checks ALL inputs.
            IF $x<$inputbox[0] THEN
               $n1_focus = $inputbox[$x+1]
            ENDIF
            CONTINUELOOP 2
         ENDIF
      NEXT
   ENDSWITCH
WEND
; Save data...
ENDFUNC

I don't have an answer for you, But I do something similar but use ControlGetFocus ( "title" [, "text"] ) and ControlFocus ( "title", "text", controlID ) instead. my examples are unfortunately at work, but will be happy to post tomorrow.

But it goes somthing like this

set the var of my inputboxes as an array...inputbox[1], Inputbox[2]...etc

my case(s) are

case inputbox[1]

do whatever here.

Controlfocus("title","",inputbox[$msg+1]) ; this moves focus to next inputbox, but I can just as well force it to any Input or button, by var name.

$cursor = controlgetfocus("title") ; $cursor is the actual internal ID of the Control with focus.

hope this helps

Share this post


Link to post
Share on other sites

I have made some notes and placed them in upper case in this version of your code:

Func EditStuff()
; Create GUI with loads of input boxes and some buttons...
    GUISetState()
    $n1_focus = 0
    While True
        $msg = GUIGetMsg()
        Switch $msg
        ; THE FOLLOWING LINE, PROBABLY SHOULD NOT BE HERE:
            Case $GUI_EVENT_MOUSEMOVE
            ; WHAT IS SUPPOSED TO TRIGGER HERE?
            Case $n1_ok
                ExitLoop
            Case $n1_stuff
                MsgBox(0, "test", "stuff")
            ; Do stuff - but the loop only gets here when clicked without editing an input box directly before clicking...
            Case $n1_cancel, $GUI_EVENT_CLOSE
                Return
        ; THE FOLLOWING LINE, MIGHT BE THE SAME CASE AS THE "CASE ELSE" which would be "0" -
            Case 0
                If $n1_focus Then
                    GUICtrlSetState($n1_focus, $GUI_FOCUS)
                    $n1_focus = 0
                EndIf
            Case Else
                For $x = 1 To $inputbox[0]
                ;IT IS NOT A GOOD IDEA TO NEST INDENTICAL CONDITIONS - $msg IS ALREADY BEING CHECKED IN THE CASE STRUCTURE:
                    If $msg = $inputbox[$x] Then
                    ; Code here that checks ALL inputs.
                        If $x < $inputbox[0] Then
                            $n1_focus = $inputbox[$x + 1]
                        EndIf
                        ContinueLoop 2
                    EndIf
                Next
        EndSwitch
    WEnd
; Save data...
EndFunc  ;==>EditStuff

Your code looks as though you have never studied the work of any of the expert coders here on the forums. As a remedy for your being hereby referred to verse 6 of the Canon (see below in my signature) you might take on a less complicated project than this one, whatever it is IDK. :)


Das Häschen benutzt Radar

Share this post


Link to post
Share on other sites

; THE FOLLOWING LINE, PROBABLY SHOULD NOT BE HERE:

Case $GUI_EVENT_MOUSEMOVE

Yes it should, otherwise all inputboxes are checked (see last comment) unneeded when the mouse is moved. Its to save processor cycles.

; WHAT IS SUPPOSED TO TRIGGER HERE?

Case $n1_ok

Clicking the OK button. Its an extract of the AU3 remember.

; THE FOLLOWING LINE, MIGHT BE THE SAME CASE AS THE "CASE ELSE" which would be "0" -

Case 0

Definitely not, GUIGetMsg() results:

<0 = system event like mouse move and such

0 = no event

>0 = control event like button click and such

For $x = 1 To $inputbox[0]

;IT IS NOT A GOOD IDEA TO NEST INDENTICAL CONDITIONS - $msg IS ALREADY BEING CHECKED IN THE CASE STRUCTURE:

If $msg = $inputbox[$x] Then

Here I check for each inputbox if its being updated.

Not identical and not possible in the main CASE, because the number of inputboxes varies.

jacQues

Share this post


Link to post
Share on other sites

Here I check for each inputbox if its being updated.

Not identical and not possible in the main CASE, because the number of inputboxes varies.

jacQues

could you do something like

case else

$Xx= controlgetfocus("","")

if stringinstr($xx,"Edit") then

$num = stringright($xx,stringlen($xx)-4)

switch $num

case 4 to $inputbox[0]

Msgbox(0,"Worked",$Xx)

endswitch

endif

endswitch

Just to get rid of that strange loop at the end.

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

...get rid of that strange loop at the end.

@jaQues - IDK what programming languages you used to use, but I myself have never got the kind of code to work that nests identical conditions. If you are above the age of 15, you are doubly referred hereby, to verse 6 of the Canon.

Rewrite your case stucture, take two aspirin and call me in the morning.

Edited by Squirrely1

Das Häschen benutzt Radar

Share this post


Link to post
Share on other sites

@jaQues - IDK what programming languages you used to use, but I myself have never got the kind of code to work that nests identical conditions. If you are above the age of 15, you are doubly referred hereby, to verse 6 of the Canon.

Rewrite your case stucture, take two aspirin and call me in the morning.

Main SWITCH check fixed objects.

FOR loop checks variable objects.

If you don't "get" that then don't ever bother with MENSA and such...

jacQues

Share this post


Link to post
Share on other sites

could you do something like

Hmmmm, yes good idea but unfortunately that wouldn't work. The GUI uses TABS, so controlgetfocus()'s result cannot be used (unreliable because the number of buttons per tab is also variable). Besides you are suggesting replacement of a FOR with a SWITCH, but a switch cannot find anything non-indexed AND of variable nature.

There is nothing wrong with the loop, no matter what Squirrely1 says. The problem I have is with a GUICtrlSetState() nullifying the sequence of GUIGetMsg() events in the queue.

Right now I have found a "fix" by creating a button off-screen and setting that as DEFBUTTON each time. This way if/when that button event comes up a focus change takes place (because the Enter key was used). I can post a cutout of the source if anyone wants.

jacQues

Share this post


Link to post
Share on other sites

Right now I have found a "fix" by creating a button off-screen and setting that as DEFBUTTON each time. This way if/when that button event comes up a focus change takes place (because the Enter key was used). I can post a cutout of the source if anyone wants.

jacQues

I had to create a hiden button and setting it to DEFButton for another problem I was having on one of my forms, Not the best fix for me either, but it works.

Sorry for Squirrely1, this is a place to find answers not a place to be put down. I can only guess how many "Dumb Questions" I've asked in forums. But I was impressed with the code you posted, made me look at the Help to figuire out what you were doing....Learned somethings I never knew.

Hazed

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