MODELESS Sample: Uses a CDialog Object as a Modeless Dialog Box

The MODELESS sample demonstrates the use of an MFC CDialog object as a modeless dialog box. MODELESS is a simple dialog-based application that manages a list box in its main dialog box while providing a modeless dialog box that allows you to add strings to the list box in the main window.

Security noteSecurity Note

This sample code is intended to illustrate a concept, and it shows only the code that is relevant to that concept. It may not meet the security requirements for a specific environment, and it should not be used exactly as shown. We recommend that you add security and error-handling code to make your projects more secure and robust. Microsoft provides this sample code "AS IS" with no warranties.

To get samples and instructions for installing them:

To access samples from Visual Studio

  • On the Help menu, click Samples.

    By default, these samples are installed in drive:\Program Files\Microsoft Visual Studio 10.0\Samples\.

  • For the most recent version of this sample and a list of other samples, see Visual Studio Samples on the MSDN Web site.

To build and run the MODELESS sample

  1. Open the solution modeless.sln.

  2. On the Build menu, click Build.

  3. On the Debug menu, click Start Without Debugging.

When the sample starts, it presents an empty list box. You can open the modeless dialog box by clicking Add. Even while the Modeless Adder dialog box is open, you can bring focus back to the main dialog box. The Add button on the main dialog box is unavailable when the modeless dialog box is open so that the user cannot create more than one instance of the modeless box.

The main dialog box's CMainDlg class manages a pointer to the modeless dialog box. It does this just for convenience; once created, the modeless dialog box requires no further management. In your application, you might choose to offer the modeless box information — that pointer would provide access to the C++ object managing the dialog box and therefore would be a great place to start.

The code for the Add button in the main dialog box creates the modeless dialog box using the Create function, instead of calling DoModal. This is what makes the box modeless; Windows treats messages for the box differently. When the box is destroyed, EndDialog is not used; instead, DestroyWindow is called. Because the normal OnOk and OnCancel member functions of a CDialog object would call EndDialog, make sure your modeless dialog box does not call those functions and instead overrides them to call DestroyWindow.

Usually, when you create a modal dialog box, you destroy it manually after DoModal returns. Because you cannot wait for Create to return while displaying your modeless dialog box, you need to have some other mechanism for destroying the C++ object associated with the window. This sample uses a very simple mechanism: It performs delete this in PostNcDestroy — a function that is called after the nonclient area of the box has been destroyed.

Note that the modeless dialog box communicates with its parent dialog in two different ways. First, when the user presses OK, the string in the edit control in the modeless dialog box is added to the content of the list box in the modal dialog box. Second, when the user destroys the window by whatever means, the modeless box calls the BoxDone function in the modal window. This function simply resets the pointer to the modal dialog box and re-enables the Add button.

This sample demonstrates the following keywords:

AfxGetApp; CDC::DrawIcon; CDC::GetSafeHdc; CDialog::Create; CDialog::DoModal; CDialog::OnCancel; CDialog::OnOK; CListBox::AddString; CMenu::AppendMenu; CMenu::ModifyMenu; CRect::Height; CRect::Width; CString::IsEmpty; CString::LoadString; CWinApp::InitInstance; CWinApp::LoadStdProfileSettings; CWnd::DestroyWindow; CWnd::DoDataExchange; CWnd::EnableWindow; CWnd::GetClientRect; CWnd::GetDlgItem; CWnd::GetWindowText; CWnd::IsIconic; CWnd::OnPaint; CWnd::OnQueryDragIcon; CWnd::OnSysCommand; CWnd::PostNcDestroy; CWnd::SendMessage; CWnd::SetActiveWindow; GetSystemMenu; GetSystemMetrics; LoadIcon


Some samples, such as this one, have not been modified to reflect the changes in the Visual C++ wizards, libraries, and compiler, but still demonstrate how to complete your desired task.

Other Resources