Jump to content

Proper use of GUIGetMsg()?


k3v
 Share

Recommended Posts

Hello Everyone,

Original question: (http://www.autoitscript.com/forum/index.php?showtopic=72838)

Here's a quick setup:

My window contains several inputboxes and some buttons. The important ones are:

$input1

$button

When the user tabs away from $input1, the input() function should be executed. (this has been working)

When the user clicks $button, the button() function should be executed.

This does not work, because clicking $button causes $input1 to lose focus, and the lostfocus event executes the input() function.

On reflection, it seems this is simply a fact of life, and the sequence of events will be the same whether using Opt('GUIOnEventMode', 0) and doing GUIGetMsg(), or Opt('GUIOnEventMode', 1) and setting the OnEvent state for my controls.

To get around it I read the message a second time in my select block to see if the button was pressed. This seemed to work intermittantly, so I believe it to be partially a timing issue. (See example code)

#include <Process.au3>
#include <GuiConstants.au3>
Opt('GUIOnEventMode', 0)
GUICreate("Event Test",320,130,400,300)
$input1 = GUICtrlCreateInput("",15,15,145,25)
$input2 = GUICtrlCreateInput("",165,15,145,25)
$input3 = GUICtrlCreateInput("",15,45,145,25)
$input4 = GUICtrlCreateInput("",165,45,145,25)
GUICtrlSetState($input2,$GUI_DISABLE)
GUICtrlSetState($input3,$GUI_DISABLE)
GUICtrlSetState($input4,$GUI_DISABLE)
$button = GUICtrlCreateButton("Run",15,75,70,30)
$clear = GUICtrlCreateButton("Clear",90,75,70,30)
$exit = GUICtrlCreateButton("Exit",240,75,70,30) 
ControlFocus("Event Test","",$input1)
GUISetState(@SW_SHOW)

while 1
    dim $msg,$msg2
    $msg = GUIGetMsg()
    select 
        case $msg = $button
            button()
        case $msg = $exit
            close()
        case $msg = $clear
            clear()
        case $msg = $input1
            sleep(300)
            $msg2 = GUIGetMsg()
            if not $msg2 = $GUI_EVENT_PRIMARYDOWN then input()
        case $msg = $GUI_EVENT_CLOSE
            close()
    EndSelect
WEnd

Func input()
    GUICtrlSetState($input3,$GUI_ENABLE)
    ControlFocus("Event Test","",$input3)
EndFunc

Func button()
    MsgBox(0,"","Button clicked")
EndFunc

Func clear()
    GUICtrlSetState($input3,$GUI_DISABLE)
    GUICtrlSetData($input1,"")
    GUICtrlSetData($input2,"")
    ControlFocus("Event Test","",$input1)
EndFunc

Func close()
    Exit
EndFunc

Inserting a sleep() has been the only way to get this to behave as "desired", (sort-of), but I really hate resorting to this... I even had to bump up the sleep from 250 to 300 ms to maintain (somewhat) consistent behavior, (which reinforces my belief of the timing issue)... am I way off base here?

Can anyone suggest a more elegant approach, or better educate me in the proper use of GUIGetMsg()?

Thanks tons,

k3v

Link to comment
Share on other sites

Trying to understand...

Maybe...

#include <Process.au3>
#include <GuiConstants.au3>

Opt('GUIOnEventMode', 0)

dim $msg,$msg2

GUICreate("Event Test",320,130,400,300)
$input1 = GUICtrlCreateInput("",15,15,145,25)
$input2 = GUICtrlCreateInput("",165,15,145,25)
$input3 = GUICtrlCreateInput("",15,45,145,25)
$input4 = GUICtrlCreateInput("",165,45,145,25)
GUICtrlSetState($input2,$GUI_DISABLE)
GUICtrlSetState($input3,$GUI_DISABLE)
GUICtrlSetState($input4,$GUI_DISABLE)
$button = GUICtrlCreateButton("Run",15,75,70,30)
$clear = GUICtrlCreateButton("Clear",90,75,70,30)
$exit = GUICtrlCreateButton("Exit",240,75,70,30)
ControlFocus("Event Test","",$input1)
GUISetState(@SW_SHOW)

while 1
    
    $msg = GUIGetMsg()
    select
        case $msg = $button
            button();: *************** or maybe the input() goes first???????
            input()
        case $msg = $exit
            close()
        case $msg = $clear
            clear()
        case $msg = $input1
            sleep(300)
            $msg2 = GUIGetMsg()
            if $msg2 <> $GUI_EVENT_PRIMARYDOWN then input()
        case $msg = $GUI_EVENT_CLOSE
            close()
    EndSelect
WEnd

Func input()
    GUICtrlSetState($input3,$GUI_ENABLE)
    GUICtrlSetState($input3,$GUI_FOCUS)
 ;   ControlFocus("Event Test","",$input3)
EndFunc

Func button()
    MsgBox(0,"","Button clicked")
EndFunc

Func clear()
    GUICtrlSetState($input3,$GUI_DISABLE)
    GUICtrlSetData($input1,"")
    GUICtrlSetData($input2,"")
    ControlFocus("Event Test","",$input1)
EndFunc

Func close()
    Exit
EndFunc

8)

