Summary of MFC View Switch Daquan

Source: Internet
Author: User
Tags unique id
Switching between the pure view


Single document multi-view switching is one of the most difficult problems I have encountered in learning MFC. I feel that the view switch is divided into three levels, the first is to switch the view class in the case of the non-segmented panes, the second is to switch the experiment view in one pane of the pane, and the third is to toggle between the separate panes and the different views.


At the beginning of the creation of SDI in MFC, MFC default View class is CView, if CView to meet your needs, you can click Finish directly, if you do not want CView to become your default view class, you can mark this place.


If you forget. Correcting the default view class It doesn't matter, we can change it in the code:


In the app class there is a function called InitInstance (), in which there is a code


CSingleDocTemplate pdoctemplate;


Pdoctemplate = new CSingleDocTemplate (


Idr_mainframe,


Runtime_class (Cprogram8doc),


Runtime_class (CMainFrame),


Runtime_class (CView1)); Change your default view class here, pay attention to don't forget to include the header file Oh


if (!pdoctemplate)


return FALSE;


AddDocTemplate (pdoctemplate);


I'm done with the changes to the default view class, we're now going to the topic.


1. Create the view class you need to switch, addclass Enter or create a control and then addclass create the control engagement class, which is useful for controls like form.


2, the grasp of the place, such as menu items Click, click the mouse or something, I am the Application menu item to switch the window


void Cmainframe::onview1 ()


{


Todo:add your command handler code here


Switchtoform (IDD_FORMVIEW1);


}


void Cmainframe::onview2 ()


{


Todo:add your command handler code here


Switchtoform (IDD_FORMVIEW2);


}


3, Switchtoform This function is primarily used for view switching


Here are some of the first things to do in this function:


1, the appropriate front view class pointer and the need to convert the view class pointer, if the first application needs new one, and the document class contact;


2, change the activity view;


3. Display new view and concealed old view;


4, set the control ID;


5, adjust the frame view.


void Cmainframe::switchtoform (int nform)


{


CView Poldactiveview=getactiveview (); 1


CView pnewactiveview= (CView) GetDlgItem (nform);


if (Null==pnewactiveview)


{


Switch (nform)


{


Case IDD_FORMVIEW1:


Pnewactiveview= (CView) new CView1;


Break


Case IDD_FORMVIEW2:


Pnewactiveview= (CView) new CView2;


Break


Case IDD_FORMVIEW3:


Pnewactiveview= (CView) new CView3;


Break


Case IDD_FORMVIEW4:


Pnewactiveview= (CView) new CView4;


Break


Default


Break


}


CCreateContext context;


Context.m_pcurrentdoc=poldactiveview->getdocument ();


Pnewactiveview->create (Null,null,ws_child | Ws_border,cframewnd::rectdefault,this,nform,&context);


Pnewactiveview->updatedata ();


}


SetActiveView (Pnewactiveview); 2


Pnewactiveview->showwindow (Sw_show); 3


Poldactiveview->showwindow (Sw_hide);


if (Poldactiveview->getruntimeclass () ==runtime_class (CView1))//4


Poldactiveview->setdlgctrlid (IDD_FORMVIEW1);


else if (Poldactiveview->getruntimeclass () ==runtime_class (CVIEW2))


Poldactiveview->setdlgctrlid (IDD_FORMVIEW2);


else if (Poldactiveview->getruntimeclass () ==runtime_class (CVIEW3))


Poldactiveview->setdlgctrlid (IDD_FORMVIEW3);


else if (Poldactiveview->getruntimeclass () ==runtime_class (CVIEW4))


Poldactiveview->setdlgctrlid (IDD_FORMVIEW4);


Pnewactiveview->setdlgctrlid (Afx_idw_pane_first);


RecalcLayout (); 5


}


Invented in RecalcLayout () when looking at other people's posts online; There is a poldactiveview in front of me, I feel so much waste of information, view class created to cover up, with the hour from the beginning of the show. This approach should be created better than every application. My little brother, a friend with a comment debate can contact me.


View Toggle with separate panes


Toggle View the second layer is a view switch with a separate pane


The view switch of the pane, I feel the difficulty is not easily in the limited area of the view switch.


1, the initial separate panes, here I soon not more statement, details see the following links;


2, give each view a unique ID number;


M_splitter. CreateStatic (this,1,2);


M_splitter. CreateView (0,0,runtime_class (CTree1), CSize (100,100), pContext);


M_splitter. CreateView (0,1,runtime_class (CForm1), CSize (100,100), pContext);


CWnd Pwnd=m_splitter. GetPane (0,1);


m_pviews[0]= (CView) m_splitter. GetPane (0,1);


Pwnd->setdlgctrlid (IDD_FORM1);


Pwnd->showwindow (Sw_hide);


M_splitter. CreateView (0,1,runtime_class (CForm2), CSize (100,100), pContext);


Pwnd=m_splitter. GetPane (0,1);


m_pviews[1]= (CView) m_splitter. GetPane (0,1);


Pwnd->setdlgctrlid (M_splitter. Idfromrowcol (0,1));


Pwnd->showwindow (Sw_show);


RedrawWindow ();


return true;


Note: I createview a new view here, I will overwrite the previous view, the final display is the last view, the front view is only hidden, and the application of the time to display it. return value to overwrite the statement returned to the base class return Cframewndex::oncreateclient (LPCs, pContext); Annotate the sentence and return true;


3, where to activate the switching function itself design, I applied the menu;


4, the response first consists of the following steps:


1, the initial access to the current view in the pane;


2, apply iskindof Determine whether this class is going to switch to the class;


3, get frame length and width of the window;


