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.
This sample code is provided to illustrate a concept and should not be used in applications or Web sites, as it may not illustrate the safest coding practices. Microsoft assumes no liability for incidental or consequential damages should the sample code be used for purposes other than as intended.
To get samples and instructions for installing them:
On the Visual Studio Help menu, click Samples.
For more information, see Visual Studio Samples.
The most recent version and complete list of samples is available online from the Visual Studio 2008 Samples page.
You can also locate samples on your computer's hard disk. By default, samples and a Readme file are copied into a folder under \Program Files\Visual Studio 9.0\Samples\. For Express editions of Visual Studio, all samples are located online.
To build and run the MODELESS sample
Open the solution modeless.sln.
On the Build menu, click Build.
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.