Destruction of windows in VC

Source: Internet
Author: User

http://blog.csdn.net/oldmtn/article/details/6904697

The basics are important, window handles in Win32 and 2 Concepts for MFC window class objects. The former was wrapped up by the latter.

First look at the article in TN017 in MSDN

In the case of C + + Windows objects that does perform auto-cleanup, you must callDestroyWindow. If You use operator Delete directly, the MFC diagnostic memory allocator would alert you is freeing memo Ry twice (the first call todelete as well as the indirect call to "DeleteThis" in the Auto-cleanup Impl Ementation ofPostNcDestroy).

What does that mean?

If we have a window class Cmywnd:public CWnd {};

Cmywnd * M_PMYWND;

M_pmywnd = new Cmywnd;

What do we do if we want to delete the window?

Law One:

[CPP]View Plaincopyprint?
    1. M_pmywnd->destroywindow ();
    2. Delete M_pmywnd;
    3. M_pmywnd = NULL;
M_pmywnd->destroywindow ();d elete M_pmywnd;m_pmywnd = NULL;
Law II: [CPP]View Plaincopyprint?
    1. M_pmywnd->destoywindow ();
    2. M_pmywnd = NULL;
M_pmywnd->destoywindow (); m_pmywnd = NULL;
someone might ask, why is the second sentence missing? Oh, actually no less, just I changed a place. Please look. [CPP]View Plaincopyprint?
    1. void Cmywnd::P Ostncdestroy ()
    2. {
    3. //cwnd::P Ostncdestroy ();
    4. Delete this ;
    5. }
