czardas Posted February 1, 2011 Share Posted February 1, 2011 (edited) I was wondering if there is an easy command to clear queued messages sent to GUI controls whilst another process is busy. If I interrupt a long process, I just want the program to return to a ready state. However all the buttons I may have clicked whilst the process was running are in a queue, waiting to execute. Is there a simple function I can use to clear these messages? #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> Local $hGUI = GUICreate("Stop Process", 300, 170) $fInterrupt = 0 $Go = GUICtrlCreateButton("Go", 10, 10, 70, 20) $Stop = GUICtrlCreateButton("Stop", 100, 10, 70, 20) $helloWorld = GUICtrlCreateButton("Hello World", 190, 10, 100, 20) GUISetState() GUIRegisterMsg($WM_COMMAND, "_Stop") While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop If $msg = $Go Then _infiniteProc() If $msg = $helloWorld Then MsgBox(0, "", "Hello World") WEnd Func _infiniteProc() While $fInterrupt = 0 ; infinite process WEnd $fInterrupt = 0 Return $GUI_RUNDEFMSG EndFunc Func _Stop($hWnd, $Msg, $wParam) If BitAND($wParam, 0x0000FFFF) = $Stop Then $fInterrupt = 1 EndFunc Edited February 1, 2011 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 1, 2011 Moderators Share Posted February 1, 2011 czardas,Just run GUIGetMsg in a loop until you get 0 as a return - that has worked for me in the past. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
czardas Posted February 1, 2011 Author Share Posted February 1, 2011 Just run GUIGetMsg in a loop until you get 0 as a return - that has worked for me in the past. expandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> Local $hGUI = GUICreate("Stop Process", 300, 170) $fInterrupt = 0 $Go = GUICtrlCreateButton("Go", 10, 10, 70, 20) $Stop = GUICtrlCreateButton("Stop", 100, 10, 70, 20) $helloWorld = GUICtrlCreateButton("Hello World", 190, 10, 100, 20) GUISetState() GUIRegisterMsg($WM_COMMAND, "_Stop") While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop If $msg = $Go Then _infiniteProc() While GUIGetMsg() <> 0 $msg = GUIGetMsg() WEnd EndIf If $msg = $helloWorld Then MsgBox(0, "", "Hello World") WEnd Func _infiniteProc() While $fInterrupt = 0 ; infinite process WEnd $fInterrupt = 0 Return $GUI_RUNDEFMSG EndFunc Func _Stop($hWnd, $Msg, $wParam) If BitAND($wParam, 0x0000FFFF) = $Stop Then $fInterrupt = 1 EndFunc Hehe, so easy when you know how. Thanks! operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
jvanegmond Posted February 1, 2011 Share Posted February 1, 2011 (edited) Looping until you get 0 is a hack. Here is how it should be handled. Simply disable the buttons so you don't get messages from them when they are clicked. It is both more obvious to the user as it is in the code.expandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> Local $hGUI = GUICreate("Stop Process", 300, 170) $fInterrupt = 0 $Go = GUICtrlCreateButton("Go", 10, 10, 70, 20) $Stop = GUICtrlCreateButton("Stop", 100, 10, 70, 20) GUICtrlSetState(-1, $GUI_DISABLE) $helloWorld = GUICtrlCreateButton("Hello World", 190, 10, 100, 20) GUISetState() GUIRegisterMsg($WM_COMMAND, "_Stop") While 1 $exit = DoEvents() If $exit Then ExitLoop EndIf WEnd Func DoEvents() $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then Return True If $msg = $Go Then GUICtrlSetState($Go, $GUI_DISABLE) GUICtrlSetState($Stop, $GUI_ENABLE) GUICtrlSetState($helloWorld, $GUI_DISABLE) _infiniteProc() GUICtrlSetState($Go, $GUI_ENABLE) GUICtrlSetState($Stop, $GUI_DISABLE) GUICtrlSetState($helloWorld, $GUI_ENABLE) EndIf If $msg = $helloWorld Then MsgBox(0, "", "Hello World") EndIf Return False EndFunc Func _infiniteProc() While $fInterrupt = 0 DoEvents() ; infinite process WEnd $fInterrupt = 0 EndFunc Func _Stop($hWnd, $Msg, $wParam) If BitAND($wParam, 0x0000FFFF) = $Stop Then $fInterrupt = 1 EndFunc Edited February 1, 2011 by Manadar github.com/jvanegmond Link to comment Share on other sites More sharing options...
czardas Posted February 1, 2011 Author Share Posted February 1, 2011 (edited) It had occured to me, but there will be such a varied number of buttons (and GUI's), that it would make life so hard. I'll still consider it as a more complicated alternative. Actually nearly all the buttons will be array elements, so I could loop through them. I don't see what advantage looping through disabling buttons or GUIGetMsg will or won't have. It seems to be easier to just clear the messages. Edited February 1, 2011 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
jvanegmond Posted February 1, 2011 Share Posted February 1, 2011 (edited) Doing things right is far more important than a few extra lines of code. You can use a lot of techniques to reduce the lines of code, if you really have to write hundreds of lines of extra code that are all similar. Wrap the toggling of the buttons to a function, or do something like this: expandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> Local $hGUI = GUICreate("Stop Process", 300, 170) $fInterrupt = 0 $Go = GUICtrlCreateButton("Go", 10, 10, 70, 20) $Stop = GUICtrlCreateButton("Stop", 100, 10, 70, 20) GUICtrlSetState(-1, $GUI_DISABLE) $helloWorld = GUICtrlCreateButton("Hello World", 190, 10, 100, 20) Local $toggleButtons[3] = [$Go, $Stop, $helloWorld] GUISetState() GUIRegisterMsg($WM_COMMAND, "_Stop") While 1 $exit = DoEvents() If $exit Then ExitLoop EndIf WEnd Func DoEvents() $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then Return True If $msg = $Go Then _toggleButtons() _infiniteProc() _toggleButtons() EndIf If $msg = $helloWorld Then MsgBox(0, "", "Hello World") EndIf Return False EndFunc Func _toggleButtons() For $n = 0 to UBound($toggleButtons)-1 $button = $toggleButtons[$n] If BitAnd(GUICtrlGetState($button), $GUI_ENABLE) Then GUICtrlSetState($button, $GUI_DISABLE) Else GUICtrlSetState($button, $GUI_ENABLE) EndIf Next EndFunc Func _infiniteProc() While $fInterrupt = 0 $exit = DoEvents() If $exit Then $fInterrupt = 1 EndIf ; infinite process WEnd $fInterrupt = 0 EndFunc Func _Stop($hWnd, $Msg, $wParam) If BitAND($wParam, 0x0000FFFF) = $Stop Then $fInterrupt = 1 EndFunc A much more elegant solution that is readable, understandable, maintainable, and does not have any hack-value. Oh I love my signature. Edited February 1, 2011 by Manadar github.com/jvanegmond Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 1, 2011 Moderators Share Posted February 1, 2011 Manadar,I know it is a hack, but it does work - at least in MessageLoop mode! Do you happen to know if there is a limit to the size of the message queue which would cause problems if the user went berzerk and clicked on the various controls umpteen times while the process was running? M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
jvanegmond Posted February 1, 2011 Share Posted February 1, 2011 (edited) Manadar, I know it is a hack, but it does work - at least in MessageLoop mode! Do you happen to know if there is a limit to the size of the message queue which would cause problems if the user went berzerk and clicked on the various controls umpteen times while the process was running? M23 Yes, and your hack answered the original question exactly as it was asked. There could be a limit on the size of the message queue, but it is a theoretical limit. Windows will notify the user that the window is unresponsive and then Windows stops additional windows messages being sent to the window. That is another problem that my solution solves. The app remains responsive the whole time to all windows messages, which is almost a requirement that Windows puts on applications. This is the same code as above but I implemented the close button being clicked while the infinite loop is active, which instead of closing the GUI, stops the infinite process using the $fInterrupt flag. expandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> Local $hGUI = GUICreate("Stop Process", 300, 170) $fInterrupt = 0 $Go = GUICtrlCreateButton("Go", 10, 10, 70, 20) $Stop = GUICtrlCreateButton("Stop", 100, 10, 70, 20) GUICtrlSetState(-1, $GUI_DISABLE) $helloWorld = GUICtrlCreateButton("Hello World", 190, 10, 100, 20) Local $toggleButtons[3] = [$Go, $Stop, $helloWorld] GUISetState() GUIRegisterMsg($WM_COMMAND, "_Stop") While 1 $exit = DoEvents() If $exit Then ExitLoop EndIf WEnd Func DoEvents() $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then Return True If $msg = $Go Then _toggleButtons() _infiniteProc() _toggleButtons() EndIf If $msg = $helloWorld Then MsgBox(0, "", "Hello World") EndIf Return False EndFunc Func _toggleButtons() For $n = 0 to UBound($toggleButtons)-1 $button = $toggleButtons[$n] If BitAnd(GUICtrlGetState($button), $GUI_ENABLE) Then GUICtrlSetState($button, $GUI_DISABLE) Else GUICtrlSetState($button, $GUI_ENABLE) EndIf Next EndFunc Func _infiniteProc() While $fInterrupt = 0 $exit = DoEvents() If $exit Then $fInterrupt = 1 EndIf ; infinite process WEnd $fInterrupt = 0 EndFunc Func _Stop($hWnd, $Msg, $wParam) If BitAND($wParam, 0x0000FFFF) = $Stop Then $fInterrupt = 1 EndFunc Edited February 1, 2011 by Manadar github.com/jvanegmond Link to comment Share on other sites More sharing options...
AdmiralAlkex Posted February 1, 2011 Share Posted February 1, 2011 (edited) While I agree that Disabling the buttons (like Manadar showed) is the better way, if you refuse to do that then stick GUIGetMsg in a loop (end when no events) in a adlib that runs every 500ms or so. That way you wont pile shitloads of events on each other. Much better than the Melba idea I think. Edit: added last sentence. Edited February 1, 2011 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...
czardas Posted February 1, 2011 Author Share Posted February 1, 2011 How do I disable the [x] close button in the top right hand corner. It seems as if either Melba's method or both must be used. Or have the button on a different GUI and just disable the whole thing. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
jvanegmond Posted February 1, 2011 Share Posted February 1, 2011 How do I disable the [x] close button in the top right hand corner. It seems as if either Melba's method or both must be used. Or have the button on a different GUI and just disable the whole thing. You can't disable the close button, but why would you want to? You can just ignore it being pressed by not handling the message: As long as you get it. See my code for details. github.com/jvanegmond Link to comment Share on other sites More sharing options...
AdmiralAlkex Posted February 1, 2011 Share Posted February 1, 2011 How do I disable the [x] close button in the top right hand corner. It seems as if either Melba's method or both must be used. Or have the button on a different GUI and just disable the whole thing. Ignore the $GUI_EVENT_CLOSE ? .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...
czardas Posted February 1, 2011 Author Share Posted February 1, 2011 To add to the complication of disabling buttons, I would also have to keep account of the buttons that are already disabled. I would also have to disable the menus. While the correct proceedure is preferable, it sucks. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
jvanegmond Posted February 1, 2011 Share Posted February 1, 2011 (edited) To add to the complication of disabling buttons, I would also have to keep account of the buttons that are already disabled. I would also have to disable the menus. While the correct proceedure is preferable, it sucks.Nick, did you even read my code? I have already showed you how to solve that problem. It works for anything that accepts $GUI_ENABLE and $GUI_DISABLE: This includes menus. Edited February 1, 2011 by Manadar github.com/jvanegmond Link to comment Share on other sites More sharing options...
czardas Posted February 1, 2011 Author Share Posted February 1, 2011 Nick, did you even read my code? I have already showed you how to solve that problem. It works for anything that accepts $GUI_ENABLE and $GUI_DISABLE: This includes menus.Sorry I was interrupted, I'll take a good look at it all now. I can see the problem with stacking too many messages. I'll give all options good consideration. Thanks. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
czardas Posted February 1, 2011 Author Share Posted February 1, 2011 (edited) Okay I looked at the example, and I agree that I may have to use Manadar's option. Although I do still have some issues with the method. While the buttons are in a mixed state of available or not before running the process, the user may wish to review the settings by examining the status of the buttons. If at some point the user realizes that the wrong configuration has been set, then they may wish to stop the process. If I disable all the buttons, the user will have less information about the process being run. This effect was actually intended by design.I know there are ways around this, but I haven't even began to write the process and it's now getting messy already. Maybe I could register all buttons to give a message saying "Please End process before you click me again!"EditI think I know what I'll do. I'll forego the advantage of visual configuration and just disable the whole GUI. I can embed the STOP button on a second GUI to enable everything again. If it works. Edited February 1, 2011 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
jvanegmond Posted February 1, 2011 Share Posted February 1, 2011 Nick, I don't think we speak the same language. Can we continue to talk in AutoIt? github.com/jvanegmond Link to comment Share on other sites More sharing options...
czardas Posted February 1, 2011 Author Share Posted February 1, 2011 (edited) This seems to work in a funny kind of way. expandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> Local $hGUI = GUICreate("Stop Process", 300, 170) $fInterrupt = 0 $Go = GUICtrlCreateButton("Go", 10, 10, 70, 20) $helloWorld = GUICtrlCreateButton("Hello World", 190, 10, 100, 20) Local $hcGUI = GUICreate("Stop", 70, 20, 100, 10, $WS_POPUP, $WS_EX_MDICHILD, $hGUI) $Stop = GUICtrlCreateButton("Stop", 0, 0, 70, 20) GUISetState() GUISwitch($hGUI) GUISetState() GUIRegisterMsg($WM_COMMAND, "_Stop") While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop If $msg = $Go Then _infiniteProc() EndIf If $msg = $helloWorld Then MsgBox(0, "", "Hello World") WEnd Func _infiniteProc() GUISetState(@SW_DISABLE, $hGUI) While $fInterrupt = 0 ; infinite process WEnd $fInterrupt = 0 GUISetState(@SW_ENABLE, $hGUI) Return $GUI_RUNDEFMSG EndFunc Func _Stop($hWnd, $Msg, $wParam) If BitAND($wParam, 0x0000FFFF) = $Stop Then $fInterrupt = 1 EndFunc Edited February 1, 2011 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
jvanegmond Posted February 1, 2011 Share Posted February 1, 2011 What is wrong with the example I gave you? It seems to work and do everything what you asked for. github.com/jvanegmond Link to comment Share on other sites More sharing options...
czardas Posted February 1, 2011 Author Share Posted February 1, 2011 (edited) What is wrong with the example I gave you? It seems to work and do everything what you asked for. There's nothing wrong with it, apart from I can't tell which buttons have been disabled. I would probably use your method under most circumstances. expandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> Local $hGUI = GUICreate("Stop Process", 300, 170) ;$fInterrupt = 0 $Go = GUICtrlCreateButton("Go", 10, 10, 70, 20) $helloWorld = GUICtrlCreateButton("Hello World", 190, 10, 100, 20) $disabled = GUICtrlCreateButton("Disabled", 10, 50, 100, 20) GUICtrlSetState(-1, $GUI_DISABLE) Local $hcGUI = GUICreate("Stop", 70, 20, 100, 10, $WS_POPUP, $WS_EX_MDICHILD, $hGUI) $Stop = GUICtrlCreateButton("Stop", 0, 0, 70, 20) GUISetState() GUISwitch($hGUI) GUISetState() GUIRegisterMsg($WM_COMMAND, "_Stop") While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop $fInterrupt = 0 ; Always set this flag before running the process! If $msg = $Go Then _infiniteProc() EndIf If $msg = $helloWorld Then MsgBox(0, "", "Hello World") WEnd Func _infiniteProc() GUISetState(@SW_DISABLE, $hGUI) GUICtrlSetState($Stop, $GUI_FOCUS) ; This is optional, but helps to add clarity. While $fInterrupt = 0 ; infinite process WEnd $fInterrupt = 0 GUISetState(@SW_ENABLE, $hGUI) Return $GUI_RUNDEFMSG EndFunc Func _Stop($hWnd, $Msg, $wParam) If BitAND($wParam, 0x0000FFFF) = $Stop Then $fInterrupt = 1 EndFunc Edited February 1, 2011 by czardas operator64 ArrayWorkshop 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