Implementing a modal dialog from scratch with C++

Right now I'm implementing my modal dialogs in windows with a separate message loop after popping up the dialog.

This straightforward an approach won't work with other systems that don't have message loops.

Obviously if I'd designed from scratch assuming one message loop I wouldn't have this problem.

In Unity3D (C#) I believe I could use a coroutine for this.

Aside from manually unrolling the code after the message loop so I can put it into a separate state or lambda to be called on close of the dialog, does anyone have any brilliant ideas on ways to make the code work with only one message loop?

I've tried googling but nothing obvious comes up.

EDIT: I know how to write modal dialogs from scratch, the question is whether there's a simpler way to update older code to remove the message loops.

Let me see if I can write a better example of the pseudcode. This is the best I've come up with.

//DoAlert has a while doAlert is up processmessage loop in it
int i = doAlert("title", "Choice1", Choice2", "Choice3")
switch (i) {
Case 1 : do something;
}


do something else and return to the routine that called you which does something else before returning, etc.

would become

auto alert = doAlert("title", "Choice1", Choice2", "Choice3");
... return from routine
... when finally at message pump...


...

Clumsy but at least it's simple to read and understand.

If I were writing from scratch, I would not have written it this way for new code.

I'd rather not decipher all these in order to get rid of the multiple message loops. The only way seems to be to trace what happens when the message loop exits, and put that into a lambda or possibly put the whole mess into a state machine. The lambda seems to be the simplest but it still means tracing through all of them and creating a stack of onexit routines from doAlert.

Thanks, Ralph

• alternatively, tiny file dialogs on sourceforge has several native modal function calls. it's a simple C C++ cross-platform file to add to your project. Jun 29 '16 at 6:24

Just have one message loop with a state or stack of modal dialogs that override your usual control flow:

handle message():
if is input message:
if has modal dialog:
handle modal input message
else:
handle main input message


If you have a window stack, this might be made a bit simple:

handle message():
get top of window stack
dispatch message to window


When you open a modal dialog, just add it to the GUI/Window manager. Now the system that processes input knows where the input goes.

If you're using polling input systems somewhere, also add a flag or check in those, e.g.

is button down():
if has modal dialog:
return false
else:
return is_down[button]


That will make it so any polling systems like gameplay just stop responding to input when the modal dialog pops up. You should probably just pause all those systems when said dialog is up, though:

update game:
update graphics
if no modal dialog is open:
update physics
update AI
update other gameplay


that way you won't keep falling or getting attacked or anything while a modal dialog is open.

So far as code organization, you likely either have a WindowManager of some sort that you pass around everywhere or you just use a global/singleton and carry on.

• I'm basically doing that now. Aug 28 '15 at 12:20
• I'm doing something like that now. My main windows loop runs through all the dialogs to give them a chance to process messages. Pushing a modal dialog onto the stack is like this. self->isDirty = false; self->MainControl->DisplaySelf(); Wait(); //Message Loop DisplayActivePanels(); CheckForDisplayIsDirty(); In some cases I need to do stuff after the dialog has closed, it's not always the same stuff, especially my alert (multiple choice) boxes. I can provide a lambda to the push method to be called on exit, but it's not always easy to puzzle out through the layers of calling code. Aug 28 '15 at 12:32
• Sean, That's a good answer and thanks for taking the time to write it. Unfortunately, it's a lot like what I'm doing now. The problem is that I'm using message loops to keep the modal dialogs open, and I'd rather do something besides add Lambdas to process the code that happens after the dialog closes. C# has something to do that while C++ doesn't as far as I know and I was hoping that there would be some elegant solution I couldn't find. Aug 28 '15 at 12:35
• @RalphTrickey: I guess I don't fully understand your problem. Good GUI (and game) programming is going to be pretty heavily event-based, so making things respond to events (via lambdas, derived dialog impl classes, or some other message-handling system) seems super natural to me. Aug 28 '15 at 15:31
• Let me see if I can write a better example of the pseudcode. //DoAlert has a while doAlert is up processmessage loop in it int i = doAlert("title", "Choice1", Choice2", "Choice3") switch (i) { Case 1 : do something; } do something else and return to the routine that called you which does something else before returning, etc. If I were writing from scratch, I would not have written it this way, I'd rather not decipher all these in order to get rid of the multiple message loops, but it seems like the only way I've seen other than a state machine. Aug 28 '15 at 19:28