Jump to content

Does GUICtrlSetState() force a key click?


g0gcd
 Share

Go to solution Solved by g0gcd,

Recommended Posts

Does GUICtrlSetState() force a key click?

I'm using a GUI in event mode and all is working as expected, except that controls are creating messages (handled in _WM_COMMAND ) when I use GUICtrlSetState() to enable them. This is being interpreted as an unwanted/unexpected key press.

Or am I just chasing a sequence error in my code?

Thanks

John

Link to comment
Share on other sites

Will do, thanks.

It'll take a couple of days to strip out the complexity but that'll have the benefit of me carefully revisiting what I'm trying to achieve anyway.

I was hoping for a simple "no, we're not expecting that behaviour" to encourage me to continue. Making a simulation may just find the problem anyway, hopefully!

Thanks

John

Link to comment
Share on other sites

There is no simple answer when you don't specify about what control we talk about and what exactly do you handle in WM_COMMAND. I have an example here with a GUI that contain a button and using event mode. I also registered WM_COMMAND to see if the procedure it's called where I use several GUICtrlSetState() calls but nothing it's called, so probably GUICtrlSetState() it's fine and you have a different issue in your code.

AutoItSetOption('GUIOnEventMode', 1)

Global $hMain, $cButton

$hMain = GUICreate('Test', 400, 400)
$cButton = GUICtrlCreateButton("Click me", 100, 100, 100, 30)
GUICtrlSetOnEvent($cButton, 'ButtonProcedure')
GUISetOnEvent(-3, 'Quit') ; GUI_EVENT_CLOSE
GUISetState(@SW_SHOW, $hMain)

GUIRegisterMsg(0x0111, 'WM_COMMAND')

GUICtrlSetState($cButton, 64) ; GUI_ENABLE
Sleep(5000)
GUICtrlSetState($cButton, 128) ; GUI_DISABLE
Sleep(5000)
GUICtrlSetState($cButton, 64) ; GUI_ENABLE

While True
    Sleep(10)
WEnd

Func Quit()
    Exit
EndFunc

Func ButtonProcedure()
    MsgBox(0,'', 'Yayyy!')
EndFunc

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    Local $nCode = BitShift($wParam, 16)
    Local $iID = BitAND($wParam, 0xFFFF)
    Local $hCtrl = $lParam
    If $iID = $cButton And $nCode = 0 Then ConsoleWrite('Button clicked' & @CRLF)
    Return 'GUI_RUNDEFMSG'
EndFunc

 

Edited by Andreik

When the words fail... music speaks.

Link to comment
Share on other sites

I have similar misteriously invoked random events in my AutoIt application (after pressing Enter in my Edit control, note: pressing TAB is OK).

It's NOT in Event mode.

It's VERY big (my biggest application) so it's not simple to use eliminating method to find source of problem.

But I intercept WM_COMMAND too and I set state of controls too, so anyway thanks for the tip to possible source of problem!

Link to comment
Share on other sites

Hi Andreik,

Thanks for the code snippet. It's very similar to that which I used originally - only the BitShift (x,16) is unclear to me. That's because i haven't read up the detail behind the WM_Messaging yet.

To explain further, I'm writing a controller for a radio analyser. Having sent all the commands to the analyser for initialisation, I am trying, within that loop, to also pause the test sequence so that I can confirm that the attached radio is also following the analyser settings. For example, the first test is on 435.000MHz, I light up a button to request the operator to confirm that the radio is actually tuned to that frequency. (along with mode, attenuator, antenna port and multiple things). Eventually, I will cater for suitably equipped radios by communicating those instructions on their USB/RS232 interfaces, and auto confirming the request for the operator to check the settings manually.

