MODELESS: Uses a CDialog Object as a Modeless Dialog

Click to open or copy the MODELESS project files.

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

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. The Add button on the main dialog is disabled when the modeless dialog box is open so that the user cannot create more than one instance of the modeless box.

The main dialog'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 and therefore would be a great place to start.

The code for the Add button in the main dialog 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. Since the normal OnOk and OnCancel member functions of a CDialog object would call EndDialog, you need to make sure your modeless dialog doesn't 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. Since you can't wait for Create to return while displaying your modeless dialog box, you'll 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 the handler for OnPostNcDestroy — a function that is called after the client area of the box has been destroyed.

Note that the modeless dialog 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 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 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::Enable3dControls; 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