void Cmywnd::P Ostncdestroy () {//cwnd::P Ostncdestroy ();d elete this;}
I do not use the default processing here, because when a Windows window is cleared, the last message sent to the window is Wm_ncdestroy. In the handler function for this message, I delete the Window object itself.

In fact, we can also use

Fahsarm

[CPP]View Plaincopyprint?
    1. Delete M_pmywnd;
    2. M_pmywnd = NULL;
Delete M_pmywnd;m_pmywnd = NULL;

How do you say that? In fact, I do this is still a conversion work. Just add the following code [CPP]View Plaincopyprint?
    1. Cmywnd::~cmywnd ()
    2. {
    3. DestroyWindow ();
    4. }
Cmywnd::~cmywnd () {DestroyWindow ();}
The Windows window object associated with the window is deleted in the destructor.

Specific how to apply, you crossing to decide ...

Here is an article on the Internet, you are interested to see . But the TN017 on MSDN is very important!!!

A window consists of two parts: the window Resource HWND and the Window object CWnd, destroyed when the resource HWND is first disposed, and then the object CWnd is destroyed.

For example:

The custom dialog box type CMyDlg, when used, allocates a new dialog object on the heap with new, which is assigned a Window object when the object calls CWnd::Create (). You should first use CWnd when destroying::D Estroywindow () or::D Estroywindow (HWND hwnd) to destroy the resource, and then use delete Pdlg to delete the space allocated for the dialog box on the heap. However, because of CWnd::D Estroywindow () and::D Estroywindow (HWND hwnd) will call CWnd PostNcDestroy () at the end, so we can also PostNcDestroy () Call Delete this to delete the allocated space on the heap. So you don't have to display the use of delete Pdlg

Example:

Create window: Ctestdlg *pdlg=new ctestdlg ();
Pdlg->create (Idd_dlg,this);
Pdlg->showwindow (Sw_show);

Destroyed:

Pdlg->destroywindow (); Or::D Estroywindow (Pdlg->m_hwnd);

Delete Pdlg;

Or

                          void Ctestdlg::P Ostncdestroy ()
                           {
                                CDialog::P Ostncdestroy ();
                                  Delete this;
                         }

In this way, when destroying, only Pdlg->destroywindow () is required; Or::D Estroywindow (Pdlg->m_hwnd);

Resources:

consider a single window case:

Assume that you created a Window object PWND by using new, and then Pwnd->create. The call order of the window is destroyed:

1. Call Pwnd->destroywindow manually ();

2. DestroyWindow will send Wm_destroy;

3. Wm_destroy corresponding message processing function is OnDestroy ();

4. DestroyWindow will send Wm_ncdestroy;

5. Wm_ncdestroy corresponding message processing function is OnNcDestroy;

6. OnNcDestroy will finally call PostNcDestroy;

7. PostNcDestroy is often overloaded by the user to provide free memory operations. For example, you can use delete this;

In this way, the Window object and the Window object itself are freed.

If a child window is included:

If you have a child window, when you call the parent window's DestroyWindow, it sends the Wm_destroy and Wm_ncdestroy messages to the child window.

The specific invocation sequence refers to the following example.

   DestroyWindow effect on Delete:

It should be said that the former has no effect on the latter. But often the DestroyWindow indirectly causes the execution of the PostNcDestroy in the Delete window object pointer, which is the delete this.

CView: The only action in:P Ostncdestroy is delete this;cframewnd::P ostncdestory. The default CWnd::P Ostncdestroy is an empty operation, nor is it overloaded in CDialog, which is also empty.

   the effect of Delete on destroy:

Delete causes a destructor. CWnd's destructor has a call to DestroyWindow, but it must be guaranteed:

M_hwnd! = NULL &&

This! = (cwnd*) &wndtop &&this! = (cwnd*) &wndbottom &&

This! = (cwnd*) &wndtopmost &&this! = (cwnd*) &wndnotopmost.

The CDialog destructor also has a call to DestroyWindow, but the condition is relatively loose and requires only m_hwnd! = NULL. Additionally CDialog: The DestroyWindow is also called by the:D Omodal.

DestroyWindow is called in the OnClose of CFrameWnd, but DestroyWindow is not invoked in its destruction.

The CView of the DestroyWindow is not called by the destructor.

the destruction process of an SDI program

There are CMainFrame class, CMyView class. And CMyView has two sub-Windows CMyDlg and Cmywnd instances.
Click the Exit button and CMainFrame will receive the WM_CLOSE message. CFrameWnd (the parent class of CMainFrame) invokes CWnd indirectly::D Estroywindow; it first sends Wm_destory and WM_NCDESTROY messages to CMyView and throws the corresponding handler functions Then send the wm_destory and Wm_ncdestroy messages to the CMyDlg and throw the corresponding handler functions, then send wm_destory and Wm_ncdestroy messages to Cmywnd and throw the corresponding handler functions.

The specific order of execution is:

1. Call CMainFrame::D Estroywindow

2. Cframewnd::ondestroy

3. Cmyview::ondestroy

4. Cmywnd::ondestroy

5. Cmydlg::ondestroy

6. Cmywnd::P Ostncdestroy

7. Destruction of Cmywnd

8. Cmydlg::ondestroy

9. Destruction of CMyDlg

CMyView::P Ostncdestroy

The destruction of CMyView

The destruction of CMainFrame

CMainFrame::D Estroywindow exit

The above scenario assumes that we have added delete this in the PostNcDestroy of Cmywnd and CMyDlg. If not added, then 7, 9 will not be executed.

Because CView: Delete This is called in the:P Ostncdestroy, then the CMyView destructor is executed. Because CFrameWnd: Delete This is called in the:P Ostncdestroy, the destructor of the CMainFrame is executed last.

If your own CMyDlg and Cmywnd have delete this in PostNcDestroy, the two will be refactored. Otherwise, the memory leaks. Of course, delete can also be placed in the cmyview of the destruction to do, just not enough oo.

Summarize

There are two ways to destroy window objects corresponding to Windows and to release window object pointers. One is through DestroyWindow. This is a good approach, because eventually MFC will automatically respond WM_CLOSE cause Cframwnd::D Estroywindow is called, and then the handle of all child windows is released at once. What the user needs to do is release the heap window object pointer in PostNcDestroy. However, because some objects are requested in the stack, delete this can be an error. This ensures that the windows that you create when you write the program use heap requests as much as possible.

The other is delete. Delete a Window object pointer. Some window classes (such as Cwnd,cdialog) call DestroyWindow indirectly, and some window classes (such as Cview,cframewnd) do not call DestroyWindow. So be careful.

The two are called each other and are cumbersome.

   a Good article: (Shiyang)

An MFC Window object consists of two aspects: the Window object encapsulated by the window, the hwnd stored in the M_hwnd Member (window handle), and the Window object itself being a C + + object. To delete an MFC window object, you should first delete the Window object that encapsulates the window, and then delete the Window object itself.

The most straightforward way to delete a window is to call CWnd::D Estroywindow or::D Estroywindow, which encapsulates the latter's functionality. The former will not only invoke the latter, but also invalidate the HWND of the member M_hwnd (NULL). If DestroyWindow deletes a parent window or owner window, the function automatically deletes all child windows or owners before deleting the parent window or owner. In general, you do not have to call DestroyWindow directly in your program to delete a window, because MFC automatically calls DestroyWindow to delete the window. For example, when a user exits an application, a WM_CLOSE message is generated that causes MFC to automatically invoke CWnd::D Estroywindow to delete the main frame window, and when the user presses the OK or Cancel button within the dialog box, MFC automatically calls CWnd::D Estroywindow to delete the dialog box and its controls.

The deletion of the Window object itself is divided into two situations, depending on how the object is created. In MFC programming, a large number of window objects are used, some window objects are embedded in other objects as variables or created on the stack as local variables, and some are created in the heap with the new operator. For aA Window object created as a variable, the programmer does not have to care about its delete problem, because the object's lifetime is always limited, ifThe object is a member variable of an object that disappears as the parent object disappears, and if the object is a local variable, it is cleared when the function returns.

For a window object that is dynamically created in the heap, its lifetime is arbitrarily long. When beginners learn C + + programming, the use of the new operator is often less practical, because creating objects in the heap with new does not forget to delete objects with delete. As readers learn about MFC's routines, they may have questions about why some programs create a Window object with new, but do not explicitly delete it with delete? The answer to this question is that some MFC window objects have the ability to purge automatically.

As mentioned in the previous non-modal dialog box, when you call CWnd::D Estroywindow or::D estroywindow Delete A window, the PostNcDestroy member function of the deleted window is called. The default PostNcDestroy does nothing, but some MFC window classes overwrite the function and call Delete this in the new version of PostNcDestroy to remove the object, which has the ability to purge automatically. Such window objects are usually created in the heap with the new operator, but programmers do not have to worry about deleting them with the delete operator, as the corresponding window object will be deleted immediately after the DestroyWindow delete window is called.

window classes that do not have the automatic cleanup feature are shown below. These window objects are usually created as variables without the ability to automatically clear them.

All standard Windows control classes.

1. Child window objects derived directly from the CWnd class (such as user-customized controls).

2. Splitting the window class CSplitterWnd.

3. The default control bar class (including toolbars, status bars, and dialog bars).

4. modal dialog box class.


1. The main frame window class (derived directly or indirectly from the CFrameWnd class). &NBSP

2. View class (derived directly or indirectly from the CView Class).

When you design your own derived window class, you can determine whether the window class is designed to be automatically cleared, depending on how the Window object is created. For example, for a non-modal dialog box, its object is created in the heap, so it should have automatic cleanup capability. &NBSP

in summary, for MFC window classes and their derived classes, it is generally not necessary to explicitly delete a Window object in a program. That is, you do not have to call DestroyWindow to delete Window object encapsulation windows, and you do not have to explicitly delete the Window object itself with the delete operator. As long as the window object that is not automatically cleared is created as a variable, the window object that is automatically cleared is created in the heap, and MFC's operating mechanism ensures that the window object is completely deleted. &NBSP

If you need to delete the Window object manually, you should first call the appropriate function (such as CWnd::D Estroywindow) to delete the window and then delete the Window object. For a window object created as a variable, the deletion of the Window object is automatically done by the framework. For a window object that is dynamically created in the heap that is not automatically purged, you must explicitly call delete after the window is deleted to delete the object (typically in the owner or parent window's destructor). For window objects with automatic cleanup, you can simply call CWnd::D Estroywindow to delete window and Window objects. Note that for window objects created in the heap, do not delete the Window object with the delete operator if the window is not closed

Destruction of windows in VC

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.