Jump to content

Timer causes GUI to hang


DrJohn
 Share

Recommended Posts

Here's what I have:

Main program script starts up, then resides in system tray infinite looping.  (I do this by calling GUICreate('parent'), which I saw in the forum somewhere at some point).

Before going into infinite loop, main script creates a popup GUI to display memory usage, then sets a Timer to update that popup.

At some point, on user input, main script creates another user GUI with which the user is intended to interact.

The idea is that the timer is supposed to keep the popup GUI updated, even when the main script is suspended while the user GUI is displayed.  And it works most of the time.  But intermittently, when the user GUI starts up, it hangs.

Attached is a pared-down prototype.  It's configured so that hitting {F11} pops up the user GUI.  If I start up the main script, then alternately hit {F11} and {Esc}, the user GUI alternately pops up and then disappears.  But eventually (usually within 40 or 50 tries), it hangs unresponsive when it pops up.  If I comment out line #24, on which the Timer is set, that doesn't happen.  So that appears to be the source of the problem.

I'm wondering if there is a somewhat straightforward reason as to why this is evidently fraught with peril.  Timers are a bit of a mysterious beast (at least to me), and it may well be that the answer to the question is "That's crazy!  You just shouldn't use a Timer that way", or the like.

In any case, I expected it to work, so if I understood why it doesn't, I probably would learn something.

Thanks again!

/John

test.au3

Link to comment
Share on other sites

  • Moderators

DrJohn,

i have never found the _Timer* functions particularly reliable so I tend to use Adlib like this:

#include <WindowsConstants.au3>
#include <AutoItConstants.au3>
#include <GuiConstantsEx.au3>
#include <Timers.au3>

Global $g_MainGUI, $g_MemGUI, $g_MemDisplay

HotKeySet("{F11}", ShowConfigGUI)
HotKeySet("{F10}", "_Exit")

Main()

Func Main()

    ; Main GUI
    $g_MainGUI = GUICreate('parent')
    GUISetState(@SW_HIDE)

    ; Popup GUI
    $style = BitOR($WS_POPUP, $WS_BORDER)
    Global $g_MemGUI = GUICreate("", 100, 50, 0, 0, $style)
    GUISetState(@SW_SHOW, $g_MemGUI)
    $g_MemDisplay = GUICtrlCreateLabel("", 10, 10, 60, 20)

    ; Call the function every second
    UpdateMemoryUsage() ; Need to call it immediately or you wait a second!
    AdlibRegister("UpdateMemoryUsage", 1000)

    While True
        Sleep(10) ; 10 is quite enough for an idle loop
    WEnd

EndFunc   ;==>Main

Func UpdateMemoryUsage()

    $a = ProcessGetStats(-1, $PROCESS_STATS_MEMORY)
    ConsoleWrite("Update at: " & @SEC & @CRLF)
    $mem = ($a[0] / (1024 * 1024))
    GUICtrlSetData($g_MemDisplay, StringFormat("%.1f Mb", $mem))

EndFunc   ;==>UpdateMemoryUsage

Func ShowConfigGUI()

    $g_ConfigGUI = GUICreate("Configuration", 400, 300, -1, -1)
    GUICtrlCreateLabel("Hello", 10, 10)

    GUISetState(@SW_SHOW, $g_ConfigGUI)
    While True
        $msg = GUIGetMsg()
        Select
            Case ($msg = $GUI_EVENT_CLOSE)
                ExitLoop
        EndSelect
    WEnd
    GUIDelete($g_ConfigGUI)

EndFunc   ;==>ShowConfigGUI

Func _Exit()
    AdlibUnRegister("UpdateMemoryUsage")
    Exit
EndFunc

i could not get that the fail - over to you to try!

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Argh!

I swear I tried using an Adlib function, before I tried the Timer.  I thought my observation was that the Adlib function didn't trigger while the other GUI was displayed.  But yours obviously does, so either I didn't observe carefully enough, or I did it wrong.  Evidently, I need to take a closer look.

🤦‍♂️

Thanks again, Melba.

/John

Link to comment
Share on other sites

Hi again Melba.

It turns out I wasn't imagining it.  The Adlib function was stopping when the GUI was displayed.  But in whittling the script down for testing (and posting), I inadvertently eliminated the part that made it so.

One of the ways I display the GUI is through the tray menu.  I found this thread from 2011 (in which you participated):

So now I know that an Adlib function is expected to stop when the tray menu is displayed.

That said, what I'm seeing is that once the tray menu closes (and the GUI starts up), the Adlib function remains stopped, which surprises me.

New version of script attached, which now includes all the relevant details.  Run the script, then display the GUI with F11 -- the Adlib function continues running.  Click on the system tray icon and select Configure, and the GUI displays -- but the Adlib function remains stopped until the GUI exits.

By any chance, when the GUI is started from the tray menu, is it regarded as a child window of the tray menu?  So that Windows thinks the tray menu is still open (in some sense) as long as the GUI is open?

/John

EDIT:  I might have thought, then, that if I explicitly specified a parent window when creating the GUI, it might work.  But it didn't.

Seems if I call ShowConfigGUI() directly from the main script, rather than as a callback from TrayItemSetOnEvent(), then the Adlib function keeps running.  So the solution is probably to have the tray menu callback signal to the main script to start up the GUI, rather than doing it itself.

ANOTHER EDIT:  Yes, that seems to be the way to go.

What I would have liked to do is for the top level GUI (the one that gets minimized to the system tray) to have its own message loop, with a Dummy control that I could message from the tray menu callback.  But that evidently requires the top level GUI to be visible (i.e., not @SW_HIDE).  So that doesn't work.

More prosaic way is for the tray menu callback to simply set a flag that the infinite loop in the main script detects, acts on, and resets.  Not as elegant, but I'm pretty sure it will work.

test.au3

Edited by DrJohn
More thoughts after some testing
Link to comment
Share on other sites

  • Moderators

DrJohn,

Quote

...tray menu callback to simply set a flag that the infinite loop in the main script detects, acts on, and resets.  Not as elegant...

Exactly how I would go about it - and I do not consider it at all inelegant.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

21 hours ago, Melba23 said:

Exactly how I would go about it - and I do not consider it at all inelegant.

Well, it seems to work fine, and it wasn't hard to implement.  So I guess I shouldn't knock it.

Thanks again.

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...