Relationships among documents, views, framework windows, and document templates

Source: Internet
Author: User


To understand the relationships between documents, views, framework windows, and document templates, you must understand their structure.
1. First Cwinapp Have a full understanding
It includes and manages applications Program .
It has a member variable cdocmanager * m_pdocmanager, which is the manager of the document/window.
M_templatelist is a list in cdocmanager. the pointer of all document templates is saved in this table.
When a user calls
After cwinapp: adddoctemplate (pdoctemplate), The pdoctemplate is saved to cwinapp: m_pdocmanager: m_templatelist.
Cwinapp: getfirstdoctemplateposition ()
Cwinapp: getnextdoctemplate (Position & Pos)
Is the template pointer of all documents in the example.
2. The document template ( Cmultidoctemplate (We mainly use documents )),
This is a very important class.
Cmultidoctemplate: m_doclist lists the pointers of all document instances of this type of document saved.
The following two functions are used to maintain cmultidoctemplate: m_doclist data
Cmultidoctemplate: adddocument (cdocument * pdoc );
Cmultidoctemplate: removedocument (cdocument * pdoc );
Cmultidoctemplate: getfirstdocposition () const;
Cmultidoctemplate: cdocument * getnextdoc (Position & rpos) const;
Used for all document instances of this document type.
3. The document mentioned above ( Cdocument )
Cdocument is the most familiar. Each document instance may correspond to multiple documents.
Cdocument: m_viewlist is used to save all views related to this document instance.
Cdocument: getdoctemplate to obtain cmultidoctemplate;
4, Cview
It is stored in javasichildwnd, and each javasichildwnd has a view
Cview: getdocument obtains the cdocument associated with this view.
Cview: getparentframe () to obtain javasichildwnd;

Through the above analysis, we can see that cwinapp, cmdichildwnd, cview, cdocument, and cmultidoctemplate must be aware of one of the instances. cwinapp leads the global architecture. At any time, you only need to obtain the cwinapp instance, all document templates, document instances, views, and frame windows can be enumerated. Afxgetapp () obtains the cwinapp instance pointer.

**************************************** **************************************** *******************************

1) Get the doc pointer in the view
2) obtain the mainframe pointer in the app
3) obtain the mainframe pointer in the view.
4) obtain the view (created) pointer
5) Get the pointer to the current document
6) Get the status bar and toolbar pointer
7) Get the status bar and toolbar Variables
8) obtain the menu pointer in mainframe.
9) obtain the application class from any class
10) Get the pointer of the View class from the document class (1)
11) Get the document template pointer in the app
12) obtain the document class pointer from the document template
13) Get the document template pointer in the document class
14) Get the pointer of the View class from the document class (2)
15) obtain the pointer of another view class from one view class
In VC programming, the biggest obstacle and problem for students who have just started learning is the message mechanism and pointer acquisition and operation. In fact, these contents are basically required for every VC learning tool book, and can be solved through many msdn problems. The following text mainly refers to some of my experiences in Pointer usage in programming. please correct me if it is inappropriate.
Generally, the framework we use is the MFC App Wizard (exe) Framework generated by Wizard provided by VC. There are pointer acquisition and Operation Problems in both multi-document and single-document. The following section describes the general framework and then the usage of pointers in multithreading. The class to be used must contain the response header file. First, we generally obtain the instance pointer this, which is supported by the class (view, document, and dialog box). The purpose of this is to send a pointer to other classes or functions through functions in the class, this allows you to operate and use functions in a non-class.

1) Get the doc pointer in the view
Cyousdidoc * pdoc = getdocument (); one view can only have one document.

2) obtain the mainframe pointer in the app
The m_pmainwnd variable in cwinapp is the mainframe pointer.
Alternatively, you can: cmainframe * pmain = (cmainframe *) afxgetmainwnd ();

3) obtain the mainframe pointer in the view.
Cmainframe * pmain = (cmaimframe *) afxgetapp ()-> m_pmainwnd;

4) obtain the view (created) pointer
Cyouview * pview = (cyouview *) pmain-> getactiveview ();

