Queso Posted May 1, 2015 Share Posted May 1, 2015 (edited) I'm trying to write a GUI that interfaces with a piece of equipment through sending and receiving serial commands. I would like to have a combo box that lists the various operating modes of the equipment. When the user selects a mode the code needs to send out a serial command. (The example code just writes a message to the text box) However after some time interval the equipment may switch modes on its own. When this happens I would like to update the combo box. Therefore, when GUIGetMsg() doesn't return an event the program needs to request information from the equipment and update the combo box. (In the example I have to program always setting the combo box value back to MODE 1 and displaying the elapsed time in the text box) The problem I’m having is that when the program updates the combo box by calling ControlCommand(), it generates and event which triggers the Case $idMsg = $idComboBox_MODE to execute on the next loop. This in turn sends another command out to the equipment. I would like to avoid this and only send out a command if the combo box was changed by the user. Is there a way to distinguish between a user selection of the combo box and an update by the program? Or is there a way to suppress the next event when the program updates the combo box? expandcollapse popup#include <GuiConstantsEx.au3> #include <ComboConstants.au3> #include <EditConstants.au3> _Main() Func _Main() Local $GUI_Title = "Temp" Local $hGUI = GUICreate($GUI_Title, 400, 200,-1,-1) Local $idComboBox_MODE = GUICtrlCreateCombo("MODE 1", 10, 50, 100, 21,$CBS_DROPDOWNLIST) GUICtrlSetData($idComboBox_MODE, "MODE 2|MODE 3|MODE 4","MODE 1") Local $idInput_STATUS = GUICtrlCreateInput(" ", 120, 50, 200, 21,$ES_READONLY) Local $ts = TimerInit() Local $td = TimerDiff($ts) GUISetState() While 1 $idMsg = GUIGetMsg() Select Case $idMsg = $GUI_EVENT_CLOSE ExitLoop Case $idMsg = $idComboBox_MODE $iMenustate = GUICtrlRead($idComboBox_MODE) GUICtrlSetData($idInput_STATUS,"Command Sent "&$iMenustate) ;Code to send command to instrument goes here Sleep(1000) EndSelect $td = TimerDiff($ts) If $td > 3000 Then ;code to read status of the instrument including its current mode goes here ;For this example I will just set the mode to MODE 1 and display the elapsed time GUICtrlSetData($idInput_STATUS,StringFormat("Status Received: %#.6g ms", $td)) ControlCommand($hGUI, $GUI_Title, $idComboBox_MODE,"SetCurrentSelection", 0) Sleep(1000) $ts = TimerInit() EndIf WEnd Exit EndFunc;==>_Main Edited May 1, 2015 by Queso Link to comment Share on other sites More sharing options...
mikell Posted May 1, 2015 Share Posted May 1, 2015 Is there a way to distinguish between a user selection of the combo box and an update by the program? You could try using WM_COMMAND to check the $CBN_DROPDOWN or $CBN_CLOSEUP notificationsThese are sent if the combo is updated by the user onlyPlease have a look at the example in the helpfile for _GUICtrlComboBox_Create Link to comment Share on other sites More sharing options...
Queso Posted May 1, 2015 Author Share Posted May 1, 2015 mikell, thanks for the response. I will look into those functions. Link to comment Share on other sites More sharing options...
Queso Posted May 1, 2015 Author Share Posted May 1, 2015 Thanks again. This is exactly what I needed! I like that the program can pause the update of the GUI when $CBN_DROPDOWN is active and then send the commands only when $CBN_CLOSEUP is activate. Looks like I will have to rewrite my actual GUI to use these library functions rather than the standard GUI functions. I would like to do a similar process for check boxes and input fields. Which looks like a similar substitution... GUICtrlCreateInput --> _GUICtrlEdit_CreateGUICtrlCreateCheckbox --> _GUICtrlButton_CreateI have one additional question. In order to send the events back to the _Main() function I used a global variable $g_sTemp. It works but I guess it isn't the most elegant solution. Is there a better way to return this information? expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <EditConstants.au3> #include <GuiComboBoxEx.au3> Global $g_hCombo_MODE Global $g_hCombo_CMD Global $g_sTemp = "" _Main() Func _Main() Local $GUI_Title = "Temp" Local $hGUI = GUICreate($GUI_Title, 400, 200,-1,-1) Local $idInput_STATUS = GUICtrlCreateInput(" ", 120, 50, 200, 21,$ES_READONLY) Local $ts = TimerInit() Local $td = TimerDiff($ts) local $sText = "" $g_hCombo_MODE = _GUICtrlComboBox_Create($hGUI, "MODE 1|MODE 2|MODE 3|MODE 4", 10, 50, 100, 21,$CBS_DROPDOWNLIST) $g_hCombo_CMD = _GUICtrlComboBox_Create($hGUI, "CMD 1|CMD 2|CMD 3", 10, 100, 100, 21,$CBS_DROPDOWNLIST) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") While 1 $idMsg = GUIGetMsg() Select Case $idMsg = $GUI_EVENT_CLOSE ExitLoop EndSelect Select Case $g_sTemp = "UPDATE MODE" ; Get Item Text _GUICtrlComboBoxEx_GetItemText($g_hCombo_MODE, _GUICtrlComboBox_GetCurSel($g_hCombo_MODE), $sText) GUICtrlSetData($idInput_STATUS,"Command Sent "&$sText) ;Code to send command to instrument goes here $g_sTemp = "" $ts = TimerInit() Case $g_sTemp = "UPDATE CMD" _GUICtrlComboBoxEx_GetItemText($g_hCombo_CMD, _GUICtrlComboBox_GetCurSel($g_hCombo_CMD), $sText) GUICtrlSetData($idInput_STATUS,"Command Sent "&$sText) ;Code to send command to instrument goes here $g_sTemp = "" $ts = TimerInit() EndSelect If $g_sTemp <> "WAIT" Then $td = TimerDiff($ts) If $td > 2000 Then ;code to read status of the instrument including its current mode goes here ;For this example I will just set the mode to 'MODE 1', CMD to 'CMD 1' and display the elapsed time GUICtrlSetData($idInput_STATUS,StringFormat("Status Received: %#.6g ms", $td)) _GUICtrlComboBox_SetCurSel( $g_hCombo_MODE,0) _GUICtrlComboBox_SetCurSel( $g_hCombo_CMD,0) $ts = TimerInit() EndIf EndIf WEnd Exit EndFunc ;==>Example Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg Local $hWndFrom, $iIDFrom, $iCode $hWndFrom = $lParam $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word $iCode = BitShift($wParam, 16) ; Hi Word Switch $hWndFrom Case $g_hCombo_MODE Switch $iCode Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed $g_sTemp = "UPDATE MODE" Case $CBN_DROPDOWN; Sent when the list box of a combo box is about to be made visible $g_sTemp = "WAIT" EndSwitch Case $g_hCombo_CMD Switch $iCode Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed $g_sTemp = "UPDATE CMD" Case $CBN_DROPDOWN; Sent when the list box of a combo box is about to be made visible $g_sTemp = "WAIT" EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_COMMAND Link to comment Share on other sites More sharing options...
mikell Posted May 2, 2015 Share Posted May 2, 2015 In order to send the events back to the _Main() function I used a global variable $g_sTemp. It works but I guess it isn't the most elegant solution. Is there a better way to return this information?Not sure, the way you use seems good as it makes the return from WM_COMMAND as fast as possible (which is recommended)Probably the $g_sTemp events in the main While loop could be optimized a little Link to comment Share on other sites More sharing options...
Queso Posted May 2, 2015 Author Share Posted May 2, 2015 Yeah that part of the example code was a little quick and messy. Thanks again for your help. 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