Getting the Indeterminate Progress Indicator to do its thing

I’ve added an indeterminate DesktopProgressBar to a PagePanel (on Windows), and told it to Refresh(), so it is visible, but it doesn’t want to do anything (IE show its indeterminate state).

My guess is its lack of indeterminate animation is due to my immediately calling into my DLL, and not returning to the Xojo app.

Is there a trick to setting up a thread to allow the UI to update? Might the DesktopProgressWheel be a better choice? Or would that have the same issue?

If the DLL call is not returning control for the duration of a long-running operation then regular Xojo threads won’t help much. Xojo threads are managed by the Xojo framework, so if the framework doesn’t have control then threads (including the one that drives the GUI) aren’t running.

Calling the DLL function from a Xojo Worker would allow the framework to stay in control while the DLL runs in a separate background app, but that presents its own challenges.

Ideally, the DLL would supply an alternate function that does a little bit of the job and then returns control to Xojo, and jobs are completed through multiple calls to the function from your app.

Sure, I get it. I was wondering how my MacOS code (Objective-C++) manages to do it, and I see I call:

[activationProgressIndicator setUsesThreadedAnimation:YES];

So I guess MacOS (Cocoa) has that figured out.

What would make sense is if I could pass my DLL a callback function which could be called from within the DLL to give the Xojo framework a slice of time to go off and update the UI. (or using some sort of timer perhaps)

…OR – I could just not put up a progress indicator, and tell the user to please wait…

May I suggest to use the Progress Wheel instead ? Make it Visible and Enabled and it works.

@Gilles_Plante – Just tried that. Visible & Enabled. But no, it doesn’t animate while I’m executing code in the DLL.

In Windows you will need a refresh for the Progress Wheel

In Windows you will need a refresh for the Progress Wheel

@Michael_Eckert – Tried that. I explicitly tried:

activationProgressIndicator.Refresh(True)

But no animation.

I’ve activated the ProgressIndicator out of the SelectionChanged event of a DesktopComboBox like this:

ProgressOfLoading.Visible = true
#if TargetWindows then
  ProgressOfLoading.Refresh(true)
#EndIf

In macOs the DesktopProgressWheel works fine, in Windows only after I had installed the refresh.

If your dll is blocking your out of luck. Maybe add your dll code to a console app and use ipcsocket to inform your gui app

1 Like

The DLL is blocking the main thread which means the UI will not update. Xojo threads are cooperative rather than preemptive so calling the DLL from a Xojo thread will not help.

If you have the ability to create a Xojo plugin and the DLL is thread safe then you could get your plugin code to use a preemptive thread to call the DLL. Christian @ MBS and Björn @ Einhuger both use this approach.

I made the ProgressWheel visable and enabled before I called the code that will run for a while, and just after changing the ProgressWheel properties, I added the diabolic statement Do.Events. In my case it’s working in development. I will compile the app and install it in the real environment today for tests, will see if it works again and post back.

Instead of calling “the diabolic statement Do.Events” you might try using a timer in single mode with a period of 100ms from which you execute your DLL processing code. I’ve found that is an effective and safe way to let the UI start a progress wheel or some other control to indicate processing is happening. Additionally sleeping a thread periodically during loops for a few milliseconds hellps keep a progress wheel spinning better.

That is what I have done too

You are on Windows, but I develop on MacOS, could that be a difference ? I mean could the trick not work on Windows ? I will learn soon.

I’ve developed this same app on MacOS, which I’m also more familiar with. Although Apple says there’s one primary UI thread for drawing into a window, MacOS/Cocoa has options to run certain UI processed through a separate thread.

Of course, doing a progress bar or spinner within a normal Xojo app that isn’t calling out to a DLL is clearly going to work. But I’m not married to putting up a progress bar – the interval is only 5 to 15 seconds. It’s just kind top the user.

I’ve an app on macOs and Windows. In macOs is works fine, in Windows I must do additional a refresh(true).

@Michael_Eckert – right, but then you aren’t going off to run code in an external library (DLL) – which is probably why it works for you.

There is a way, though: use a helper to display the indefinite progressbar in a window.

The helper is another desktop application which you place into Resources, and launch with a shell before you call your DLL.

Use IPC to communicate with the helper, so it terminates when needed.

1 Like

@Michel_Bujardet – That sounds like a brilliant solution!

Yes, I have no DLL