5) Get the pointer to the current document
Cdocument * pcurrentdoc = (cframewnd *) m_pmainwnd-> getactivedocument ();

6) Get the status bar and toolbar pointer
Cstatusbar * pstatusbar = (cstatusbar *) afxgetmainwnd ()-> getdescendantwindow (afx_idw_status_bar );
Ctoolbar * ptoolbar = (ctoolbar *) afxgetmainwnd ()-> getdescendantwindow (afx_idw_toolbar );

7) if you add the toolbar and status bar variables to the framework, you can do the same.
(Cmainframe *) getparent ()-> m_wndtoolbar;
(Cmainframe *) getparent ()-> m_wndstatusbar;

8) obtain the menu pointer cmenu * pmenu = m_pmainwnd-> getmenu () in mainframe ();

9) obtain the application class from any class
Obtain it using the global function afxgetapp () of MFC.

10) obtain the pointer of the View class from the document class
I learned from
The purpose of getting a View class pointer from a document is generally to control the positioning of multiple views in the same document. My experience is particularly true when the ceditview produces multiple view classes, this function is very required.
The cdocument class provides two functions for positioning the View class:
Getfirstviewposition () and getnextview ()
Virtual position getfirstviewposition () const;
Virtual cview * getnextview (Position & rposition) const;
Note: The parameters in the getnextview () Brackets use the reference method, so the value may change after execution.
Getfirstviewposition () is used to return the position of the first view (not a view pointer, but a position value). getnextview () has two functions: return the pointer of the next View class and use the reference call method to change the value of the input position type parameter. Obviously, there is only one view class in the test program. Therefore, you only need to call these two functions once to obtain the ctestview pointer as follows (you need to define a position structure variable to assist in the operation ):
Ctestview * ptestview;
Position Pos = getfirstviewposition ();
Ptestview = getnextview (POS );
In this way, you can access the ptestview pointer of the ctestview class. after executing a few sentences, the variable Pos = NULL, because there is no next View class, naturally there is no position for the next View class. 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 all view classes until the specified class is found. When judging whether a class Pointer Points to an instance of a class, you can use the iskindof () member function to perform a row check, for example:
Pview-> iskindof (runtime_class (ctestview ));
You can check whether pview refers to the ctestview 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 * ctestdoc: getview (cruntimeclass * Pclass)
Cview * pview;
Position Pos = getfirstviewposition ();
While (Pos! = NULL ){
Pview = getnextview (POS );
If (! Pview-> iskindof (Pclass ))
If (! Pview-> iskindof (Pclass )){
Afxmessagebox ("connt locate the view. \ r \ n ");
Return NULL;
Return pview;
Two View class member functions iskindof () are used to determine whether to exit the while loop.
1. If POS is null, no view class exists;
2. pview has met the requirements.
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. Therefore, POS is the position of the next View class of pview, it is possible that both Pos = NULL and pview meet the requirements. When the required view is the last view and is the last view class, it is cited as follows. Therefore, two judgments are required.
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.
3. Get the pointer of another view class from one view class
Combining 1 and 2, it is easy to obtain the method of getting pointers between view classes: it is to use the document class as a transit, first use the 1 method to get the pointer of the document class, and then use the 2 method, use the view locating function of the document class to obtain another view class. Similarly, you can implement a function:
(Assume that you want to obtain a pointer to other view classes from ctestaview)
Cview * ctestaview: getview (cruntimeclass * Pclass)
Ctestdoc * pdoc = (ctestdoc *) getdocument ();
Cview * pview;
Position Pos = pdoc-> getfirstviewposition ();
While (Pos! = NULL ){
Pview = pdoc-> getnextview (POS );
If (! Pview-> iskindof (Pclass ))
If (! Pview-> iskindof (Pclass )){
Afxmessagebox ("connt locate the view .");
Return NULL;
Return pview;
Compared with getview () in 2, this function adds the first sentence to get the document class pointer, and adds the document class pointer before getfirstviewposition () and getnextview, to indicate that they are document class member functions. With this function, to obtain the ctestbview pointer from ctestaview, you only need:
Ctestbview * ptestbview = (ctestview *) getview (runtime_class (ctestbview ));

11) multiple document templates can also be added to a single document. However, in general development, multiple document templates can be developed using the MDI method. The method is very similar to the method for obtaining the preceding view, I will explain it here. If it is unclear,
Please refer to msdn (the following four content (11, 12, 13, 14) Source:
You can use cwinapp: getfirstdoctemplatepostion to obtain the location of the first document template registered by the application. Use this value to call the cwinapp: getnextdoctemplate function to obtain the pointer of the first cdoctemplate object.
Position getfirstdoctemplate () const;
Cdoctemplate * getnextdoctemplate (Position & Pos) const;
The second function returns the document template identified by the POS. Position is a value defined by MFC for iteration or object pointer retrieval. With these two functions, the application can traverse the entire document template list. If
The document template is the last in the template list, and the POs parameter is set to null.

12) A document template can have multiple documents. Each document template retains and maintains a pointer list for all corresponding documents.
Use the cdoctemplate: getfirstdocposition function to obtain the position of the first document in the document set related to the document template, and use the position value as the cdoctemplate :: getnextdoc parameters are used to repeatedly traverse the list of template-related documents. Function prototype:
Viaual position getfirstdocposition () const = 0;
Visual cdocument * getnextdoc (Position & rpos) const = 0;
If the list is empty, rpos is set to null.

13) in this document, you can call cdocument: getdoctemplate to obtain the pointer to this document template.
The original function is as follows:
Cdoctemplate * getdoctemplate () const;
If the document does not belong to document template management, the return value is null.

14) a document can have multiple views. Each document retains and maintains a list of all associated views.
Cdocument: addview connects a View to the document, adds the view to the list of associated views of the document, and points the document pointer to the document.
When a file/New, file/open, Windows/new, or window/split command connects a newly created object to the document, MFC automatically calls this function, the framework associates the document with the view through the document/view structure. Of course, programmers can also call this function according to their own needs.
Virtual position getfirstviewposition () const;
Virtual cview * getnextview (Position & rposition) cosnt;
The application can call cdocument: getfirstviewposition to return the location of the first view in the list of views associated with the call document, call cdocument: getnextview to return the view at the specified position, and set
The value of rpositon is set to the position value of the next view in the list. If the result is regarded as the last view in the list, the rposition is set to null.

15) obtain the pointer of another view class from one view class
This application is widely seen in multi-view applications. Generally, if you do a variable mark in the main program or the main framework, you can also get it. What is more common is to use the document class as a transit, traverse and locate the view of the document class to obtain another view class. This function can be obtained from the 10th items in this article.