CView pview= (CView) m_splitter. GetPane (0,1); 1


M_btest=pview->iskindof (Runtime_class (CFORM2)); 2


CRect rcframe,rcclient; 3


M_splitter. GetClientRect (&rcclient);


GetClientRect (&rcframe);


Above all is to organize the work, below is the real switch;


4. Delete the original view


5. Create the current View


6. Adjustment frame


if (m_btest)


{


M_splitter. Deleteview (0,1);


M_splitter. CreateView (0,1,runtime_class (CForm1), CSize (Rcclient.width (), Rcframe.height ()), NULL);


M_splitter. RecalcLayout ();


}


Else


{


M_splitter. Deleteview (0,1);


M_splitter. CreateView (0,1,runtime_class (CForm2), CSize (Rcclient.width (), Rcframe.height ()), NULL);


M_splitter. RecalcLayout ();


}


Look carefully, it seems that this is more than the pure view switch is also simple, this has no way, csplitterwnd supply such a convenient way.


Toggle between separate view and non-separate view


This is the trilogy I think the most difficult, not to say how difficult the statutes, just think of this segmentation format is really not easy, today, the trilogy of the last song to share to the master, but also for the internet to do a little to offer.


Let's begin with the thinking of the statutes, create a class based on CFrameWnd for the separate window layer, then write the code for the separate views here, and then switch to the other non-separate view classes.


Let's take a look at the implementation process:


1. Create a derived class csplitterframe based on CFrameWnd;


2. Add the view class to fill the window and switch the view class with the separate view;


3. Overload the OnCreateClient function for this derived class, and the organization view separately


M_splitter.createstatic (this,1,2);


M_splitter.createview (0,0,runtime_class (Clefttree), CSize (300,0), pContext);


M_splitter.createview (0,1,runtime_class (crightlist), CSize (300,0), pContext);


return true;


Here I do not say clear, presumably the master are very familiar with, here I would like to say a bit of my own mistakes. I Dibon want to getclientrect here to get window size, but failed, wrestling not familiar with inquire, later only invented, this is not cmainframe, so the foundation can't get, if using API function.


4. Add frame and view class pointer variables inside the CMainFrame class


Csplitterframe M_psplitterframe; Separate view frame pointer


CView M_pview; 0-D view class, based on the CView class


CView M_pform; 0-D view class, based on the CFormView class


int M_ncurrentid; Record Current View


5. Overload the OnCreateClient function inside the CMainFrame class to create a view and separate frames


CRect rcclient;


GetClientRect (&rcclient);


M_pview=new cviewshow;


M_pview->create (Null,null,afx_ws_default_view &~ws_border,rcclient,this,null,pcontext);


M_pview->showwindow (Sw_show);


M_pview->setdlgctrlid (Afx_idw_pane_first);


Pcontext->m_pnewviewclass= (CRuntimeClass) M_pview; Set the default view class


M_pform=new cformshow;


M_pform->create (Null,null,afx_ws_default_view &~ws_border,rcclient,this,idd_formshow,pcontext);


M_pform->showwindow (Sw_hide);


M_psplitterframe=new Csplitterframe;


M_psplitterframe->create (Null,null,afx_ws_default_view &~ws_border,rcclient,this,null,0,pcontext);


M_psplitterframe->showwindow (Sw_hide);


return true;


6. Create a view switch function


BOOL Cmainframe::switch (int. NID)


{


if (Nid==m_ncurrentid)


return false;


Switch (NID)


{


Case Idd_formshow:


M_pform->showwindow (Sw_show);


M_pform->setdlgctrlid (Afx_idw_pane_first);


M_pview->showwindow (Sw_hide);


M_pview->setdlgctrlid (afx_idw_pane_first+2);


M_psplitterframe->showwindow (Sw_hide);


M_psplitterframe->setdlgctrlid (afx_idw_pane_first+1);


M_ncurrentid=idd_formshow;


Break


Case AFX_IDW_PANE_FIRST+1:


M_psplitterframe->showwindow (Sw_show);


M_psplitterframe->setdlgctrlid (Afx_idw_pane_first);


M_pform->showwindow (Sw_hide);


M_pform->setdlgctrlid (idd_formshow);


M_pview->showwindow (Sw_hide);


M_pview->setdlgctrlid (afx_idw_pane_first+2);


m_ncurrentid=afx_idw_pane_first+1;


Break


Case AFX_IDW_PANE_FIRST+2:


M_pview->showwindow (Sw_show);


M_pview->setdlgctrlid (Afx_idw_pane_first);


M_pform->showwindow (Sw_hide);


M_pform->setdlgctrlid (idd_formshow);


M_psplitterframe->showwindow (Sw_hide);


M_psplitterframe->setdlgctrlid (afx_idw_pane_first+1);


m_ncurrentid=afx_idw_pane_first+2;


Break


Default


Break


}


RecalcLayout ();


return true;


}


7. Create a Call method


void Cmainframe::onform ()


{


Todo:add your command handler code here


Switch (idd_formshow);


}


void Cmainframe::onview ()


{


Todo:add your command handler code here


Switch (afx_idw_pane_first+2);


}


void Cmainframe::onsplitter ()


{


Todo:add your command handler code here


Switch (afx_idw_pane_first+1);


}


There is a strong attraction between us. Just a few hours later, we both know: our heart is a whole of the two halves, our hearts are twins, is a bosom friend. She makes me feel more energetic, more perfect and happier. Even if she is not with me, I still feel happy, because she always in one way or another to appear in my heart. --Enrique Barrios "The Civilization of Love"

From: http://www.gjprj.cn/news1.asp?id=2354

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.