MFC Dialog Showing Problem - mfc

I create class with base class of CPropertySheet, show this dialog using
d.DoModal()
and it freezes my application. Can I execute my dialog asynchronously?
d.ShowWindow(SW_NORMAL)
doesn't work.

You need to use CPropertySheet::Create to use the dialog asynchronously. There's also some hints at http://support.microsoft.com/kb/146916 .

Related

Possible to Superclass a Dialog Box in Win32?

I'm using raw Win32 and C++ for a project. As I understand it, I am able to superclass Windows controls by retrieving the class information, replacing the procedure, then registering this as a new class and using it when creating a new window. Subclassing is done by replacing the window's procedure after the window is created. The advantage of superclassing is that you are able to process messages before CreateWindow() returns.
I'm looking to see if it's possible to superclass a dialog box created with CreateDialog() because I'd like to use a resource file for the dialog layout. The problem is that I don't know how I would provide my superclass when I create a dialog box. Is it even possible? Any idea how MFC handles this?
If you use an extended dialog box template to create your dialog, you can specify a custom window class as part of the DLGTEMPLATEEX definition.
The dialog manager will create and layout your dialog as normal, and call your window procedure for any dialog messages. You can use the DefDlgProc function to obtain default processing for any dialog messages you don't want to handle yourself.

create dialog that doesn't block the main app mfc

I'm using mfc, is there any way to create a dialog that doesn't block the main app without using threads?
if yes, how can i do it?
thanks in advance
You need to create a modeless dialog. Click the link for more details.
There is a good tutorial about it here.
Example to display:
CModeLess *m_pmodeless = new CModeLess(this);
m_pmodeless->Create(CModeLess::IDD);
m_pmodeless->ShowWindow(SW_SHOW);
I won't repeat the tutorial but it explains how you using messages to relay to the parent what the dialog result is.

MFC one parent dialog, multiple child dialogs

I want to build a MFC application, with one main dialog, and all the other dialogs are child of this main dialog (and embedded in it).
Now, i was able to embed the first child in the main dialog, but i want to pass to the next dialog (note that the order of opened dialogs is random), so i need to hide the first dialog and show another. To know which dialog is shown at the moment and hide it, i've tried using a CDialog variable to store the current opened dialog, but i get a CObject::operator =' : cannot access private member declared in class 'CObject' error.
Is there another way to do this "hide and show dialogs" game?
EDIT: Could i store some ID of the dialogs and use it to acomplish this task?
So i managed to accomplish this task using classes IDDs.
First, i store the last opened dialog's IDD
m_dlgStartPage.Create(CStartPageDlg::IDD, this);
m_openedWin.nDialogIDD = m_dlgStartPage.IDD;
m_dlgStartPage.ShowWindow(SW_SHOW);
Then, when a new dialog needs to be shown, i send a message to my main dialog (nIDD is the IDD of pending dialog to show):
AfxGetApp()->m_pMainWnd->SendMessage(WM_COMMAND_CHANGE_WINDOW, nIDD, 0);
And last, in my main dialog, i parse all the child dialogs and check if m_openedWin.nDialogIDD matches with each dialog's IDD, so i can hide it. After this, i parse once again all the chid dialogs and use the nIDD from the sent message to show the correct one.
I don't really like this approach, because of all the parsing and sent messages to the main dialog's class, so if anyone has a better idea or method, please post it.

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.

MFC modal dialog close error

I have a strange error and spend hours in the debugger without finding a solution.
(But it helped me to fixed another error that you should never call EndDialog from a WM_KICKIDLE task).
My problem is that i have a main window and a modeless dialog window wich raises a modal subdialog window. When the subdialog window is closed. The modeless dialog window turns itself into a modal window. My code really does leave the modal loop. And if i close the now modal window it behaves like an invisble modal window is active, meaning no interaction is possible anymore.
When i only run a modal dialog on top of the main window it is closed fine.
BTW: The main window is not the one available view CWinApp::m_pMainWnd but a new create FrameWindow. I hide the p_MainWnd and use it as an invisible message only window. From some comments and my debugging session i found that the pMainWnd has some special meaning but i could figure what exactly it has to do with modal windows (there is an undocumented "CWinApp::DoEnableModeless" for example).
EDIT: I'm posting a WM_CLOSE to the dialog and then use EndDialog(0) from the OnClose() handler to exit the modal state. I also tried to use EndDialog(0) directly. There is no difference between this two methods.
When MFC creates a modal dialog, it makes it modal by disabling the windows above it. The code that reenables those windows occurs when the dialog ends normally with a call to EndDialog. If anything prevents that code from running, the other windows will be locked out.
Modeless dialogs are a different beast, and there's a note specifically in the EndDialog documentation warning you to use DestroyWindow instead.
Maybe this is justifiable but I have a question:
why are you using hidden window? Was it created as message only window (passing HWND_MESSAGE as a parent handle and Message as a class) or you just call it message only?
OK, a little more info about MFC and dialogs.
MFC does not use Windows modal dialog. It always creates modeless dialog; either Create or DoModal call in turn ::CreateDlgIndirect windows API.
Modeless dialof rely on the main window message dispatch, while modal calls RunModalLoop that is similar to MFC window message pupmp (not a message loop).
It runs in the main thread of execussion without freezing because it allows for idle processing (calls OnIdle).
How do you dismiss the modeless dialog? As Mark pointed you should use DestroyWindow.
As for m_pMainWnd, MFC framework uses it extensively to determine may things that control main window behavior. By changing it you may have created the behavior you experience.
Did you set the value to a newly created frame you treat as a main window?
What kind of MFC application is it? SDI or MDI?
Would it be possible to create test app to duplicate this behavior and post it somewhere for download?
By the way, you do not have to be concern about DoEnableModeless, since it does not do anything but calls hook (COleFrameHook type) that is spasly used, unless you are trying to implement some functionality using OLE or ActiveX or you are trying to marry MFC and .NET Windows Forms.
In conclusion if your (or third party code uses this hook, I would suggest checking the code in the COleFrameHook class.