VC multi-document program structure [transfer]

1. Relationship between templates, documents, views, and frameworks

Serialization 1 ~ 5. We have explained documents, document templates, views, and framework categories individually. serialization 1 has emphasized that these classes have close internal relationships. Conclusion 1 ~ 5. We can summarize the contact information as follows:

(1) The document retains the View list of the document and the pointer to the document template that created the document. The document has at least one associated view, and the view can only be associated with one document.

(2) The view retains the pointer to its document and is contained in its parent frame window;

(3) The document Framework Window (I .e. the MDI child window containing the view) retains the pointer pointing to its current active view;

(4) The document template retains the list of open documents and maintains the ing of framework windows, documents, and views;

(5) The application retains the list of its document templates.

We can use a group of functions to make these classes accessible to each other. Table 6-1 lists these functions.

Table 6-1 mutual access between documents, document templates, views, and framework classes

Call the global function afxgetapp to obtain the cwinapp application class pointer.
Use afxgetapp ()-> m_pmainwnd as the frame window pointer;
Use cwinapp: getfirstdoctemplatepostion and cwinapp: getnextdoctemplate to traverse all document template documents.
Call cdocument: getfirstviewposition, cdocument: getnextview to traverse all views associated with the document;
Call cdocument: getdoctemplate to obtain the document template pointer Document Template
Call cdoctemplate: getfirstdocposition and cdoctemplate: getnextdoc to traverse all corresponding document views.
Call cview: getdocument to get the corresponding document pointer;
Call cview: getparentframe to obtain the Framework Window documentation Framework Window.
Call cframewnd: getactiveview to obtain the current active view pointer;
Call cframewnd: getactivedocument to obtain the document pointer appended to the current view
The MDI Framework Window calls cmdiframewnd: mdigetactive to obtain the currently active MDI subwindow (cmdichildwnd)

