Use MFC to dynamically create a new window during running

Source: Internet
Author: User
Tags protected constructor
Use MFC to dynamically create a new window at runtime Author: Zheng Yong Release Date: 2001/03/23
 
Abstr:

This article introduces a way to dynamically create a new window while using the MFC class library in the Visual C ++ 6.0 programming environment. This method uses the framework class of MFC, so the new window has its own menu bar, toolbar, and status bar.
Key words: MFC, Visual C ++, window, framework

Body:  


Use MFC to dynamically create a new window during running

When running a program, you often need to use a dialog box to give certain prompts or receive user feedback. However, in a few cases, just using the dialog box is not enough. You may need to bring up a new window that contains your menu bar, dialog box, and status bar. Of course, you can add menu bar, dialog box, and status bar to the dialog box, this is technically feasible, but why not directly create a new window? This article provides a method under MFC.
We know that in Windows programming, creating a new window involves two steps:
(1) register the corresponding windows window class;
(2) generate a window based on the registered window class.
However, if we want to use the features of C ++ and MFC in MFC, we 'd better use the ready-made MFC class to inherit from it and transform it to add the necessary elements.
The following is an example. A rectangle is displayed in the main window. When you click in the main window, a new window containing the editing control is displayed. Note that you can create multiple new windows. When the main window is closed, all new windows are closed.
         
                           
Step 1: Create an SDI project test.
 
Edit the ctestview: ondraw function and draw a rectangle in the customer area:
Void ctestview: ondraw (CDC * PDC)
{
Ctestdoc * pdoc = getdocument ();
Assert_valid (pdoc );
// Todo: Add draw code for native data here

// Draw a rectangle in Client
PDC-> rectangle (50, 50,200,200 );
PDC-> textout (10, 10, "click the left mouse button in the window to create a new window ");
}
                                                   
              

Step 2: Use classwizard to inherit the cnewframe class of the new window from cframewnd:

Resources in resources:

       
   

For simplicity, the toolbar still uses the toolbar and status bar of the main window.

Insert the declaration of the toolbar and the status bar object in the class declaration of cnewframe. h:
Protected: // control bar embedded members
Cstatusbar m_wndstatusbar;
Ctoolbar m_wndtoolbar;

In the cnewframe response wm_create message, load the toolbar and status bar in cnewframe: oncreate:
Int cnewframe: oncreate (maid)
{
If (cframewnd: oncreate (lpcreatestruct) =-1)
Return-1;

// Todo: add your specialized creation code here

If (! M_wndtoolbar.createex (this, tbstyle_flat, ws_child | ws_visible | cbrs_top
| Cbrs_gripper | cbrs_tooltips | cbrs_flyby | cbrs_size_dynamic) |
! M_wndtoolbar.loadtoolbar (idr_mainframe ))
// For simplicity, the toolbar of the main window is still loaded
// You can also load your own Toolbar
{
Trace0 ("failed to create toolbarn ");
Return-1; // fail to create
}

If (! M_wndstatusbar.create (this) |
! M_wndstatusbar.setindicators (indicators,
Sizeof (indicators)/sizeof (uint )))
{
Trace0 ("failed to create status Barn ");
Return-1; // fail to create
}

// Todo: delete these three lines if you don't want the toolbar
// Be dockable
M_wndtoolbar.enabledocking (cbrs_align_any );
Enabledocking (cbrs_align_any );
Dockcontrolbar (& m_wndtoolbar );

Static int s_nnewframeid = 0;
S_nnewframeid ++;
Cstring STR;
Str. Format ("new window No. % d", s_nnewframeid );
Setwindowtext (STR); // set the title of the new window
Return 0;
}

