Disabling Dialog Controls MFC - mfc

How do I disable all the controls in a dialog window ? I know I could use
EnableWindow(FALSE);
but this doesnt seem like a good idea because now there is no way for the user to click "Ok" or "Cancel" button or press the "X" icon to exit. The dialog is like frozen.
What I am looking for is a way to disable all the controls in a dialog while providing some way for a user to exit.
Another solution is to do it manually by going through all the dialog controls and disabling them but this gets tedious. Any easy way ?
Thanks.

Sorry, but going through all of the controls and disabling each of them is the easy way.
You can write a general function to do this using EnumChildWindows or using a loop calling GetWindow(... GW_HWNDNEXT) until it returns NULL for the next window.
Just remember to skip disabling the window that has the IDCANCEL as the id.

Related

Disable all top level window (WS_POPUP) when showing modal dialog

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!
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...

How to disable user interaction in a Qt application when a DialogBox shown?

I have a modeless QDialog box that popup on errors/warning in my Qt application, I want to force the user to only focus on that dialog box and not click anything in the application until they clicked Ok on the dialog box.
I need the dialog box to remain modeless. A solution like hiding the main window or covering it up is not acceptable.
At the moment I'm using setModal(true); to solve my problem. But I think this method might be stopping the main application from executing.
From the documentation:
If you use show() and setModal(true) together to perform a long
operation, you must call QApplication::processEvents() periodically
during processing to enable the user to interact with the dialog.
Instead of using a QDialog box, try using qDebug statements in your code or a log file using qInstallMsgHandler.
You could also show a QTextEdit and post your log/error messages there in real time, too.
http://qt-project.org/doc/qt-4.8/debug.html
http://qt-project.org/doc/qt-4.8/qdebug.html#details
http://qt-project.org/doc/qt-4.8/qtglobal.html#qInstallMsgHandler
http://qt-project.org/doc/qt-4.8/qtextedit.html#details
If you still really want to debug using a QDialog box for errors, in a pseudo modal dialog but not modal dialog, you could try using eventFilters to prevent mouse and keyboard events from arriving at any other window, but it would be tricky to allow the exception to end up only at QDialog, but it is do-able.
You could also go to the one or two widgets that accept mouse and keyboard input, and ignore the input if the a QDialogBox is visible. But both of these ways of showing an error, but limiting input without making it Modal is really hacky, and would probably be error prone.

c++ win32 prevent context menu from closing

I would like to prevent the context menu from being closed in my win32 c++ application. I want to prevent closing the submenu when user clicks on a submenu item. Which message do i have to implement/override?
Haven't done win32 dev in a while, however just random thoughts that come to my mind - maybe will be helpful:
1) maybe you could try to show the context menu again right after the item was clicked
2) or do it the complex way - find, then subclass the context menu window, then intercept WM_CLOSE/WM_DESTROY messages
Overall this seems to be a weird thing to want to implement. Maybe the menu is not the right UI element if you want to keep it on the screen after the selection was made. Maybe you need a modeless dialog instead?
Please see the following article.

button keyboard focus issues

How would one prevent the little dotted square that appears on a button when it has the keyboard focus in a dialog. (w/ apologies for the technical jargon). At one point I hacked together a solution by subclassing a button WindowProc and subverting some windows messages, but wanted to know the correct way.
There's actually a problem with another control in the dialog also involving the keyboard. This other control is actually also a button, but being used as a group box or panel, not as a functioning button. But when I hit the tab key in the dialog, this group box "button" comes to the foreground obscuring the static controls on top of it, so I wanted to prevent that.
For both of the above, I tried turning off WS_TABSTOP - didn't help.)
Both of my problems mentioned above were solved by subclassing the WndProcs and returning 0 in response to message 0x128 and discarding it. Even Spy++ could not identify this message 0x128, and I don't have it in any header. But its sent to every control in the dialog the first time tab is hit in the dialog.
(I did try BN_SETFOCUS as described above and also WM_SETFOCUS but it didn't help.)
So if anyone knows where to find what windows message 0x128 is...
The correct way is to write your own button control instead of using the default Windows one.
Alternatively, you can prevent if from ever getting keyboard focus.

Convert a modeless dialog to modal at runtime

I have a dialog (CDialog derived class) that can be used in two different ways (edition mode and programming mode).
When the dialog is open to be used in programming mode it is a modeless dialog that it is used for modifying the main view (kind of a toolbar). When it is open in edition mode the user can change the configuration of the dialog itself and in this case it is a modal dialog.
Right now they are two different dialogs with few differences and I would like to have just want dialog and let the user change between programming mode and edition mode just by pressing a button in the dialog.
So I need to convert the modeless dialog in a modal dialog and vice versa at runtime. Is there a way to achive that?
Thanks.
As maybe someone could be interested in doing something similar in the future, this is the way I eventually did it:
I use this two functions of main frame: CMainFrame::BeginModalState() and CMainFrame::EndModalState().
The problem with these functions is the same that with disabling the parent window. The window you want to make modal also gets disabled. But the solution is easy, just re-enable the window after calling BeginModalState.
void CMyDialog::MakeModal()
{
//disable all main window descendants
AfxGetMainWnd()->BeginModalState();
//re-enable this window
EnableWindow(TRUE);
}
void CMyDialog::MakeModeless()
{
//enable all main window descendants
AfxGetMainWnd()->EndModalState();
}
Thanks for your help.
That can't be done easily without closing and reopening the dialog. Then you can call ShowWindow or DoModal as appropriate.
That is not correct. This can be done, if you look at MFC's source you will realize that it's modal dialogs are not technically even modal. You will have to do a lot of mucking about to make this work properly, but basically you just have to disable the parent of the 'modal' window, and re-enable it when the 'modal' window closes.
I have done this personally so this may work for you, though I am not exactly sure what you are trying to do.