[Win32]: Is it possible to display modeless dialog yet make it "stuck in your face"?

Started by
7 comments, last by Codeka 14 years, 8 months ago
Hi, I'm making an editor for a game and with modal dialogs the simulation loop hanged when a dialog was up. Now I've changed all my dialogs to modeless and that solved that particular issue, however, now the user can click on any other window in the application without first closing the dialog - which isn't what I want. There must surely be a way to make a dialog TOPMOST as well as prioritized which disables the rest of the stuff in the background. I've tried intercepting callbacks and trying to hinder the main window from doing its stuff while a dialog is up, but that killed all commands to the actual dialog, too. Threading isn't possible with the nature how this 3rd party engine is designed so I hope that isn't the answer. Any assistance is appreacited!
Advertisement
You can just use EnableWindow to disable the parent window while your "modal" window is active. I would suggest that you try to avoid that wherever possible, though - you've already done the hard work of making your windows modaless, don't destroy all that good work by making things modal again!
WS_EX_TOPMOST is the style you want. otherwise use SetWindowPlacement to push it to the top of the z-order if you want other windows to be able to placed over it. Note this applies only to the windows in your process other windows of other processes can be put above you I believe.
Well, disabling the parent would bring me back to modalness again as you said - which is not what I'm looking for. I still want the parent to paint itself and my main loop to continue.

If you have a menu, and a File submenu with "Open File" as an option that brings up a dialog. You don't want the user able to click the menu again and open up another dialog of the same type when you already have one opened.

Modalness solves that, but then my main loop stalls.
Oh well, guess I'll have to disable all other controls while the dialog is up. It's just so much work..
Quote:Original post by david_watt78
WS_EX_TOPMOST is the style you want. otherwise use SetWindowPlacement to push it to the top of the z-order if you want other windows to be able to placed over it. Note this applies only to the windows in your process other windows of other processes can be put above you I believe.


That does place the window ontop, but other windows are still processing input.
For instance, in the WarCraft III editor you can have the "Do you want to save your changes" dialog up, while in the background the game view is still updated and other controls around the dialog too, but the dialog blinks when you try to click anywhere else.

Edit: I tried making all dialogs modal again, but in their WM_PAINT callbacks calling my main loop. That did update my main loop but only when I moved the mouse or clicked somewhere..

I'm out of ideas.

Solution: Gah, I had no idea you could open up a modal window and process its messages while calling your main loop from there. This awesome article explains how!

[Edited by - SymLinked on August 18, 2009 8:12:33 AM]
Adding a timer to your window should work, and update on WM_TIMER messages.
EDIT: I see you found a better solution. =)
(Tack Erik!)

I've found an even more simple solution than the message queue. I'm not sure if it has any side effects but right now it works exactly like I wanted it, and like the other game editors I've seen.

Before creating the dialog (with CreateDialog, not DialogBox which is modal) I disable the parent (with EnableWindow) and all of the sudden it works. The background is updated and doesn't get white as I move the dialog around, my main loop keeps going but the user has to close the dialog to be able to click anywhere else.

It also seems I don't have to re-enable the parent when the dialog is closed.
Another approach would be to process WM_SETFOCUS in your main window. If the window that's going to lose focus is the dialog, set the focus back to the dialog.

EDIT: Or vice-versa with WM_KILLFOCUS in the dialog.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Quote:Original post by SymLinked
Well, disabling the parent would bring me back to modalness again as you said - which is not what I'm looking for. I still want the parent to paint itself and my main loop to continue.
If you just disable the parent, then it won't be exactly like you had. There's actually two parts to a model dialog. One is that it disables the parent when the dialog is shown, and the other is that the message loop is executed by the modal dialog until it is closed (that's how things like GetOpenFileName can return only once the user has clicked "OK"). The first thing is what prevents you from clicking on the parent to give it focus (and what you're after) but it's the second point that makes your rendering stall.

So if you simply disable the parent window, then you'll get the modal behaviour, while still running your own message loop and being able to run your render thread as well. Disabling a window only stop it from getting input messages and being activated - it still gets all of the other messages (otherwise, you'd never see a regular window repaint it self when you move it's modal children around).

My point about "destroying all your hard work" is that, in general, modal dialogs are bad for productivity. They force a workflow on the user which may not be the best, where as a modaless dialog allows the user to continue to work with the dialog open. For example, a "properties" dialog which updates itself based on your selection whenever your selection changes, rather than having to close the current dialog, and select "properties" for the next element, etc.

This topic is closed to new replies.

Advertisement