So, the loop is currently incredibly complex (and probably wrong in it's logic). What I'm seeing is a group of three controls, all labels representing the antenna selection. The first shows a title "Antenna Port", the second, the default (from an .ini file for the radio type), e.g. "VHF" and the third should be red background and carrying a white ?. It's this control that I capture a click for and use that to change the label to a green background and set an 'OK to continue' flag. However, the loop I use (and your example) both force the label to green. I'm trying to find out the exact logic route that's causing it. 

I've attached the program in it's current form but, I've also modified your suggestion to more simply illustrate to effect. In this example, the button sequence works fine but 5 seconds later, the 'click me' is re-enabled. I'm not expecting it to.

 

AutoItSetOption('GUIOnEventMode', 1)

Global $hMain, $cButton

$hMain = GUICreate('Test', 400, 400)
$cButton = GUICtrlCreateButton("Click me", 100, 100, 100, 30)

$cAnotherButton = GUICtrlCreateButton("Don't Click me yet", 100, 150, 100, 30); simulating 'confirm the equipment is connected correctly before proceeding with test'
GUICtrlSetState($cAnotherButton, 128) ; GUI_DISABLE

GUICtrlSetOnEvent($cButton, 'ButtonProcedure')
GUISetOnEvent(-3, 'Quit') ; GUI_EVENT_CLOSE
GUISetState(@SW_SHOW, $hMain)

GUIRegisterMsg(0x0111, 'WM_COMMAND')

GUICtrlSetState($cButton, 64) ; GUI_ENABLE
Sleep(5000)
GUICtrlSetState($cButton, 128) ; GUI_DISABLE
Sleep(5000)
GUICtrlSetState($cButton, 64) ; GUI_ENABLE

While True
    Sleep(10)
WEnd

Func Quit()
    Exit
EndFunc

Func ButtonProcedure()
    MsgBox(0,'', 'Yayyy!')
EndFunc

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    Local $nCode = BitShift($wParam, 16)
    Local $iID = BitAND($wParam, 0xFFFF)
    Local $hCtrl = $lParam
    If $iID = $cButton And $nCode = 0 Then                      ; modified this bit to add in the trap for readying to attached equipment
        ConsoleWrite('Button clicked' & @CRLF)
        GUICtrlSetState($cButton, 128) ; GUI_DISABLE
        GUICtrlSetState($cAnotherButton, 64) ; GUI_ENABLE
        GUICtrlSetData($cAnotherButton, "Are you ready")        ; to here
    Endif

    Return 'GUI_RUNDEFMSG'
EndFunc

 

I'm not expecting anyone to debug this for me but hopefully a comment here or there will unlock what I'm doing wrong.

 

Warning, the attached example doesn't close properly.. I'm not done with that yet. 

But for illustration, confirming the inserted attenuator (which must be done first) is working correctly, but once tests are triggered, the frequency and mode are working correctly but antenna selection is not.

Any thoughts appreciated

Regards

John

 

_Anritsu.au3 _Anritsu.ini G0GCD_Library.au3

Link to comment
Share on other sites

Oops, I forgot about the RS232 comms modules. (And these were difficult to get working, but now work well)

The Analyser is emulated  in the script (by setting the following in Anritsu.ini ..
     [Config]
     NO_ANALYSER=True
), so the script doesn't need this functionality unless I'm actually testing with the real analyser but, of course, the script needs the UDFs to describe what's being requested!

Thanks

John

 

Zedna - watch this space. Once I've figured out what's going on, I may be able to help you... it sounds very much as if we've got very similar projects (if the purpose is different)

I'm convinced that I'm trying too hard and, as a result, I've done something that logically invalid. My debugging has resulted in a number of ways of doing the same things and lot's of scrappy little bits to try to get an indication of what's happening. There's a lot of tidying up to do when it works!

I've 6 of my radios backed up ready for testing and a number of friends that I've suddenly gained who also want a report of their 'rig'.  😊

AnritsuCustomUDFs.zip

Link to comment
Share on other sites

I've tried and I can't break the code snip that Andreik showed me. Therefore, it must be my logic.

I'm going to build my functionality on this snip until I get the problem again - and I will have the solution. But for now, my original question has been answered - No, there isn't a trigger when a control state is toggled.    Yes there is a trigger on most if not all events. To get a 'simple' key click trigger, not responding to 'accelerator' conditions, the high 16 bits of $wParam must be zero. This can be checked explicitly (as per Andreik example) or comparing $wParam with the control handle (which has the high 16bits as zero).

My problem was due to having half of each approach....

Thanks all for your help.

Zedna - I'll be back !

 

Regards

John

Edited by g0gcd
correction/clarification after finding solution
Link to comment
Share on other sites

Thank you so much Andreik!

The key seems to be the BitShift($wParam,16) statement, and then excluding WM_COMMAND() calls where that value is non-zero.

Inserting as follows gives me the behaviour that I expected.

Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $nCode = BitShift($wParam, 16)        ;; Inserted from Andreik
    If $nCode = 0 Then                          ;; Inserted from Andreik
        Switch BitAND($wParam, 0x0000FFFF)
            Case $hKill
                ;etc...
        Endswitch
    Endif                                       ;; Inserted from Andreik
EndFunc

That filter wasn't in the snippet that I originally lifted (https://www.autoitscript.com/forum/topic/200355-pause-resume-gui-button-help/), so a lesson learned there. I must try to understand what I'm lifting before putting it into use!

Regards

John

Link to comment
Share on other sites

  • Solution

In fact, unless I'm missing something obvious (which is perfectly possible), isn't it the case that Zedna and I have been misled by bit manipulation?

As the (now working) code firstly ensures that the upper 16 bits are zero, and then extracts the lower 16 bits to match with the control handle, I think that we only need to:

Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Switch $wParam
        Case $hKill
            ;etc...
    Endswitch
EndFunc

. and therefore, it was the insertion of the BitAND that's caused the trouble....

From https://learn.microsoft.com/en-us/windows/win32/menurc/wm-command#parameters, I now understand that the upper 16bits of $wParam (for $Msg 0x111 = WM_COMMAND) indicate accelerator actions related to the control. These are possibly what caused my observation of spurious key presses. I've not yet been able to confidently associate an accelerator to a DISABLE/ENABLE or SHOW/HIDE command but I'll keep plugging on.

But for now, it's onwards with tidying up that code and finishing the project, so that I can get on with the real job of testing radio sets.

Thanks again for your help.

Regards

John

 

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