0
votes

I have the main window, and then the user can "pop up" one of the frames in the application so that it floats rather than being contained in the main window. There are multiple frames that can be popped up so that in a given time there might be three WS_POPUP windows.

The problem is when I want to show the modal dialog, I can only disable one of them using the parameter in the DoModal function. How can I disable all top-level windows using DoModal? I can't simply disable the windows before showing modal and then enable it back because There could multiple chained modal dialog (one modal dialog opens up another modal dialog).

Does the API provide a way to do something like this? I've googled this for two hours and can't find a good enough solution. I'm using a combination of MFC, WTL, and ATL.

Thanks in advance!

1
That's just not how dialogs work. You'd have to use EnableWindow() explicitly to achieve a similar effect. But don't, it is not intuitive to any user.Hans Passant
@JanS: A modal dialog is owned by its owner. There is no child/parent relationship. A modal dialog does not disable siblings, e.g. other owned windows.IInspectable
@HansPassant Which part do you think is not intuitive? One real world example would be visual studio. Visual studio supports multiple pop up windows. In VS when you want to open a file, all other pop up windows are disabled. Anyway, i'm more concerned about the implementation.bysreg
Well, good example, it never ever makes a docked window modal. It just makes any selections inside the window unavailable when the UI is in the wrong state. When it displays a dialog then you always know it, nobody is ever confused about what, say, File > New > Project or Tools > Options does. Modal operations because they need to be.Hans Passant
Actually, what i meant was that the top level windows are all modeless (and dockable). The modal dialog (from such thing like the open folder) can come from any of those top level windows including the main window. So, I guess there's no really easy way to do it then.bysreg

1 Answers

2
votes

As I understand the problem, it is the same like the MFC frame windows work.

In fact only the CFrameWnd of an MFC application gets disabled. On arrival off the WM_ENABLE message (with FALSE) BeginModalState is called and this function just disables it floating "child windows" of the CFrameWnd.

Same again, when EnableWindow (WM_ENABLE arrives with TRUE) is called for CFrameWnd. EndModalState is called and all disabled "child and floating" windows are enabled again.

See the MFC implementation of CFrameWnd::OnEnable, BeginModalState, EndModalSTate in the source code.

So you main window knows it's own popups. Upon launching the true modal dialog, and disabling this parent, it will disable it's floating popups.

The trick is that CDialog::DoModal needs the real parent... if not given in the constructor it guesses the correct one in most cases. For your case it should be necessary that you provide your "main window" as the parent window... same for message boxes...