qwert Posted April 24, 2008 Share Posted April 24, 2008 I have a script that uses both a While 1 ... WEnd loop and an On_WM_COMMAND registered function. I've discovered that the registered WM_COMMAND is cycling multiple times for each click on the GUI. I've tried various combinations change that, but my result is always the same. I've prepared this simplified example to demonstrate the behavior. (The simple 300 x 200 graphic is shown below.) expandcollapse popup#include <GUIConstants.au3> $GUI = GUICreate("Main", 300, 200, 300, 300) GUICtrlSetState(-1,$GUI_DISABLE) $image = GUICtrlCreatePic(@ScriptDir&"\Image.bmp",0,0,300,200) GUICtrlSetState(-1,$GUI_DISABLE) $OnGraphic = GUICtrlCreateGraphic(30, 20, 70, 70) GUICtrlSetTip(-1, " On " ) ; show tooltip as a test $OffGraphic = GUICtrlCreateGraphic(140, 20, 70, 70) GUICtrlSetTip(-1, " Off " ) ; show tooltip as a test $regularButton1 = GUICtrlCreateButton("Yes", 40, 160, 30, 20) $regularButton2 = GUICtrlCreateButton("No", 80, 160, 30, 20) $exit = GUICtrlCreateButton("X", 280, 10, 16, 16) $display = GUICtrlCreateInput("", 70, 100, 60, 20) $state = GUICtrlCreateInput("", 120, 160, 60, 20) GUISetState() ;=========================================== GUIRegisterMsg($WM_COMMAND, "On_WM_COMMAND") ;=========================================== While 1 $gMsg = GUIGetMsg() ; read button click Switch $gMsg Case $regularButton1 GUICtrlSetData($state, "Yes") Case $regularButton2 GUICtrlSetData($state, "No") Case $exit Exit EndSwitch WEnd Func On_WM_COMMAND($hWnd, $Msg, $wParam, $lParam) Local $iNotifyCode = BitShift($wParam, 16), $iID = BitAnd($wParam, 0x0000FFFF) MsgBox(32, "Entry", "On_WM_Command", 1) ;<<<<<<<<<<<< need to investigat multiple cycles If $iID = $OnGraphic Then GUICtrlSetData( $display, "On" ) EndIf If $iID = $OffGraphic Then GUICtrlSetData( $display, "Off" ) EndIf EndFuncIt's probably obvious, but the While 1 Loop handles the defined graphical buttons, and the registered function handles regular buttons. Have I left something out? Or is this behavior normal? If so, why? Thanks for any assistance. Link to comment Share on other sites More sharing options...
AdmiralAlkex Posted April 24, 2008 Share Posted April 24, 2008 (edited) Why do you use ON_WM_COMMAND to begin with?? Wouldn't this be better= #include <GUIConstants.au3> $GUI = GUICreate("Main", 300, 200, 300, 300) GUICtrlSetState(-1,$GUI_DISABLE) $image = GUICtrlCreatePic(@ScriptDir&"\Image.bmp",0,0,300,200) GUICtrlSetState(-1,$GUI_DISABLE) $OnGraphic = GUICtrlCreateGraphic(30, 20, 70, 70) GUICtrlSetTip(-1, " On " ) ; show tooltip as a test $OffGraphic = GUICtrlCreateGraphic(140, 20, 70, 70) GUICtrlSetTip(-1, " Off " ) ; show tooltip as a test $regularButton1 = GUICtrlCreateButton("Yes", 40, 160, 30, 20) $regularButton2 = GUICtrlCreateButton("No", 80, 160, 30, 20) $exit = GUICtrlCreateButton("X", 280, 10, 16, 16) $display = GUICtrlCreateInput("", 70, 100, 60, 20) $state = GUICtrlCreateInput("", 120, 160, 60, 20) GUISetState() While 1 $gMsg = GUIGetMsg() ; read button click Switch $gMsg Case $regularButton1 GUICtrlSetData($state, "Yes") Case $regularButton2 GUICtrlSetData($state, "No") Case $OnGraphic GUICtrlSetData( $display, "On" ) Case $OffGraphic GUICtrlSetData( $display, "Off" ) Case $exit Exit EndSwitch WEnd Edit:Spelling Edited April 24, 2008 by AdmiralAlkex .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface Link to comment Share on other sites More sharing options...
qwert Posted April 24, 2008 Author Share Posted April 24, 2008 Why do you use ON_WM_COMMAND to begin with?? Wouldn't this be better=Yes, you would think that simplification would work. Unfortunately, the response time to rapid clicking on the graphic buttons is unacceptable. Here's a much clearer example, which loses clicks: expandcollapse popup#include <GUIConstants.au3> Opt("WinWaitDelay", 10) ;10 milliseconds (DOESN'T HELP) $GUI = GUICreate("Main", 300, 200, 300, 300) GUICtrlSetState(-1,$GUI_DISABLE) $image = GUICtrlCreatePic(@ScriptDir&"\Image.bmp",0,0,300,200) GUICtrlSetState(-1,$GUI_DISABLE) $OnGraphic = GUICtrlCreateGraphic(30, 20, 70, 70) GUICtrlSetTip(-1, " On " ) ; show tooltip as a test $OffGraphic = GUICtrlCreateGraphic(140, 20, 70, 70) GUICtrlSetTip(-1, " Off " ) ; show tooltip as a test $regularButton1 = GUICtrlCreateButton("Yes", 40, 160, 30, 20) $regularButton2 = GUICtrlCreateButton("No", 80, 160, 30, 20) $exit = GUICtrlCreateButton("X", 280, 10, 16, 16) $reset = GUICtrlCreateButton("reset", 240, 100, 60, 20) $display = GUICtrlCreateInput("", 40, 100, 200, 20) $state = GUICtrlCreateInput("", 120, 160, 100, 20) GUISetState() While 1 $gMsg = GUIGetMsg() ; read button click Switch $gMsg Case $regularButton1 GUICtrlSetData($state, "Yes") Case $regularButton2 GUICtrlSetData($state, "No") Case $OnGraphic GUICtrlSetData( $display, GUICtrlRead($display) & "On" ) Case $OffGraphic GUICtrlSetData( $display, GUICtrlRead($display) & "Off" ) Case $reset GUICtrlSetData( $display, "" ) Case $exit Exit EndSwitch WEnd Think in terms of a game in which you click five times rapidly on a symbol. The script only receives two -- maybe three -- of the clicks. I posted a question a few weeks ago here, and the $WM_Command method emerged as the apparent solution. The only drawback I'm aware of is the extra cycling I described above. Thanks for the response. I certainly look forward to any other suggestions of methods. Link to comment Share on other sites More sharing options...
Siao Posted April 24, 2008 Share Posted April 24, 2008 Every control sends various notifications to the parent window through WM_NOTIFY and WM_COMMAND messages. That's why there are means to get notification code and control id/handle, so you could filter out the stuff you don't need. Why is that a drawback, exactly? "be smart, drink your wine" Link to comment Share on other sites More sharing options...
qwert Posted April 24, 2008 Author Share Posted April 24, 2008 Why is that a drawback, exactly?Thanks for your response.The drawback is that in my full script, I also have ControlSends to another window. Between those and the mouse clicks, the $WM_Command processing function gets flooded with these multiple notifications -- sort of like an echo effect: one user action invokes several notifications. I developed the simplified example in my first post to try to isolate and understand what was going on.As I said in my original post, I'm unsure why I get three cycles in response to one click in my example script. Is it mouse click down, mouse click up? ... and then what? And by "filtering", do you mean only responding to notifications that are recognized? Or is there a way to suppress unneeded notifications? Link to comment Share on other sites More sharing options...
Siao Posted April 24, 2008 Share Posted April 24, 2008 (edited) If you want to see what flooded really means, check how many WM_NOTIFY messages are generated when you move mouse over a virtual listview which has some columns, and the sad part is that all of them actually have to be handled for it to work. 3 messages aren't worth even a single drop in my book, especially when/if you're really interested only in one of them If you mean 3 WM_COMMAND messages in your example script when you click Yes/No button, then they are - a button sends BN_CLICKED notification when you click it. Then, input box sends EN_UPDATE notification that its display is about to change (because of GUICtrlSetData), and after that it sends EN_CHANGE notification to report that its display has changed. It's obvious that you have no previous experience with Win32 GUI programming (and maybe programming in general), so it's hard for you to wrap your mind around this whole concept of working with windows messages (and maybe even about constructing a logic flow in your script with the help of conditional statements If...Then, Switch...Case, etc.). Which is why I don't know what to say, because to me all this seems pretty clear. Generally speaking, you have a function that gets called on multiple events. If you want something to be executed only on specific event for specific control, you simply make it so, you have all the tools. Who cares how many times the function got called in total. At the start of the function, you know control ID of the control which sent the notification, and the notification code itself. If you have multiple GUI windows, you can also add GUI handle ($hWnd) to your logic. Even in your example script, GUICtrlSetData($display, "On") or GUICtrlSetData($display, "Off") only happens when corresponding graphic control is clicked. To make sure of that you should also be checking the $iNotifyCode, because as I said, a control can send several various notifications (doesn't happen in this particular case, but that doesn't mean it can't happen in other cases), and unless you absolutely want something to happen for each one of them, you have to check for that. If you have multiple GUIs, lets say their handles are stored in global variables $hGui1 and $hGui2, and you only want to tinker with the controls in 1st one, before everything else simply do a If $hWnd <> $hGui1 Then Return That's about it. I can't believe such things really need so many words... Edited April 24, 2008 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
qwert Posted April 24, 2008 Author Share Posted April 24, 2008 It's obvious that you have no previous experience with Win32 GUI programming ...Ouch! I was hoping that wasn't so apparent. Truth is, I never looked at a Win32GUI until about eight weeks ago. In these weeks, however, I've been amazed at what GUIs constructed with AutoIt can be made to do. From your perspective, I guess it's painful to watch neophytes stumble through many of these things. It's a complicated runtime environment on the PC. One only has to read a few passages of MSDN2 documentation to be amazed that it all can ever work (mostly). Only through some coaching and redirection do folks like me ever stand a chance at moving upward. I do appreciate you taking the time to explain what you have. Like stopping to ask directions in a strange city, a little help can go a long way.Regarding the flood of notifications, I've done more monitoring of my main application and have found -- unbelievable to me -- that there are over 100 notifications per second. So something else is triggering them. I'm in the process of disabling sections of the script to find the culprit(s). Overall, the script is structured just the way my example is, so until I find the exact cause, I remain baffled by the situation.Thanks again for your help. Link to comment Share on other sites More sharing options...
qwert Posted April 24, 2008 Author Share Posted April 24, 2008 Well, I've gotten to the bottom of the flood of notifications. It is due to a keystroke detection method I put in last week:I just read the input control contents on each cycle of my While 1 ... WEnd loop and compare to the previous contentsThat method was the apparent "best method" to be able to detect individual keystrokes. (What I had hoped for was the ability to receive WM_CHAR directly from the OS, but I understand that direct mode is not available in AutoIt.) My error was clearing the input control and placing focus on it -- even if nothing had been entered. Having those two steps inside an If statement put things back to "normal".So, unless another method is suggested, I'll tune my loop delay and live with all the extraneous notifications. Link to comment Share on other sites More sharing options...
Siao Posted April 25, 2008 Share Posted April 25, 2008 I guess it's painful to watch neophytes stumble through many of these things.Nah, pain is those critters who keep posting trivial questions without even bothering to look it up in the helpfile (or failing real bad at doing it). If it's not in the helpfile and hasn't been answered in the forums a hundred times over, I don't mind.Thing is that I kind of go by the assumption that if I know something, most coders with minimal experience could figure it out without much problems too. Not even mentioning the solutions I pillage from Google, and that resource is available for all. Regarding WM_CHAR, and to suggest anything we'd have to see more of your script, or know why do you need this key detection for... depending on that, some ways may be better than others. "be smart, drink your wine" 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