1 Introduction
In Microsoft Vc ++ 6.0, MFC-based applications are generally divided into the following types: Multi-Document Interface (MDI ),
Single Document Interface (SDI) and dialog box-based applications. One document can be divided into one view and multiple views,
Generally, a single document only requires a single view, such as a notepad and drawing program that comes with windows. However
In some cases, a single document requires multi-view support. For example, you can observe different parts of the document at the same time from different perspectives.
Observe the same document.
In the framework of MFC, the Document Object (cdocument) has a list of all its views, and provides
Adds the addview and removeview functions, and notifies users of changes to the document content.
Updateallviews ). The multi-document Framework's window replication mechanism and the single-document Framework's split window
The port mechanism is the main method to implement multiple views of a single document.
2. Multiple Views of a single document
Generally, there are three scenarios for a single document and multiple views:
(1) In the multi-Document Interface (MDI), each view is located in an independent sub-document Framework of MDI, And the view object Base
In the same view class. You can use the "window | new window" menu to create a window for the view of the same document,
In the newly created window, you can edit and observe another part of the document. Each view of the same document is automatically synchronized,
The user modifies the content of a view and automatically updates it in another view.
The MFC framework implements the above functions by copying the original sub-Framework Window and the view.
Dynamic.
(2) view objects are based on the same view class. All views are located in the same document framework.
Split Window splits the views of a single document window into several independent views. The framework creates multiple views from the same view class.
Graph object. Word subwindows belong to this type.
(3) view objects are based on different view classes. All views are in the same document framework.
Multiple Views share the same document framework, but they are created from different view classes. Each view can provide different
Observe and edit methods. For example, you can observe different parts of a document in a window, or use the unnecessary type in a window.
View to observe the same document. The implementation method of this type is to reload the member functions of the framework class cmainframe.
Oncreateclient implementation. You can divide the window into multiple vertical or horizontal split Windows based on different needs.
The following describes how to implement multi-view window splitting and multi-view communication in a single document through instance design.
3 Split Window
1. Divide the window into three views. The left view is based on the cview class and can be used as a ry. The top right view is based on
In the ceditview class, used to display text messages. The lower right view is based on the cformview class.
In this box and the send and clear buttons, the send button is used to send messages to the upper-right view.
Figure 1 design style
Open Microsoft Vc ++ 6.0 and use MFC Appwizard (exe) to create a single document (SDI) named splitwnd)
Project. All options are set by default when you create a project.
After the project is created, the csplitwndview class in the project is taken as the class corresponding to the Left view (implementation of this class ).
It has nothing to do with the focus of this Article. If you are interested, you can contact the author.
View class. Therefore, you must manually create the class corresponding to the upper right view and lower right view. You can use the MFC Wizard
Add two MFC classes (menu "insert | new class>"). Because the upper right view is used to display text, the base class is selected.
Ceditview, the class name is clefttopview; the base class of the other MFC class is cformview, and the class name is
Cleftbttmview, which corresponds to the lower-right view (because this class is based on the cformview class, a dialog box and
Therefore, you should first create a dialog box in the resource, control 1 in the dialog box ).
After adding the class, write the code. First, add the csplitterwnd object in the cmainframe class declaration.
Statement:
Class cmainframe: Public cframewnd {
>
Csplitterwnd m_wndsplitter; // split the view into left and right
Csplitterwnd m_wndsplitterright; // split the right view into top and bottom
>>}
Reload the oncreateclient function of the cmainframe class and add the following code to split the window:
Bool cmainframe: oncreateclient (> ){
// Split the window into 1> 2, that is, two columns.
M_wndsplitter.createstatic (this, 1, 2,
Ws_child | ws_visible | ws_border );
// Split the 2nd columns of the window into 2> 1
M_wndsplitterright.createstatic (& m_wndsplitter, 2, 1,
Ws_child | ws_visible, m_wndsplitter.idfromrowcol (0, 1 ));
// The following is the view class corresponding to the split window.
M_wndsplitter.createview (0, 0, runtime_class (csplitwndview ),
Csize (600,100), pcontext );
M_wndsplitterright.createview (0, 0, runtime_class (clefttopview ),
Csize (10,500), pcontext );
M_wndsplitterright.createview (1, 0, runtime_class (cleftbttmview ),
Csize (10, 10), pcontext );
>}
Call createstatic (cwnd * pparentwnd, int nrows, int ncols,
DWORD dwstyle = ws_child | ws_visible, uint nid = afx_idw_pane_first) member
The function is used to create and initialize a static split window. The pparentwnd parameter is used to identify the split parent window, nrows, and ncols.
Indicates the number of rows and columns, that is, the number of rows divided into pparentwnd in the parent window. dwstyle is used to identify the style of the split window.
NID refers to the Child window in which the parent window pparentwnd is split. Therefore, the m_wndsplitter function is called.
When createstatic is used, the entire window is split into one row, two columns (left and right), two views: 0th rows, and 0 columns (Left view ),
Then, call the createview function to set the class csplittertestview of the view. For the first column of row 0th, call the object
M_wndsplitterright function createstatic, split it into two rows and one column (up and down) Two views.
The parent window is m_wndsplitter and the NID is m_wndsplitter.idfromrowcol (0, 1), because m_wndsplitter
There are two windows left and right, and the column to be split is 0th rows and one column. Then, call the createview function to set the class of the view.
4. Communication between views
Communication between Views refers to the transmission of data between views. In this example, click the send button in the lower-right view.
Send the text in the text box to the upper-right view and display it in the upper-right view to transfer data between the two views.
In the cleftbttmview class, add the onsendmsg function corresponding to the send button. The function is to set
The Code is as follows:
Void cleftbttmview: onsendmsg (){
Updatedata (); // update the control variable data. The variable corresponding to the text box is m_stext.
// Use the m_wndsplitterright variable in the cmainframe class to obtain the class pointer of the upper right view.
Cmainframe * pmainfrm = (cmainframe *) afxgetapp ()-> getmainwnd ();
Cwnd * pwnd = pmainfrm-> m_wndsplitterright.getpane (0, 0 );
Clefttopview * plefttopview = dynamic_downcast (clefttopview, pwnd );
Plefttopview-> getmsg (m_stext + "\ r \ n"); // clefttopview member function to receive data
}
In the upper right view, the member function getmsg of the clefttopview class needs to save and display the received messages.
The Code is as follows:
Void clefttopview: getmsg (cstring smsg ){
M_sallmsg + = smsg; // m_sallmsg is a member variable and records all messages.
Int ntextlen = getwindowtextlength ();
Geteditctrl (). setsel (ntextlen, ntextlen );
Geteditctrl (). replacesel (smsg); // display new messages
}
With the above two functions, You can implement the upper right view class clefttopview and upper right view class cleftbttmview.
Similar to the simple communication between views, data can be transmitted between all views.
Instance description
The instance is a single-document-based MFC application that uses the static split window method to split the window three-way, that is, the common
Three panes. The program enables you to enter student information and add it to the list view. Program final operation
The result of the row is as follows:
The left-side Basic Information Input pane uses a cformview view.
Enter information and click "Submit". The data is added to the document and displayed in the List View on the right. Right side
The information display pane uses a clistview view to display all student information stored in the document. While the bottom
In the left-side Navigation Pane, The ceditview view is used to prompt the user for the data added in the previous step. The following describes the specific
Implementation process.
Create a project
Use Appwizard to create a single-document-based application framework project named "guo ".
Use the default settings.
Add View class
You need to add three view classes for the three panes. Cleftformview, ctoplistview, cbottomeditview
The base classes are cformview, clistview, and ceditview.
1. Implementation of the cleftformview class
A. Add dialog box resource template: before adding the cleftformview class, you must first add
Shows the dialog box template in the cleftformview:
The ID of the dialog box template is "idd_dialog1", its style attribute is set to "child", and the bolder attribute is set
"None ".
B. Add the cleftformview class. Run the "insert" → "New Class" menu command to bring up the "New Class" dialog.
Box, enter the class name "cleftformview" in the name edit box, and select the base class from the base class list box.
"Cformview" option, select the "idd_dialog1" dialog box resource in the dialog ID list box. Click OK.
Added the cleftformview class.
C. Add resources related to the cleftformview class: use Class Wizard in cleftformview, as the dialog box
Add member variables m_num, m_name, m_magor, and,
M_home, and add the onsubmit () Message response function for the "Submit" button ().
2. Implementation of the ctoplistview class
Similarly, in the "New Class" dialog box, add the ctoplistview class and set its base class type to clistview.
Then, use Class Wizard to reload the precreatewindow () function of the class, and define the type of the List View in it.
The Code is as follows:
Bool ctoplistview: precreatewindow (createstruct & CS)
{
// Todo: add your specialized code here and/or call the base class
CS. Style = cs. Style | lvs_report; // set it to display the report list.
Return clistview: precreatewindow (CS );
}
Use Class Wizard to reload the oninitialupdate () function of the ctoplistview class, and add the header of the List to it,
The Code is as follows:
Void ctoplistview: oninitialupdate ()
{
Clistview: oninitialupdate ();
// Todo: add your specialized code here and/or call the base class
Cstring m_columnlabelstr [] = {"student ID", "name", "Major", "nationality "};
// Header field
Clistctrl & listctrl = getlistctrl (); // gets the list control
DWORD dwstyle = listctrl. getextendedstyle ();
Dwstyle | = lvs_ex_fullrowselect;
// Select an exercise to highlight the entire line (only applicable to listctrl in the report style)
Dwstyle | = lvs_ex_gridlines;
Dwstyle | = lvs_ex_underlinehot;
Listctrl. setextendedstyle (dwstyle); // list Style
Int width [6] = {80, 80, 110,150 };
For (INT I = 0; I <4; I ++)
{
Listctrl. insertcolumn (I, m_columnlabelstr [I], lvcfmt_left, width [I]); // set
Header
}
}
3. Implementation of the cbottomeidtview class
Similarly, in the new class dialog box, add the cbottomeditview class and select its base class as "ceditview ".
Then, use Class Wizard to reload the oninitialupdate () function of this class, and implement initialization settings in it. The Code
As follows:
Void cbottomeditview: oninitialupdate ()
{
Ceditview: oninitialupdate ();
// Todo: add your specialized code here and/or call the base class
Cedit & medit = geteditctrl (); // gets the control of the editing view.
Medit. setwindowtext ("waiting for the user to enter student information! "); // Set the display information
Medit. enablewindow (false); // The editing control cannot be edited.
}
Static split window implementation
In the process of window separation, the main frame cmainframe splits the window into the upper and lower panes, corresponding
The views are cguoview and cbottomeditview. Then, in the cguoview view, the pane is divided into left and right
The two panes correspond to the cleftformview and ctoplistview. The implementation process is as follows.
1. In the header file of the cmainframe class, declare the member variable m_wndsplitter1 of the csplitterwnd class,
Used to split the first window
Protected: // control bar embedded members
Cstatusbar m_wndstatusbar;
Ctoolbar m_wndtoolbar;
Csplitterwnd m_wndsplitter1; // used to generate the first static split.
2. Use Class Wizard to reload the oncreateclient () function of the cmainframe class, and implement the first
Split the window.
Bool cmainframe: oncreateclient (lpcreatestruct lpcs, ccreatecontext * pcontext)
{
// Todo: add your specialized code here and/or call the base class
Crect rect;
Getclientrect (& rect); // generates the first static split.
M_wndsplitter1.createstatic (this, // parent window pointer
2, 1); // number of rows and columns
M_wndsplitter1.createview (0, 0, // The ordinal number of the row and column in the pane
Runtime_class (cguoview), // View class
Csize (rect. Width (), rect. Height ()-rect. Height ()/5), pcontext); // create a parameter for the parent window
M_wndsplitter1.createview (1, 0, runtime_class (cbottomeditview ),
Csize (rect. Width (), rect. Height ()/5), pcontext );
// The oncreateclient function of the base class is not called.
Return true;
}
Include the corresponding header file and add the following statements at the beginning of the mainframe. cpp File
# Include "guoview. H"
# Include "bottomeditview. H"
3. Declare a member variable of the csplitterwnd class in the header file of the visual window class cguoview.
M_wndsplitter2, used for the second window split.
Protected:
Csplitterwnd m_wndsplitter2; // used to separate the second window
4. Use Class Wizard to reload the oncreateclient () and onsize () Functions of the cguoview class to implement
Split twice and set the size of the pane.
Int cguoview: oncreate (maid)
{
If (cview: oncreate (lpcreatestruct) =-1)
Return-1;
// Todo: add your specialized creation code here
Crect rect;
Getclientrect (& rect); // obtain the window creation Information pointer
Ccreatecontext * pcontext = (ccreatecontext *) lpcreatestruct-> lpcreateparams;
M_wndsplitter2.createstatic (this,); // generates the second static split.
// Generate a view for the first pane
M_wndsplitter2.createview (0, 0, // The ordinal number of rows and columns in the window
Runtime_class (cleftformview), // View class
Csize (rect. Width ()/4, rect. Height ()),//
Pcontext );
// Generate a view for the second pane
M_wndsplitter2.createview (0, 1, runtime_class (ctoplistview), csize (1, 1), pcontext );
Return 0;
}
Void cguoview: onsize (uint ntype, int CX, int CY)
{
Cview: onsize (ntype, CX, CY );
// Todo: add your message handler code here
Crect rect;
Getclientrect (& rect );
Int x = rect. Width ();
Int y = rect. Height ();
M_wndsplitter2.movewindow (-2,-2, X, Y + 3 );
M_wndsplitter2.setcolumninfo (0, x/4, 0); // left pane position
M_wndsplitter2.setcolumninfo (1, x-X/4, 0); // The Position of the right pane
M_wndsplitter2.recalclayout ();
}
At this point, the window is split, and the program is compiled and run, and the three-way window has been implemented. If the connection is compiled
The following error occurs during the program:
C: \ Documents ents and Settings \ chenqi \ Desktop \ Guo \ guoview. H (23): Error c2143: syntax error: Missing
'; 'Before '*'
C: \ Documents and Settings \ chenqi \ Desktop \ Guo \ guoview. H (23): Error c2501: 'cguosdoc ': Missing
Storage-class or type specifiers
C: \ Documents and Settings \ chenqi \ Desktop \ Guo \ guoview. H (23): Error c2501: 'getdocument ':
Missing storage-class or type specifiers
You can add the class cguodoc before the header file of the cguoview class.
Interaction between the pane view and the document
The split pane views in the window correspond to the same document object cguodoc, and each cview derived class has
The getdocument () function is supported. Therefore, you can obtain the object of the document by performing type forced conversion after calling.
For example, cguodoc * pdoc = (cguodoc *) getdocument ();
In this example, the object cguodoc stores student information through array objects.
In the view, when you enter the student information and click the submit button, the input information is written to the array object in the document and repainted.
View.
1. Declare the array object and data modification tag in the header file of the cguodoc class as follows:
Public:
Cstringarray infoarray [4];
Bool add;
The value of ADD is initialized to false in the constructor.
2. In the response function onsubmit () of the cleftformview class, add code to implement control data protection.
Save and update all views.
Void cleftformview: onsubmit ()
{
// Todo: add your control notification handler code here
Updatedata (true); // obtain control data in the dialog box
If (m_num.isempty () | m_name.isempty () // determines whether it is null.
{Afxmessagebox ("student ID and name cannot be blank! "); Return ;}
Cguodoc * pdoc = (cguodoc *) getdocument (); // get the document
Pdoc-> infoarray [0]. insertat (0, m_num); // insert data into the input data
Pdoc-> infoarray [1]. insertat (0, m_name );
Pdoc-> infoarray [2]. insertat (0, m_magor );
Pdoc-> infoarray [3]. insertat (0, m_home );
Pdoc-> Add = true; // added data
Pdoc-> updateallviews (null); // update all views
M_num = _ T ("");
M_name = _ T ("");
M_magor = _ T ("");
M_home = _ T ("");
Updatedata (false); // clear the content of each control
}
The header file containing the cguodoc class is added to the cleftformview. cpp file with the following statement:
# Include "guodoc. H"
3. Reload the onupdate () function in the View class ctoplistview and cbottomeditview to update the view.
Void ctoplistview: onupdate (cview * psender, lparam lhint, cobject * phint)
{
// Todo: add your specialized code here and/or call the base class
Cguodoc * pdoc = (cguodoc *) getdocument (); // get the document pointer
If (pdoc-> Add) // added data
{
Clistctrl & listctrl = getlistctrl (); // gets the list control
Listctrl. deleteallitems (); // delete all items
For (INT I = 0; I <pdoc-> infoarray [0]. getsize (); I ++) // insert data into the list box
{
Listctrl. insertitem (I, pdoc-> infoarray [0]. getat (I ));
Listctrl. setitemtext (I, 1, pdoc-> infoarray [1]. getat (I ));
Listctrl. setitemtext (I, 2, pdoc-> infoarray [2]. getat (I ));
Listctrl. setitemtext (I, 3, pdoc-> infoarray [3]. getat (I ));
}
}
}
Void cbottomeditview: onupdate (cview * psender, lparam lhint, cobject * phint)
{
// Todo: add your specialized code here and/or call the base class
Cguodoc * pdoc = (cguodoc *) getdocument (); // get the document pointer
If (pdoc-> Add) // added data
{
Cstring STR;
STR = "added student information with student ID" + pdoc-> infoarray [0]. getat (0) +! ";
Cedit & medit = geteditctrl (); // gets the edit View Control
Medit. setwindowtext (STR); // display information
}
}
You also need to include the header file of the Document Object in the resource files of these two view classes, as follows:
# Include "guodoc. H"
At this point, the instance development is complete. Compile and run the project to implement the required results.
Note: compilation may report:
Error c2143: syntax error: ";" missing (before)
Error c2501: "ctestview: ctestdoc": the storage class or type specifier is missing.
Error c2501: "ctestview: getdocument": the storage class or type specifier is missing.
Warning c4183: "getdocument": The return type is missing. It is assumed that it is a member function that returns "int ".
Solution:
C *** view. h file header added
# Include "C *** Doc. H"
You can also remove the above in C ** view. cpp,