[Switch]
Obtain the pointer of each part of the vc mfc sdi/MDI framework
Source: China Talent Pool updated on: Views: 531 Previously summarized in csdn, once helped me sort out and summarize, hoping to help others.
| |
obtain cwinapp |
obtain cmainframe |
obtain cchildframe |
obtain cdocument |
obtain cview |
| In cwinapp |
|
afxgetmainwnd () m_pmainwnd |
afxgetmainwnd ()-> mdigetactive () afxgetmainwnd ()-> getactiveframe () |
SDI: afxgetmainwnd () -> getactiveview ()-> getdocument () MDI: afxgetmainwnd ()-> mdigetactive () -> getactiveview ()-> getdocument () |
SDI: afxgetmainwnd ()-> getactiveview () MDI: afxgetmainwnd () -> mdigetactive ()-> getactiveview () |
| In cmainframe |
afxgetapp () theapp |
|
mdigetactive () getactiveframe () |
SDI: getactiveview ()-> getdocument () MDI: mdigetactive () -> getactiveview ()-> getdocument () |
SDI: getactiveview () MDI: mdigetactive ()-> getactiveview () |
| In cchildframe |
afxgetapp () theapp |
getparentframe () |
|
getactiveview ()-> getdocument () |
getactiveview () |
| In cdocument |
afxgetapp () theapp |
afxgetmainwnd () |
afxgetmainwnd ()-> mdigetactive () afxgetmainwnd ()-> getactiveframe () |
|
position Pos = getfirstviewposition (); getnextview (POS) |
| In cview |
afxgetapp () theapp |
afxgetmainwnd () |
getparentframe () |
getdocument () |
|
| in other classes |
afxgetapp () |
afxgetmainwnd () |
afxgetmainwnd ()-> mdigetactive () afxgetmainwnd ()-> getactiveframe () |
SDI: afxgetmainwnd () -> getactiveview ()-> getdocument () MDI: afxgetmainwnd ()-> mdigetactive () -> getactiveview ()-> getdocument () |
SDI: afxgetmainwnd ()-> getactiveview () MDI: afxgetmainwnd () -> mdigetactive ()-> getactiveview () |
It is easy to understand the above messy logic by taking a look at the relationships between these classes of MFC. An app is an application domain, and everything in it can be accessed through global functions. Mainframe is the main framework and can be accessed using global functions. There are several childframes under mainframe, and several views and documents in childframe (which may not be paired). childframe manages views and documents for interoperability. Therefore, the overall framework comes out. Generally, except for the direct application relationship, you can access it through the line mainframe --> active childframe --> active View --> document. What should this be called from? The omnipotent method is ^_^.
Http://hi.baidu.com/blackfox1983/blog/item/2538071b3a4f66d0ad6e7583.html
The access between documents, views, and frameworks in MFC has been a common topic, but I don't think there are any detailed descriptions.
For those with poor English, I checked some blogs and summarized them! I hope it will be helpful to people like me!
I:
1: for SDIProgramThe main framework window is the document box window (if you do not know this, you need to check the composition of the single document under MFC ).
The following is a single document.
Example: how to obtain the View class pointer in the cmainframe framework.
You can get the framework pointer first, and then call the getactiveview function to point to the current activity view.
C ** view * pview;
Pview = (C ** view *) (cframewnd *) afxgetapp ()-> m_pmainwnd)-> getactiveview ();
Of course, this may be the case, but some people may not understand what the real m_pmainwnd and afxgetapp () mean.
You may know how to obtain the mainframe pointer (framework class) in the app: The m_pmainwnd variable in the cwinapp is the pointer of the cmainframe.
Therefore, in other classes, you can first get m_pmainwnd and get the mainframe pointer. to obtain the View class pointer, you must first obtain the cframewnd pointer m_pmainwnd, and then call getactiveview under framewnd to direct it to the current active view.
M_pmainwnd:
Each MFC application has a cwinapp derived class object. This object corresponds to the main thread of the program. The cwinapp class has a cwnd * m_pmainwnd member variable. This member variable records the main window of the application.
When you create an MFC application, m_pmainwnd is displayed in the initinstance virtual function.
The only exception is the single-document interface's MFC application. You cannot see this section in the initinstance function.CodeBecause it has been hidden in
Processshellcommand is in this function. Then you can draw a conclusion: as long as you create your own window class, you must assign the object of this class to m_pmainwnd.
This member can only be used in the C ** app class. So how can I use the cwnd type variable in the cwinapp class to get the pointer of the main frame window ??
The afxgetapp function can be used, because afxgetapp () obtains the cwinapp class object, and afxgetapp returns the cwinapp Object Pointer, which is the c ** app generated by MFC. the object defined in CPP (the pointer to the object theapp ).
Because you get the cwndapp member function or member variable in your own project, you must forcibly convert it to the class in your project to find the member function or variable.
Note: in a single document, the simplest way to obtain the pointer is
(C ** view *) cframewnd: getactiveview ())
2: Of course, you can also get the pointer of the document class in framewnd:
Cmydocument * pdoc;
Pdoc = (cmydocument *) (cframewnd *) afxgetapp ()-> m_pmainwnd)-> getactivedocument ();
3: You can see how to obtain the mainframe pointer in the view.
Cmainframe * pmain = (cmainframe *) afxgetapp ()-> m_pmainwnd;
Note: Obtain the main frame window class pointer from the View class: Use the function: cwnd: getparentframe () or afxgetmainwnd ().
Can achieve the goal. Getparentframe () works by searching in the parent window chain until cframewnd or its derived class is found and Its pointer is returned.
(Cmainframe *) cwnd: getparentframe ())
Or
(Cmainframe *) afxgetmainwnd ())
II:
Of course, for the MDI program, because the child window is the document box window, you must first use getactiveframe () to obtain the activity sub-frame window, and then obtain the activity view and document through this sub-window:
Cmdichildwnd * pchild = (cmdichildwnd *) (cframewnd *) afxgetapp ()-> m_pmainwnd )-
> Getactiveframe ();
Get activity View:
Cmyview * pview = (cmyview *) pchild-> getactiveview ();
Get activity documents:
Cmydocument * pdoc = pchild-> getactivedocument ();
Note: You can also use this method to obtain the view pointer in multiple documents.
// Obtain the activity sub-Framework Window
Cmdichildwnd * pchild = (cmdichildwnd *) getactiveframe ();
// Or:
Required ichildwnd * pchild = mdigetactive ();
// Obtain the activity view of the activity sub-frame window
Cmyview * pview = (cmyview *) pchild-> getactiveview ();
III:
1. Get the pointer of the document class from the View class
Before you reference a document class in a view class, use the following statement:
C * Doc * pdoc = (C * Doc *) getdocument ();
Then you can use the pdoc pointer to access the document class.
2. The cdocument class pointer for obtaining a View class from the document class provides two functions for locating the View class:
Getfirstviewposition () and getnextview ()
Note: The parameters in the getnextview () Brackets use the reference method, so the value may change after execution. getfirstviewposition () is used
Return
Return to the first view position (the returned value is not a view class pointer, but a position type value). getnextview () has two functions: return the pointer of the next View class and use reference
To change the value of the input position parameter. Obviously, in the test program, there is only one view class, so you only need to call these two functions once to get
The ctestview pointer is as follows (a position structure variable must be defined to assist in the operation ):
C * view * pview;
Position Pos = getfirstviewposition ();
Pview = getnextview (POS );
In this case, you can get the pointer pview of the c * View class. After a few statements are executed, the variable Pos = NULL, because there is no next View class, naturally there is no next View class
Position. however, these statements are too simple to have strong versatility and security features. As mentioned earlier, when you want to return a pointer to a specified class in multiple views, we need to traverse
A View class exists until the specified class is found. Checks whether a class Pointer Points to an instance of a class.
For example:
Pview-> iskindof (runtime_class (C * view ));
You can check whether pview refers to a C * View class.
With the above foundation, we can get any class pointer from the document class. For convenience, we use it as a member function of the document class. It has a parameter that indicates the class pointer to be obtained. The implementation is as follows:
Cview * C * DOC: getvieww (cruntimeclass * Pclass)
{Cview * pview;
Position Pos = getfirstviewposition ();
While (Pos! = NULL ){
Pview = getnextview (POS );
If (! Pview-> iskindof (Pclass ))
Break ;}
If (! Pview-> iskindof (Pclass )){
Afxmessagebox ("connt locate the view .");
Return NULL ;}
Return pview ;}
Two View class member functions iskindof () are used to determine whether to exit the while loop. There are three possible reasons:
1. If POS is null, no view class exists;
2. pview has met the requirements.
3.1 and 2 are the same. This is because the getnextview () function is to change the current view pointer to the position of a view and return the current view pointer, so POS is under the pview
The position of a view class may be both Pos = NULL and pview. When the required view is the last view and is the last view class, it is cited as follows. Therefore
Use two judgments.
Use this function in the following format (taking the ctestview pointer as an example ):
Ctestview * ptestview = (ctestview *) getview (runtime_class (ctestview ));
Runtime_class is a macro. It can be understood simply as a function of converting the class name to cruntimeclass as a pointer.
As for forced type conversion, it is also for the sake of security, because the pointer types from the same base class are mutually compatible. This forced type conversion may not be necessary, but it can avoid some possible troubles.