Click here to Skip to main content
12,302,493 members (66,071 online)
Click here to Skip to main content
Add your own
alternative version


159 bookmarked

Tutorial - Modeless Dialogs with MFC

, 18 Jun 2002 CPOL
Rate this:
Please Sign up or sign in to vote.
Some tips/suggestions on using modeless dialogs with MFC


Modeless dialog boxes have often puzzled newbie programmers. Basically a modeless dialog box is one that allows us to interact with other windows even when the modeless dialog is still on screen. If you keep in mind a few nifty little tricks then programming modeless dialogs will be a piece of cake.

Creating the modeless dialog

The straightforward way to create a modeless dialog is using Create(). Pass the name of the dialog's template resource and an optional CWnd* which points to the parent window. If you don't pass a parent window pointer the main application window will be used as the parent window. Create() will return true if the call was successful. 

Since Create() returns immediately unlike DoModal(), you must never declare your modeless dialog as a local variable with scope and lifetime only within the function where it is declared. Instead allocate the modeless dialog on the heap. If you don't do that, the modeless dialog will be destroyed the moment, you exit the function within which you declared it.

An alternative solution is to declare your modeless dialog as a heap member object of your main frame window or your CWinApp derived class. An advantage with this method is that you actually have control over the modeless dialog, since you have a pointer to it.

By the way, unlike modal dialogs, modeless dialogs need to have the WS_VISIBLE style set if you want them to be visible immediately after creation. Otherwise you'll have to explicitly call ShowWindow() with SW_SHOW. In fact I recommend that you do this, instead of going all over the place, changing default styles.

CModeLess *m_pmodeless = new CModeLess(this);

The parent issue

The usual practice is to make the parent window the main window of your application, which is typically the main frame window. Now one issue with this is that the modeless dialog will remain on top of this parent window. It allows you to interact with the main frame window, perhaps it contains a CView derived view. But it may be annoying and undesirable to have the modeless dialog remain on top. The solution here is to create the modeless dialog as a child of the desktop. Use GetDesktopWindow() to get a pointer to the Desktop and pass that as the parent window for the modeless dialog in your call to Create().


Destroying the modeless dialog

Since we have allocated memory on the heap, we must delete it when the modeless dialog is destroyed, otherwise we'll soon run into big trouble with memory leaking left, right and center. When the dialog is destroyed the last message our handler class receives is the WM_NCDESTROY message. The OnNcDestroy function is invoked and this in turns calls the virtual function PostNcDestroy. That's exactly where we can delete our modeless dialog. First call the base class function so that it does it's own cleaning up.

void CModeLess::PostNcDestroy() 
    delete this;

Issue with member objects

If the modeless dialog is a member object of the parent window class, we have a slight issue here. The member variable still holds a pointer reference, but the memory it references has been deleted. There are workarounds to this problem. One method is to post an user defined message to the parent window and handle it in the parent class, by setting the modeless dialog member variable to NULL. Another method is to use GetParent() to get the parent window, if any and then cast it to the actual parent class. Now we have access to the parent class's member variable that holds the pointer to the modeless dialog. Set that to NULL. The latter method is portrayed later where I discuss how to restrict a modeless dialog to one instance. The former method is shown below :-

void CModeLess::PostNcDestroy() 
    delete this;
LRESULT CMainFrame::OnMyMethod(WPARAM wParam, LPARAM lParam)
    m_pmodeless = NULL; 
    return 0;

Problems with OnOK() and OnCancel()

In modal dialog boxes, everybody including the queen's cook, has the OK/Cancel buttons. In my opinion, and presumably in many other more learned people's opinions, you'd do good to avoid having OK and Cancel on a modeless dialog. But if for some unavoidable reason, you badly want to have them on your modeless dialog, then you'll need to over-ride both functions.

Here is my modeless version of the OnCancel() function. As you can see I have simply called DestroyWindow() and I haven't bothered to call the base class. In fact don't call the base class at all. The base class function will call EndDialog() which is associated with DoModal().

void CModeLess::OnCancel() 

Okay, now for my modeless version of OnOK(). I have called DestroyWindow() as in the OnCancel(), but there is some extra code too as you can see. I am calling UpdateData, because that's what OnOK() does in a modal dialog. If the DDV macro validations are successful then UpdateData(true) returns true and we destroy the window, else the DDV message box is automatically shown to the user and we refuse to destroy the dialog. Thus we are simulating the behavior of a modal dialog's OK button here.

void CModeLess::OnOK() 


Passing back data

In modal dialogs, we can still access the data variables when DoModal() returns because the dialog object has not been destroyed yet, only the underlying dialog window has been destroyed. This is also possible with modeless dialogs using a nifty trick as shown below.

void CModeLess::OnOK() 


Here I have assigned the value of the dialog data variable m_sss to the parent class's member variable, m_x. Here,m_parent is a pointer to the parent window. If you are wondering where I got this m_parent from, scroll up and see how I have constructed my modeless dialog object. I'll repeat that single line to refresh your memory, and also to help you avoid scrolling, thus saving you some energy.

