g0gcd Posted July 12, 2023 Share Posted July 12, 2023 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 More sharing options...
Andreik Posted July 12, 2023 Share Posted July 12, 2023 Maybe it's good to post a script that reproduce the issue. When the words fail... music speaks. Link to comment Share on other sites More sharing options...
g0gcd Posted July 12, 2023 Author Share Posted July 12, 2023 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 More sharing options...
Andreik Posted July 12, 2023 Share Posted July 12, 2023 (edited) 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. expandcollapse popupAutoItSetOption('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 July 12, 2023 by Andreik When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Shark007 Posted July 12, 2023 Share Posted July 12, 2023 (edited) After setting the State of a Control (like a checkbox), you still need to call the function mycheckbox() to actually carry out the state that you just set. Edited July 12, 2023 by Shark007 Link to comment Share on other sites More sharing options...
Zedna Posted July 15, 2023 Share Posted July 15, 2023 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! Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
g0gcd Posted July 15, 2023 Author Share Posted July 15, 2023 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. expandcollapse popupAutoItSetOption('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 More sharing options...
Andreik Posted July 15, 2023 Share Posted July 15, 2023 (edited) Maybe I will have some time to look over but put together all the required UDFs. There are some non-standard UDFs used in your project. Edited July 15, 2023 by Andreik When the words fail... music speaks. Link to comment Share on other sites More sharing options...
g0gcd Posted July 15, 2023 Author Share Posted July 15, 2023 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 More sharing options...
g0gcd Posted July 16, 2023 Author Share Posted July 16, 2023 (edited) 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 July 18, 2023 by g0gcd correction/clarification after finding solution Link to comment Share on other sites More sharing options...
g0gcd Posted July 16, 2023 Author Share Posted July 16, 2023 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 More sharing options...
Solution g0gcd Posted July 16, 2023 Author Solution Share Posted July 16, 2023 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 Zedna 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now