- Table of Contents
- Copyright
- About the Authors
- About the Contributors
- Acknowledgments
- Tell Us What You Think!
- Introduction
- How to Use This Book
- What You Need to Use This Book
- What's New in Visual C++ 6.0
- Contacting the Main Author
- Part I: Introduction
- Chapter 1. The Visual C++ 6.0 Environment
- Part II: MFC Programming
- Chapter 2. MFC Class Library Overview
- Chapter 3. MFC Message Handling Mechanism
- Chapter 4. The Document View Architecture
- Chapter 5. Creating and Using Dialog Boxes
- Chapter 6. Working with Device Contexts and GDI Objects
- Chapter 7. Creating and Using Property Sheets
- Chapter 8. Working with the File System
- Chapter 9. Using Serialization with File and Archive Objects
- Part III: Internet Programming with MFC
- Chapter 10. MFC and the Internet Server API (ISAPI)
- Chapter 11. The WinInet API
- Chapter 12. MFC HTML Support
- Part IV: Advanced Programming Topics
- Chapter 13. Using the Standard C++ Library
- Chapter 14. Error Detection and Exception Handling Techniques
- Chapter 15. Debugging and Profiling Strategies
- Chapter 16. Multithreading
- Chapter 17. Using Scripting and Other Tools to Automate the Visual C++ IDE
- Part V: Database Programming
- Chapter 18. Creating Custom AppWizards
- Chapter 19. Database Overview
- Chapter 20. ODBC Programming
- Chapter 21. MFC Database Classes
- Chapter 22. Using OLE DB
- Chapter 23. Programming with ADO
- Part VI: MFC Support for COM and ActiveX
- Chapter 24. Overview of COM and Active Technologies
- Chapter 25. Active Documents
- Chapter 26. Active Containers
- Chapter 27. Active Servers
- Chapter 28. ActiveX Controls
- Part VII: Using the Active Template Library
- Chapter 29. ATL Architecture
- Chapter 30. Creating COM Objects Using ATL
- Chapter 31. Creating ActiveX Controls Using ATL
- Chapter 32. Using ATL to Create MTS and COM+ Components
- Part VIII: Finishing Touches
- Chapter 33. Adding Windows Help
- Part IX: Appendix
Modeless Dialog Boxes
So far, you've seen how to create a modal dialog box using the DoModal() function. When a modal dialog box is displayed, the user is unable to interact with any other parts of the application's user interface until the dialog box is closed.
You may want to display a dialog box like a control palette, for example, or to provide feedback such as coordinates from a drawing operation. To do this, you'll need a modeless dialog box.
Modeless Dialog Box Resource Templates
You should consider a few differences when creating a dialog box template for a modeless dialog box.
First, you may not require OK and Cancel buttons for a modeless dialog box, because these usually are associated with modal operations. The user normally closes a modeless dialog box via the close box (a small x) in the upper-right corner of the dialog box. If you do decide to use OK and Cancel buttons, you must override the default OnOK() and OnCancel() message handlers and create your own that call DestroyWindow(). You must do this because the default functions call EndDialog(), which only closes a dialog box in modal operation.
Second, if you want your dialog box to be visible after creation, you should set the Visible flag in the dialog box's properties (on the More Styles tab). By setting this flag, you create the dialog box with the WS_VISIBLE style. Otherwise, the dialog box is created but remains invisible unless you call the dialog box's ShowWindow() function passing TRUE.
Figure 5.9 shows the Visible property for a modeless dialog box with no OK or Cancel button.
Figure 5.9 A typical modeless dialog box template and properties.
Creating and Destroying Modeless Dialog Boxes
You can create a modeless dialog box by using the Create() function instead of the DoModal() function to display the dialog box.
You should pass the dialog box's template ID (or a resource name) to Create() and optionally a pointer to a parent window. If the creation succeeds, Create() returns a TRUE value and the dialog box is created.
If you haven't specified the WS_VISIBLE flag on the dialog box template, nothing is displayed until you call ShowWindow(TRUE). If you have set this flag, the modeless dialog box is displayed immediately.
The Create() function returns immediately after the dialog box is created—unlike the DoModal(). This has implications for the scope and lifetime of your modeless dialog box class. You should never declare your modeless dialog box as a local function variable as you might with a modal dialog box. If you do, when the function returns, the dialog box's handler object is destroyed, and the modeless dialog box is destroyed immediately by the CDialog base class destructor.
Instead, you can allocate the memory dynamically and, depending on your application requirements, track the memory or just let the dialog box delete itself when it is closed.
If you don't track the dialog box, for example, you may create an instance from a menu handler function like this:
void CDialogTemplDoc::OnShowdialogDisplaymodeless()
{
CModeless* pDlgModeless = new CModeless;
pDlgModeless->Create(CModeless::IDD);
}
If you allocate the memory in this way, you must delete it after the dialog box is closed to avoid memory leaks. When the dialog box is closed, the last message sent to your dialog box handler class is WM_NCDESTROY. The default implementation of OnNcDestroy() then does some housekeeping and finally calls the PostNcDestroy() virtual function. You can override this virtual function to delete the C++ this pointer to the dialog box object itself.
You can add an override to your CDialog-derived class by using the Add Virtual Function dialog box and then adding the delete statement like this:
void CModeless::PostNcDestroy()
{
CDialog::PostNcDestroy();
// Delete Ourselves
delete this;
}
If you want to create the modeless dialog box from a memory-based dialog box template (instead of a resource), you can call the CreateIndirect() function passing a pointer to a DLGTEMPLATE structure or a global memory segment handle to memory containing the structures.
Tracking Modeless Dialog Boxes
The memory-tracking technique in the preceding section is very simplistic and allows the user to create many instances of the modeless dialog box, which probably is undesirable. Also, none of the instances can be destroyed from any objects in your code, because the dialog box object is the only thing that knows where its memory is located.
A more likely scenario is that your document would track the modeless dialog box. To do this, you would add a member variable to your document to track the dialog box so that you can destroy it from the document, and send it messages to provide feedback from other elements of the user interface. You also should place a pointer back to the parent document so that you can inform the document of when the user closes the dialog box.
You could add a pointer to your CDocument-derived class to the modeless dialog box handler class, for example, and initialize it through the constructor like this:
CModeless::CModeless(CDialogTemplDoc* pParent)
: m_pParent(pParent)
{
Create(CModeless::IDD);
}
void CModeless::PostNcDestroy()
{
CDialog::PostNcDestroy();
m_pParent->m_pDlgModeless = NULL;
delete this;
}
You'll notice that the constructor also calls Create() so that the modeless dialog box is created and displayed when the object is constructed, thus simplifying the creation process from the calling object. The PostNcDestroy() function sets its pointer to the modeless dialog box equal to NULL, indicating that the dialog box is dead and gone.
The document then can track the modeless dialog box with its own member pointer and close it from a menu handler, as shown in these lines:
CDialogTemplDoc::CDialogTemplDoc() : m_pDlgModeless(NULL)
{
}
void CDialogTemplDoc::OnShowdialogDisplaymodeless()
{
if (!m_pDlgModeless) m_pDlgModeless = new CModeless(this);
}
void CDialogTemplDoc::OnShowdialogClosemodeless()
{
if (m_pDlgModeless) m_pDlgModeless->DestroyWindow();
}
This technique also lets you update the controls in the modeless dialog box from other application objects (such as a view to indicate the current mouse position) using dialog box member functions accessible through the document's pointer.
Only one instance of the modeless dialog box can be created at any one time, because the document menu handler function checks the pointer to see whether it already points to a modeless dialog box.
Dialog Bars
A dialog bar is a special form of modeless dialog box that encapsulates the functionality of a control bar (like a toolbar or status bar). This bar lets the modeless dialog box dock naturally to the window frames or float with a small frame.
You can create a dialog box template for a dialog bar like that for a normal modeless dialog box. The only difference is that you should set only the WS_CHILD (the Child setting in the Style combo box) and not the WS_VISIBLE flag (visible from the More Styles tab).
You then can construct the dialog bar using the MFC CDialogBar class (inherited from CControlbar) or your own derived class. The default constructor doesn't require any parameters. You normally would embed the CDialogBar object inside a frame window class, such as CMainFrame, as you might a toolbar or status bar.
After you construct the dialog bar, you can call its Create() function to create it. If you've embedded the dialog bar inside a frame window class, you probably will call the Create() function inside the frame's OnCreate() function, just like a toolbar.
The dialog bar's Create() function differs from a modeless dialog box's Create() function and is more like a control bar's Create(). The first parameter is a pointer to the parent window (normally a frame window). The second parameter is the ID of the dialog box template resource that you want to use for the dialog bar (or a resource name string). The third parameter lets you specify a docking/alignment style. This is just like a control bar style and can be a flag value such as CBRS_TOP, CBRS_LEFT, or CBRS_NOALIGN. You should supply an ID for the control bar as the last parameter to uniquely identify the dialog bar.
You can handle the control and messages of a dialog bar as you would a modeless dialog box. Dialog bars let you embed all the normal controls you can use on a dialog box template while letting you dock and reposition the bar like a toolbar.
Summary | Next Section

Account Sign In
View your cart