Step 3: Process Window destruction. If we can ensure that only one new window is created, this step can be skipped without additional code. However, it is often useful to create multiple windows, each window is independent of each other. The window destruction problem becomes very complicated.

    
We know that the destruction of window classes in MFC includes two aspects: the destruction of windows, and the analysis of window classes. Because cnewframe inherits from cframewnd, the latter has the delete this statement in its virtual function postncdestroy, as shown below:
Void cframewnd: postncdestroy ()
{
// Default for frame windows is to allocate them on the heap
// The default post-cleanup is to 'delete this '.
// Never explicitly call 'delete' on a cframewnd, use destroywindow instead
Delete this;
}
It indicates that cframewnd and its subclasses must be created on the stack. If we strictly create a new window, close it, and then create and close it, everything will work normally. If we create multiple windows and then close the main window, as the program exits, all new windows will be closed, but memory leakage will occur at this time, because we did not destroy the new windows one by one when exiting, so the delete this in postncdestroy is not executed.
The solution is to save all new window pointers in the main window program. We use the list to save all pointers. Add the following in ctestapp. h:
# Include "afxtempl. H" // description of the clist header file
# Include "newframe. H" // header file of the new window
Add members to the ctestapp class:
Public:
Clist <cnewframe *, cnewframe *> m_listframe; // save all new window pointers
When closing a new window, you should delete the pointer of the window from the pointer list:
Void cnewframe: postncdestroy ()
{
// Todo: add your specialized code here and/or call the base class

// Because cframewnd: postncdestroy () will delete this
// Won't set the pointer to this frame (pframe) to null, thus
// This will cause the cmsgsmanagerapp: exitinstance ()
// Delete the pointer again, and this will cause one exception
// So we must travel the list frame to set the point to null
// Or delete it

Ctestapp * PAPP = (ctestapp *) afxgetapp ();
Position Pos = PAPP-> m_listframe.find (this );
If (POS)
PAPP-> m_listframe.removeat (POS );

Cframewnd: postncdestroy ();
}
If you exit the main program directly without closing the new window, you should traverse the list and destroy the windows one by one:
Int ctestapp: exitinstance ()
{
// Todo: add your specialized code here and/or call the base class
Cnewframe * pframe;

// If a window is not closed when you exit the program, traverse the window linked list
// And close every frame of the listframe
Trace ("Count = % DN", m_listframe.getcount ());
While (! M_listframe.isempty ()){
Pframe = m_listframe.removehead ();
If (pframe-> getsafehwnd ()){
Trace ("Count = % DN", m_listframe.getcount ());
Pframe-> destroywindow ();
// We need not delete pframe
// Because pframe inherit the cframewnd
// And the virtual method postncdestroy of cframewnd
// Will delete this
}
}

Return cwinapp: exitinstance ();
}
Step 4: Create a new window.
First, change the attribute of the cnewframe constructor and destructor to public:
Public: // protected:
Cnewframe (); // protected constructor used by Dynamic Creation
Virtual ~ Cnewframe ();
Change the ctestdoc constructor to public:
Public: // protected: // create from serialization only
Ctestdoc ();
Then, create a window in the Response Function by clicking the left mouse button:
Void ctestview: onlbuttondown (uint nflags, cpoint point)
{
// Todo: add your message handler code here and/or call default

Cnewframe * pframe = new cnewframe;
Ccreatecontext context;
Ctestdoc * pmsgsmanagerdoc = new ctestdoc;
Context. m_pcurrentdoc = pmsgsmanagerdoc; // getdocument ();
Context. m_pnewviewclass = runtime_class (ceditview );

Pframe-> loadframe (idr_newframe, ws_overlappedwindow | fws_addtotitle,
Null, & context );
Pframe-> showwindow (true );

// This is import !!!
Ctestapp * PAPP = (ctestapp *) afxgetapp ();
PAPP-> m_listframe.addtail (pframe );
Trace ("Count = % DN", Papp-> m_listframe.getcount ());

Position Pos = pmsgsmanagerdoc-> getfirstviewposition ();
Ceditview * pview = (ceditview *) pmsgsmanagerdoc-> getnextview (POS );
Assert (pview );
Pview-> geteditctrl (). setwindowtext ("new window example. ");
}
Note:
(1) After a new window is created, it must be added to the window pointer list.
(2) Use getfirstviewposition and getnextview to obtain the view object pointer in the new window, so that you can use the document/framework/View Structure for further operations.


Program running interface:

                     
This document provides a simple example where you can insert your own toolbar and status bar and corresponding message functions. I hope this article will help you.

Member name of the author: a dang

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.