CModeLess *m_pmodeless = new CModeLess(this);

As you can see, I have passed this to the constructor. In my case, this is a pointer to my CFrameWnd derived class which App Wizard has named as CMainFrame for me. Now take a look at my CModeLess class's constructor.

CModeLess::CModeLess(CWnd* pParent /*=NULL*/)
    : CDialog(CModeLess::IDD, pParent)
    m_sss = 0;
    m_parent=pParent; //This is where I point m_parent to my main frame window

It all slowly makes sense, eh?

Tracking the modeless dialog count

Let's say you want to have only one instance of the modeless dialog alive at one time. In that case, each time the user initiates some action that results in the bringing up of the modeless dialog you have to check and see if the modeless dialog is already active. Say, m_pmodeless is the modeless dialog member of your class. In the class constructor set m_pmodeless to NULL. Now each time you check to see if m_pmodeless  is NULL and if it is NULL, create a new modeless dialog, otherwise, show a MessageBox that the dialog is already active or use SetForegroundWindow() to bring the modeless dialog to the foreground..

Here is how I create my modeless dialog now that I want to restrict them to just one at a time:-

    m_pmodeless = new CModeLess(this);

But when the dialog is destroyed we need to inform the parent class that the pointer it holds is now useless. What we do is to set that pointer to NULL in the PostNcDestroy. In fact it is essential that you do this, otherwise the next time the user tries to activate the modeless dialog, your program will crash as it thinks m_pmodeless is still pointing to a valid dialog window and tried to call SetForegroundWindow() on it. And here is my PostNcDestroy :-

void CModeLess::PostNcDestroy() 
    ((CMainFrame*)m_parent)->m_pmodeless = NULL;
    delete this;


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Nish Nishant
United States United States
Nish Nishant is a Software Architect/Consultant based out of Columbus, Ohio. He has over 16 years of software industry experience in various roles including Lead Software Architect, Principal Software Engineer, and Product Manager. Nish is a recipient of the annual Microsoft Visual C++ MVP Award since 2002 (14 consecutive awards as of 2015).

Nish is an industry acknowledged expert in the Microsoft technology stack. He authored
C++/CLI in Action for Manning Publications in 2005, and had previously co-authored
Extending MFC Applications with the .NET Framework for Addison Wesley in 2003. In addition, he has over 140 published technology articles on and another 250+ blog articles on his
WordPress blog. Nish is vastly experienced in team management, mentoring teams, and directing all stages of software development.

Contact Nish : You can reach Nish on his google email id voidnish.

Website and Blog

You may also be interested in...

Comments and Discussions