Let's take an example to describe how to use the functions in the above table.CodeWhich provides the ability to traverse document templates, documents, and views:

Cmyapp * pmyapp = (cmyapp *) afxgetapp (); // get the application pointer
Position P = pmyapp-> getfirstdoctemplateposition (); // get 1st document templates
While (P! = NULL) // traverse the Document Template
Cdoctemplate * pdoctemplate = pmyapp-> getnextdoctemplate (P );
Position p1 = pdoctemplate-> getfirstdocposition (); // obtain the 1st documents corresponding to the document template.
While (P1! = NULL) // traverse the document corresponding to the Document Template
Cdocument * pdocument = pdoctemplate-> getnextdoc (P1 );
Position P2 = pdocument-> getfirstviewposition (); // obtain the 1st views corresponding to the document.
While (P2! = NULL) // traverse the view corresponding to the document
Cview * pview = pdocument-> getnextview (P2 );
It can be seen that the following management relationships and implementation approaches are completely similar:

(1) apply to document templates;

(2) The document template is for the document;

(3) view the document.

××××××××××××××××××××××××××××××××××××××××××× ×

1. The application object has a document template manager cdocmanager * m_pdocmanager (New when adddoctemplate is called for the first time)

2. The document template manager has a list of document template objects cptrlist m_templatelist (the adddoctemplate function is responsible for adding this list)

3. The document template object has a static cruntimeclass member pointer of the document, view, and framework for dynamic creation, and a m_nidresource is used to represent the UI object to be used.

4. Each document template object has m_ponlydoc or m_doclist (document pointer or document pointer list), onfilenew and onfileopen call opendocumentfile of the document template object, and opendocumentfile call createnewdocument of the document template, createnewdocument then calls adddocument of the document template to fill the document list or document pointer

5. The document object has a document template pointer m_pdoctemplate (back to the template object of the Document Object ). same as above, it is also the adddocument member function of the document template to set this pointer (the document template itself ). plug the file object you just created

6. The document object has a m_viewlist (View list). Both onfilenew and onfileopen call opendocumentfile of the document template object. This function calls createnewdocument to create the document and then call createnewframe to create the framework object.

Createnewframe: Construct a ccreatecontext object
Ccreatecontext: (1) newly created document pointer (2) cruntimeclass pointer of the View
After createnewframe creates a framework object, it calls loadframe.
The last parameter of loadframe is the ccreatecontext pointer.

Loadframe calls create, create and then createex. The last parameter is the ccreatecontext pointer.
The call to create is triggered by the message ing table. cframewnd: oncreate is called.
One of the fields of the oncreate lpcreatestruct is still the ccreatecontext pointer.

Then, in cframe: oncreate, The cruntimeclass (view) of the ccreatecontext calls Createobject.
After a view object is generated, the object calls create (the last parameter is still the ccreatecontext pointer)

Create of view object is called oncreate of view object caused by message ing table
The value of the oncreate parameter of the view is the lpcreateparams of the lpcreatestruct or the ccreatecontext pointer)
Therefore, use the ccreatecontext member m_pcurrentdoc (current document)
To call cdocument: addview to add the view to the View list of the document.

7. The view has a document pointer m_pdocument (pointing to the document)
Same as above, it is also initialized by the cdocument: addview function, as shown below:
Pview-> m_pdocument = this;

8. The framework has a m_pviewactive (activity view)
Set by setactiveview of the framework

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: 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.