Assert raisied when closing multi-level modal dialog recursively

33 views
Skip to first unread message

Assen Mladenov

unread,
Apr 17, 2026, 6:12:08 AM (10 days ago) Apr 17
to wx-users
Hi,
I need to close (stacked) modal dialogs programmatically and I try doing that in a recursive fashion, starting from the one on top.

Here is the piece of code that is executed on the main event loop (the app's):

static void closeAllDialogsRec(wxWindow* parent, wxApp *app) {
    auto pclNode = parent->GetChildren().GetFirst();
    while (pclNode) {
        auto dlg = wxDynamicCast(pclNode->GetData(), wxDialog);
        if (dlg && dlg->IsModal()) {
            closeAllDialogsRec(dlg, app);
            app->CallAfter([dlg, app]() mutable {
                wxCommandEvent evt(wxEVT_CLOSE_WINDOW);
                wxQueueEvent(dlg, evt.Clone());
                });
            break;
        }
        pclNode = pclNode->GetNext();
    }
}

The issue is that the top one's event loop is active and it can be closed, but the for the others below, their event loops are still inactive and it fails for them. So on theory, we have to wait until the next dialog becomes "active" and then close it only then. How though ?


Best regards,
Assen

Vadim Zeitlin

unread,
Apr 18, 2026, 9:10:06 AM (9 days ago) Apr 18
to wx-u...@googlegroups.com
On Fri, 17 Apr 2026 00:47:54 -0700 (PDT) Assen Mladenov wrote:

AM> I need to close (stacked) modal dialogs programmatically and I try doing
AM> that in a recursive fashion, starting from the one on top.

Why can't you just call EndModal() if you have the pointers to all dialogs
already?

AM> Here is the piece of code that is executed on the main event loop (the
AM> app's):
AM>
AM> static void closeAllDialogsRec(wxWindow* parent, wxApp *app) {
AM> auto pclNode = parent->GetChildren().GetFirst();
AM> while (pclNode) {
AM> auto dlg = wxDynamicCast(pclNode->GetData(), wxDialog);
AM> if (dlg && dlg->IsModal()) {
AM> closeAllDialogsRec(dlg, app);
AM> app->CallAfter([dlg, app]() mutable {
AM> wxCommandEvent evt(wxEVT_CLOSE_WINDOW);
AM> wxQueueEvent(dlg, evt.Clone());
AM> });
AM> break;
AM> }
AM> pclNode = pclNode->GetNext();
AM> }
AM> }
AM>
AM> The issue is that the top one's event loop is active and it can be closed,
AM> but the for the others below, their event loops are still inactive and it
AM> fails for them. So on theory, we have to wait until the next dialog becomes
AM> "active" and then close it only then. How though ?

You probably need to close one dialog at a time, i.e. return to the main
event loop after closing the first dialog and then redoing it again as long
as there are more dialogs, but this risks being messy.

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
https://www.tt-solutions.com/
Reply all
Reply to author
Forward
0 new messages