Tag Archives: CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);ASSERT(pWnd != NULL);

Solve the problem of destroying windows caused by multiple attchs of control classes in MFC. CWnd * pWnd = CWnd:: fromhandlepermanent (hWnd); ASSERT(pWnd != NULL); Assertion failure problem

Problem Description:

Recently, we are working on an MFC frame window (cframwwnd) program. The form program takes the dialog box project as the frame, and creates a frame window (cframwwnd) on this basis. There are no cdocument and CView in the frame window (cframwwnd), in which the member of CSplitterWnd class of separator bar is added, and the separation m is made in the frame window destruction function_ wndSpltter.Detach(); Then in C: \ program files (x86) \ Microsoft Visual Studio \ 2017 \ enterprise \ VC \ tools \ MSVC \ 14.16.27023 \ atlmfc \ SRC \ MFC \ wincore.cpp file:

1 CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
2 ASSERT(pWnd != NULL);

The problem of assertion failure.

 

Find the reason:

Because I didn’t know it was M_ wndSpltter.Detach(); report errors,

Refer to:

Deep parsing windows window creation and message distribution

https://www.cnblogs.com/findumars/p/6329614.html

After that, we have a clearer understanding. Because before debugging will often enter the MFC source code, the basic message pump frame there is a certain concept.

You must first find out which control the window handle that reported an error belongs to.

(Note: all controls in the window inherit from CWnd class)

 

resolvent:

1.. F5 debugging, after the error report pops up, click Retry to get the error handle, and query the handle in Spy + +.

2. Open Spy + +, find the window product of this program, and locate the window handle.

3. However, the CSplitterWnd window class member displays afxmdiframw140sud.

4. At this time, it is suspected that it is CSplitterWnd. Repeat steps 1 and 2 again, insert a breakpoint at the error code, and add the hWnd value of the member at cmyframe:: onclose(). This also allows you to edit breakpoint conditions:

(0x00580D40 == hWnd || hWnd == 0x002F1140 || hWnd == 0x00B81060) && nMsg == 0x2

Followed by the main window handle, CSplitterWnd, handle, and the child window handle with CSplitterWnd, 0x2 is WM_ Destroy message.

5. The handle after an error is reported. Compare it with the CSplitterWnd handle.

6. After finding the initiator, when debugging again, follow CWnd * pWnd = CWnd:: fromhandlepermanent (hWnd); Code, return null in lookuppermanent(). Obviously M_ This handle is missing from the permanentmap.

7. Let’s look at what detach() does, removehandle. All the reasons have been found. I did detach() more than once at onclose(). When I destroyed the window, I returned null when looking for the window handle.

8. Remove all other detaches and the program runs normally.