Want to turn progress dialog modal at the end. Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
ebyrob
Knows some wx things
Knows some wx things
Posts: 26
Joined: Wed Sep 28, 2016 8:27 pm

Want to turn progress dialog modal at the end.

Post by ebyrob » Tue Sep 25, 2018 3:18 pm

Hello,

I've implemented a progress dialog derived from wxDialog which makes a pretty good progress bar so far with short bursts of activity interspersed with a lot of:

Code: Select all

wxSafeYield(this)
At the end I finish processing with a tight loop that looks like this as I wait for the user to hit "Close" :

Code: Select all

    while( !this->WasClosed() )
    {
        this->Yield();
        Sleep(1);
    }
Initially I was having trouble restoring from minimize, so I disabled minimize on this dialog. However, in Windows 7 a user can still minimize the window by choosing to "minimize all" from the taskbar. Once minimized, the application gets stuck and won't restore.

It looks like I could alleviate this problem by implementing wxEventLoopBase and using wxEventLoopActivator.

Unfortunately, I can't find any implementations of wxEventLoopBase or uses of wxEventLoopActivator in the wx samples I have. Implementing wxEventLoopBase seems non-trivial as my compiler keeps telling me my wxEventLoopBase derived class is abstract even though I've already stubbed about 8 functions I've no clue how to implement properly.

Is there an easier way to turn a wxDialog modal after already having displayed it with Show()?

Is there a better approach? (progress dialog for single long thread which pauses at the end to wait for close)

Right now my application is entirely single threaded and I'd like to keep it that way for simplicity.
Last edited by ebyrob on Wed Sep 26, 2018 4:28 pm, edited 1 time in total.
Operating System: Windows 7, 64-bit
Compiler: Visual Studio 2010
wxWidgets version: 3.1.0

User avatar
doublemax
Moderator
Moderator
Posts: 14300
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Want to turn progress dialog modal at the end.

Post by doublemax » Tue Sep 25, 2018 3:33 pm

I don't really see why you need that loop at all. The dialog won't disappear on its own.

Why is the dialog not modal from the beginning?
Use the source, Luke!

ebyrob
Knows some wx things
Knows some wx things
Posts: 26
Joined: Wed Sep 28, 2016 8:27 pm

Re: Want to turn progress dialog modal at the end.

Post by ebyrob » Tue Sep 25, 2018 3:42 pm

> Why is the dialog not modal from the beginning?

Well, I couldn't figure out how to keep the thread of execution for myself while calling the blocking method ->ShowModal()

I think I got it, and sorry to bother everyone with a now rhetorical question. I wouldn't have thought to try this but I replaced the above loop with:

Code: Select all

    int nRet = this->ShowModal();
Which silently and brilliantly switched the wxDialog modal in an instant!

Further, to avoid minimize while running I added this to my Yield() function:

Code: Select all

    // in case window gets minimized.  Slightly annoying to pop-back, but effective.  
    wxFrame *pParentWindow = (wxFrame*)wxTheApp->GetTopWindow();
    if( pParentWindow->IsIconized() )
        pParentWindow->Iconize(false); // restore the window if minimized
I'm really impressed that this works. Who would have thought the implementation was that robust!
Last edited by ebyrob on Tue Sep 25, 2018 3:49 pm, edited 1 time in total.
Operating System: Windows 7, 64-bit
Compiler: Visual Studio 2010
wxWidgets version: 3.1.0

ebyrob
Knows some wx things
Knows some wx things
Posts: 26
Joined: Wed Sep 28, 2016 8:27 pm

Re: Want to turn progress dialog modal at the end.

Post by ebyrob » Tue Sep 25, 2018 3:46 pm

> The dialog won't disappear on its own.

I think... I think you're right and I'm not thinking about this correctly. Why can't I just drop the thread when I'm done? For some reason I can't get my head around that after having done so much work with the thread already, I somehow want to hang on to control till completion.

I have the thread. You'll get it back when I'm done thank you very much! Not sure why I can't get around that.
Operating System: Windows 7, 64-bit
Compiler: Visual Studio 2010
wxWidgets version: 3.1.0

Manolo
Can't get richer than this
Can't get richer than this
Posts: 704
Joined: Mon Apr 30, 2012 11:07 pm

Re: Want to turn progress dialog modal at the end.

Post by Manolo » Tue Sep 25, 2018 5:00 pm

Make yourself a favor: Use a dedicated thread for the long task; that comunicates with main, GUI thread, through messages and flags.
In the main thread you update your modal/not modal progress dialog. Even you could delete the not-modal and recreate a new modal one for the last x% of the total task. This way, your app is still responsive (it not modal dialog case).

Threads may seem a bit scary the first time you face them. Not so much. They are worth enough.

ebyrob
Knows some wx things
Knows some wx things
Posts: 26
Joined: Wed Sep 28, 2016 8:27 pm

Re: Want to turn progress dialog modal at the end.

Post by ebyrob » Wed Sep 26, 2018 4:20 pm

My experience with threading has been that it introduces even more non-deterministic behaviors to programs and that it can easily become hazardous.

For this project I'm working in C++ and I'm not at all happy with C++ exceptions, nor very comfortable with the RAII cleanup model. I've just spent about 16 years of my career coding mostly in Java and C# (or Managed C++, which basically is C# for masochists). In those environments I often use threading, but I also have a very robust try/catch/finally exception mechanism to fall back on (even in C++/CLI).

Even in managed code, I generally minimize the number and use of threads.

This wxWidgets GUI application I'm working on is the client half of a client / server application (Yes, a very archaic model I know). Oddly, the server does employ threading to handle many different clients at the same time. However, even there I minimized the threading and relied almost entirely on libmsql.dll and libzmq.dll for synchronization.

I purposely avoided threading in the GUI client because I hoped it would reduce complexity for the maintenance coders who would inevitably come later. I initially chose wxWidgets because 2 developers in another department both use wx in their applications, but to my knowledge, they don't employ threading in their applications. So, I also wanted to write wxWidgets code that was similar in style to what they are used to.

That said, if you're saying wxWidgets loves threading, I suppose I should at least give it a try in some test programs.

The application I have written fulfills the business requirements, but it is not beautiful. It is a bit too tightly coupled to the server over the network and can hang for 5-10 seconds at a time (based on hard-coded timeouts) or for some slower operations as much as 30 to 60 seconds. Generally, I've used a progress dialog in cases where the timeout is greater than 10 seconds, but sometimes it's more important for the user to get things done, than for the a particular user requested operation to be quick and responsive. Slow searches especially (one big SQL SELECT) can be a large bite to chew.
Operating System: Windows 7, 64-bit
Compiler: Visual Studio 2010
wxWidgets version: 3.1.0

Post Reply