NEWHeader1.png

Link to comment
Share on other sites

Thanks for the reply...

I only need $input3 to be affected if the user tabs away from $input1... but for the button press, (at least in this example), it's enough to just display a message.

Each action requires a different and unrelated reaction..

1) user tabs out of $input1 --> $input3 is enabled and gets focus.

2) button is pressed --> other stuff happens... (for the example, just a message box)... it's ok that focus remains on the button after its pressed.

Thing is, when the button is pressed, (instead of tabbing out of $input1), the first thing that happens is that $input1 loses focus... so the program thinks it should execute the "tabbed out of $input1" function... hence, the second GUIGetMsg() function to test whether button-press happened immediately following the "lostfocus". If the user tabbed out, the answer is no, and the input() function executes. If the button was pressed, and $msg2 = $button, the button() function executes.

But if all of this happens too quickly, then $msg2 is set before the button-press message is queued, and winds up being set to $input1 even if the button was pressed... hence, the sleep()... But I find this to be a clunky fix, and even at 300 ms, it still allows the possibility of human interaction that would break the process.

Anyway, that's where I'm stuck. I still believe that GUIGetMsg() could be the way to resolve this, but I'm pretty sure I'm not implementing it as it was intended. Or if there is another way to attack this, I'm all ears :)

Link to comment
Share on other sites

$GUI_EVENT_PRIMARYDOWN relates to the primary mouse button so I am unsure how you have considered Not $GUI_EVENT_PRIMARYDOWN as a reliable trigger at any point. It will only work as it may trigger for anything but the primary mouse button.

Give IsPressed() a try and see if it behaves in a manner more suitable for your needs.

#include <misc.au3>
#include <Process.au3>
#include <GuiConstants.au3>
Opt('GUIOnEventMode', 0)
$handle_Gui = GUICreate("Event Test", 320, 130, 400, 300)
$input1 = GUICtrlCreateInput("", 15, 15, 145, 25)
$input2 = GUICtrlCreateInput("", 165, 15, 145, 25)
$input3 = GUICtrlCreateInput("", 15, 45, 145, 25)
$input4 = GUICtrlCreateInput("", 165, 45, 145, 25)
GUICtrlSetState($input2, $GUI_DISABLE)
GUICtrlSetState($input3, $GUI_DISABLE)
GUICtrlSetState($input4, $GUI_DISABLE)
$button = GUICtrlCreateButton("Run", 15, 75, 70, 30)
$clear = GUICtrlCreateButton("Clear", 90, 75, 70, 30)
$exit = GUICtrlCreateButton("Exit", 240, 75, 70, 30)
GUICtrlSetState($input1, $GUI_FOCUS)
GUISetState(@SW_SHOW)

While 1
    Dim $msg
    $msg = GUIGetMsg()
    Select
        Case $msg = $button
            button()
        Case $msg = $exit
            close()
        Case $msg = $clear
            clear()
        Case $msg = $input1 And _IsPressed('09'); tab key as well
                input()
        Case $msg = $GUI_EVENT_CLOSE
            close()
    EndSelect
WEnd

Func input()
    GUICtrlSetState($input3, $GUI_ENABLE)
    GUICtrlSetState($input3, $GUI_FOCUS)
EndFunc

Func button()
    MsgBox(0, "", "Button clicked", 0, $handle_Gui)
EndFunc

Func clear()
    GUICtrlSetState($input3, $GUI_DISABLE)
    GUICtrlSetData($input1, "")
    GUICtrlSetData($input2, "")
    GUICtrlSetState($input1, $GUI_FOCUS)
EndFunc

Func close()
    Exit
EndFunc

:)

Link to comment
Share on other sites

Hi MHz, at some point I did try using @GUI_EVENT_PRIMARYDOWN, but (probably due to misuse on my part), it tended to be as inconsistent as other methods I tried.

On the other hand, your suggestion to try _IsPressed seems very promising. I will give it a try and post my results.

Thanks MHz!!

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...