GeneralVery nice!!! Pin
eb300023-May-04 23:45
membereb300023-May-04 23:45 
GeneralThanx a lot that helps Pin
cycosi12-May-04 3:51
membercycosi12-May-04 3:51 
GeneralThank you . Good article Pin
Ramanan Sivan4-May-04 7:41
memberRamanan Sivan4-May-04 7:41 
GeneralEvaluating Memory-Checking for Memory Leaks Pin
johnsb23-Mar-04 4:29
memberjohnsb23-Mar-04 4:29 
GeneralRe: Evaluating Memory-Checking for Memory Leaks Pin
rbid21-Jun-04 5:26
memberrbid21-Jun-04 5:26 
QuestionHow to create modeless dialog using CreateEx() Pin
Short Wills2-Mar-04 17:27
memberShort Wills2-Mar-04 17:27 
GeneralPostNcDestroy problems Pin
andyg.1019-Jun-03 8:48
memberandyg.1019-Jun-03 8:48 
GeneralRe: PostNcDestroy problems Pin
Nishant S9-Jun-03 10:04
editorNishant S9-Jun-03 10:04 
GeneralRe: PostNcDestroy problems Pin
andyg.1019-Jun-03 23:38
memberandyg.1019-Jun-03 23:38 
GeneralRe: PostNcDestroy problems Pin
Nishant S11-Jun-03 4:59
editorNishant S11-Jun-03 4:59 
GeneralRe: PostNcDestroy problems Pin
andyg.10113-Jun-03 1:05
memberandyg.10113-Jun-03 1:05 
GeneralRe: PostNcDestroy problems Pin
Dan Spear13-Jun-03 4:09
memberDan Spear13-Jun-03 4:09 
GeneralRe: PostNcDestroy problems Pin
andyg.10113-Jun-03 10:22
memberandyg.10113-Jun-03 10:22 
GeneralRe: PostNcDestroy problems Pin
andyg.10113-Jun-03 22:32
memberandyg.10113-Jun-03 22:32 
QuestionModeless Dialogs and threads??? Pin
dragonshot22-May-03 13:18
memberdragonshot22-May-03 13:18 
Generalpointer and new method Pin
tatalevieuxgrincheux15-May-03 14:58
susstatalevieuxgrincheux15-May-03 14:58 
GeneralRe: pointer and new method Pin
Nitron22-May-03 13:42
memberNitron22-May-03 13:42 
GeneralDialog without initial focus Pin
rrrado10-Apr-03 5:36
memberrrrado10-Apr-03 5:36 
GeneralRe: Dialog without initial focus Pin
Nishant S13-Apr-03 9:05
editorNishant S13-Apr-03 9:05 
GeneralRe: Dialog without initial focus Pin
rrrado13-Apr-03 21:05
memberrrrado13-Apr-03 21:05 
AnswerRe: Dialog without initial focus Pin
wuzhlg8-Feb-11 3:14
memberwuzhlg8-Feb-11 3:14 
Generalhelp with modeless dialogue Pin
Anonymous10-Apr-03 0:17
sussAnonymous10-Apr-03 0:17 
Generalsorry meant to check as is Pin
Anonymous10-Apr-03 0:18
sussAnonymous10-Apr-03 0:18 
GeneralGood Article Pin
babiq25-Mar-03 19:49
memberbabiq25-Mar-03 19:49 
GeneralMessage Pin
laue2-Feb-03 3:26
memberlaue2-Feb-03 3:26 
Generalrunning UpdateAllViews in modeless dialog Pin
boon kian29-Jan-03 4:28
memberboon kian29-Jan-03 4:28 
Generaltransferig data between modelless dialogs Pin
pmukh29-Jan-03 1:27
memberpmukh29-Jan-03 1:27 
GeneralModeless dialogs always on top of CChildFrame classes Pin
Christohper Crotty17-Jan-03 7:56
sussChristohper Crotty17-Jan-03 7:56 
GeneralMain window not responding to left click if modeless dialog got focus Pin
gaamoa2k16-Jan-03 14:49
membergaamoa2k16-Jan-03 14:49 
GeneralOnOk not called Pin
niklas11-Jan-03 3:17
memberniklas11-Jan-03 3:17 
GeneralRe: OnOk not called Pin
Nishant S29-Jan-03 16:33
editorNishant S29-Jan-03 16:33 
GeneralRe: OnOk not called Pin
Anonymous30-Jan-03 3:39
sussAnonymous30-Jan-03 3:39 
GeneralExcellent article Pin
Dylan Kenneally17-Dec-02 0:10
memberDylan Kenneally17-Dec-02 0:10 
GeneralRe: Excellent article Pin
Nishant S19-Dec-02 12:51
editorNishant S19-Dec-02 12:51 
GeneralPostNcDestroy() not being called Pin
Ly Ter16-Dec-02 10:12
sussLy Ter16-Dec-02 10:12 
GeneralRe: PostNcDestroy() not being called Pin
Ly Ter17-Dec-02 4:18
sussLy Ter17-Dec-02 4:18 
GeneralRe: PostNcDestroy() not being called Pin
Ly Ter17-Dec-02 4:23
sussLy Ter17-Dec-02 4:23 
GeneralRe: PostNcDestroy() not being called Pin
Nishant S19-Dec-02 12:51
editorNishant S19-Dec-02 12:51 
QuestionHow i get datas from myDoc Pin
Anonymous5-Nov-02 23:05
sussAnonymous5-Nov-02 23:05 
AnswerRe: How i get datas from myDoc Pin
Nishant S19-Dec-02 12:53
editorNishant S19-Dec-02 12:53 
GeneralModeless in MDI Pin
mduong8125-Oct-02 13:30
membermduong8125-Oct-02 13:30 
GeneralRe: Modeless in MDI Pin
Nishant S19-Dec-02 12:55
editorNishant S19-Dec-02 12:55 
Generalexactly what I needed Pin
Mike Mentes13-Oct-02 15:03
sussMike Mentes13-Oct-02 15:03 
GeneralRe: exactly what I needed Pin
Nishant S13-Oct-02 15:09
editorNishant S13-Oct-02 15:09 
GeneralRe: exactly what I needed Pin
Kannan Kalyanaraman14-Oct-02 3:38
memberKannan Kalyanaraman14-Oct-02 3:38 
GeneralRe: exactly what I needed Pin
Nishant S14-Oct-02 3:36
editorNishant S14-Oct-02 3:36 
Generaldestroying the window Pin
brianwelsch3-Oct-02 10:43
memberbrianwelsch3-Oct-02 10:43 
GeneralRe: destroying the window Pin
Nishant S3-Oct-02 12:10
editorNishant S3-Oct-02 12:10 
GeneralRe: destroying the window Pin
TornNight27-Nov-02 11:00
memberTornNight27-Nov-02 11:00 
QuestionIs there a way to make a modeless dialog resize automatically? Pin
Dave W.12-Sep-02 11:19
memberDave W.12-Sep-02 11:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160530.1 | Last Updated 19 Jun 2002
Article Copyright 2001 by Nish Nishant
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid