Sign in to follow this  
Followers 0
SlowCoder74

GUI events are being skipped in main loop

6 posts in this topic

I'm building my own TCP client/server UDF.  It works, except for some reason it seems like GUI events are skipped in the main program loop.  This is causing it to take multiple seconds (sometimes > 5) to send simple TCP data from server to clients.

I have attached my UDF, and server and client source.

The issue appears in the server program:

- For testing, a pipe is written to console to show each iteration of the main loop.

- When something is sent from the server, it writes the socket it is sending to into the console.  Note that it displays it BEFORE actually calling the _TCPServer_SendData function, so I'm sure that function is not to blame.

- If you run the server, and at least 1 client, when you click the Send button on the server, you can see that multiple iterations of the main loop happen (watch the pipes) before the GUI event is triggered.

- Might be something in _TCPServer_CheckForNewConnections.  If I remark that line in the main loop, the loop runs faster, and it seems like GUI events are captured.

Help appreciated.

Routines_TCP.au3

TCP Server.au3

TCP Client.au3

Share this post


Link to post
Share on other sites



Have you considered registering WM_COMMAND from your GUI? Then you would monitor the "button has been clicked" event from your GUI, instead of monitoring for clicks in your main loop.

 

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiMenu.au3>
#include <WinAPI.au3>

$Form1 = GUICreate("main form", 250, 240)
$Button1 = GUICtrlCreateButton("Click me", 15, 15, 100, 25)
$Button2 = GUICtrlCreateButton("Click me #2", 15, 45, 100, 25)
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND")

ConsoleWrite("!-----------------------------------" & @CRLF & @CRLF & "-> ");
While 1
    ;main loop
    Sleep(250);
    ConsoleWrite("|")
WEnd

Func WM_SYSCOMMAND($hWnd, $iMsg, $WParam, $LParam)
    Switch $hWnd
        Case $Form1
            Switch $WParam
                Case $SC_CLOSE ;X (close) button in the GUI form
                    Exit
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam, $ilParam
    Local $nID = BitAND($iwParam, 0x0000FFFF)
    $iCode = _WinAPI_HiWord($iwParam)
    ;how to detect GUI control clicks:
    Switch $nID
        Case $Button1
            ConsoleWrite(@CRLF & "+> Button 1 clicked!" & @CRLF & "-> ")
        Case $Button2
            ConsoleWrite(@CRLF & ">> Button 2 clicked!" & @CRLF & "-> ")
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Share this post


Link to post
Share on other sites

Thank you, dragan.

I've run into this issue multiple times in the past, on various AutoIt programs I've written.  Registering WM_COMMAND is the general response.  But I'd really like to know why the "normal" method doesn't always work.

Share this post


Link to post
Share on other sites

You are certainly not helping yourself by artificially throttling GUIGetMsg() down to just 20 runs per second. Look at it in the helpfile, notice there are a lot more things it returns than just clicking controls. Even moving the mouse generates a message.

 

If events are skipped, then you are filling up the queue with messages faster than you are removing them. Though it's more likely that they are just delayed (waiting to get in front of the queue) rather than skipped.

 

Simply removing that much too large Sleep() will help a lot. If you want your GUI even more attentive, then add

 

If $nMsg <> 0 Then ContinueLoop
 

after the EndSwitch, so that way you deal with GUI things ASAP, and let the rest of the code in the main loop run when it's less disruptive. You can even keep that Sleep(50) then.

Share this post


Link to post
Share on other sites

Yeah, I'd been adjusting the sleep throughout the dev/troubleshooting process.  50 is very high, and I settled on 10.

I took your suggestion and wrapped the message management code into a do...until $nmsg = 0 loop, and it's working much better.  Really, that's something I should have been able to come up with on my own, but sometimes I think things more complicated than they really are.  Thanks for bringing me back to Earth. :)

Share this post


Link to post
Share on other sites

Don't be hard on yourself! I don't think I've seen anyone use that trick on this forum. Yet you have to wonder, with so many clever people around... Why it isn't seen occasionally. It's such a small yet effective change.

I just wanted to say that you are not alone :)

1 person likes this

Share this post


Link to post
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
Sign in to follow this  
Followers 0