1. Create a different sub-frame.
In the document View program, CMainFrame (class Cmainframe:public CMDIFrameWndEx) inherits from CMDIFrameWnd (CMDIFrameWndEx is a CMDIFrameWnd subclass). So you can turn m_pMainWnd into a cmdiframewnd pointer, and then call Createnewchild to create a child frame. This can be cast to the desired object, depending on the specific class name passed in.
cmdiframewnd* Pmdifrmwnd = reinterpret_cast<cmdiframewnd*>(m_pmainwnd); = reinterpret_cast<cchildfrm*> (pmdifrmwnd->createnewchild (Runtime_class (CCHILDFRM), IDR_MAINFRAME)) ; M_pchildfrm->showwindow (sw_show);
2. CSplitterWnd splitter window.
The splitter window is in the OnCreateClient method of the CMDIChildWnd subclass. First, the window can be split using createstatic, with a maximum support of 16 x.
Then createview the different regions to set different CView, after the completion of the use of CSplitterWnd object GetPane method can obtain different areas of CWnd pointer, strong to the set of CView subclass.
Note: (1) Each zone created by createstatic must use CreateView to set a subclass of CView, or to continue splitting with another CSplitterWnd population.
(2) CreateView incoming must be CView subclass, cannot use CTRL or dialog, for controls such as CEdit, you can use CEditView instead, other such as CCtrlView class. For dialog classes that use resources, you can use CFormView.
BOOL Cchildfrm::oncreateclient (lpcreatestruct/*LPCs*/, ccreatecontext*PContext) { //To Create a splitter window if(!m_wndsplitter.createstatic ( This,2,1)) returnFALSE; if(!m_wndsplittertop.createstatic (&m_wndsplitter,1,3, Ws_child | Ws_visible, M_wndsplitter.idfromrowcol (0,0))) { returnFALSE; } if(!m_wndsplittertop.createview (0,0, Runtime_class (Cleftview), CSize (0,0) ( PContext)) {returnFALSE; } if(!m_wndsplittertop.createview (0,1, Runtime_class (Csplitedemoview), CSize (0,0) ( PContext)) {returnFALSE; } if(!m_wndsplittertop.createview (0,2, Runtime_class (Csplitedemoview), CSize (0,0) ( PContext)) {returnFALSE; } if(!m_wndsplitter.createview (1,0, Runtime_class (Cctrlsview), CSize (0,0) ( PContext)) {returnFALSE; } M_pleftview= Reinterpret_cast<cleftview*> (M_wndsplittertop.getpane (0,0)); M_pmidview= Reinterpret_cast<csplitedemoview*> (M_wndsplittertop.getpane (0,1)); M_prightview= Reinterpret_cast<csplitedemoview*> (M_wndsplittertop.getpane (0,2)); M_pctrls= Reinterpret_cast<cctrlsview*> (M_wndsplitter.getpane (1,0)); returnTRUE;}
3. CSplitterWnd size Adjustment
The OnSize method is called when the window size changes (you need to add on_wm_size () to the message map), and you typically need to modify the size and position of the splitter and the individual child view. Where splitter is adjusted, you need to call SetRowInfo and setcolumninfo to reset the position of the separator bar.
Note that the OnSize method is called multiple times during initialization, and some windows may not be created, so you need to make a decision.
Begin_message_map (cchildfrm, CMDIChildWndEx) on_wm_size () on_message (Um_input_text,&Cchildfrm::oninputtext) End_message_map ()voidCchildfrm::onsize (UINT NType,intCxintcy) {cmdichildwndex::onsize (NType, CX, CY); if(:: IsWindow (M_wndsplittertop)) {CRect rect; GetClientRect (rect); M_wndsplitter.movewindow (rect); intnheight = rect. Height ()- -; if(Nheight <0) nheight=0; M_wndsplittertop.movewindow (Rect.left, Rect.top, Rect.right, nheight); M_wndsplitter.setrowinfo (0, nheight,0); M_wndsplitter.recalclayout (); M_wndsplittertop.getclientrect (rect); intnwidth = rect. Width ()/3; M_wndsplittertop.getpane (0,0),MoveWindow (Rect.left, Rect.top, nwidth, Rect.bottom); M_wndsplittertop.getpane (0,1)->movewindow (nwidth, Rect.top, nwidth *2, Rect.bottom); M_wndsplittertop.getpane (0,2)->movewindow (nwidth *2, Rect.top, Rect.right, Rect.bottom); M_wndsplittertop.setcolumninfo (0, nwidth,0); M_wndsplittertop.setcolumninfo (1, nwidth,0); M_wndsplittertop.recalclayout (); M_wndsplitter.getclientrect (rect); M_pctrls-OnSize (NType, CX, CY); }}
4. Message Distribution in frame
A frame typically contains multiple child view. A child view's message usually needs to be passed to another child view, or some time-consuming operation needs to be updated to the interface after processing in the child thread, which involves message processing.
When a child view is notified to another child view, it is usually passed to the frame before it is distributed. Then other interested child view responds to this message again.
For child threading results, it is best to PostMessage return a new object created by the frame using the SendMessage notification to each child view processing before releasing.
voidcctrlsview::onbnclickedbuttonconfirm () {CString* Pstrtext =NewCString (); CWnd* PWnd =GetDlgItem (Idc_edit); PWnd->GETWINDOWTEXTW (*pstrtext); PWnd->setwindowtext (_t ("")); GetParentFrame ()->sendmessage (Um_add_text, (WPARAM) Pstrtext,0);} LRESULT Cchildfrm::oninputtext (WPARAM WPARAM, LPARAM LPARAM) {M_pleftview-SendMessage (Um_add_text, WParam, LParam); M_pmidview-SendMessage (Um_add_text, WParam, LParam); M_prightview-SendMessage (Um_add_text, WParam, LParam); CString* PStr = (cstring*) WParam; if(pStr) {DeletepStr; PStr=NULL; } return 0;} LRESULT Csplitedemoview::oninputtext (WPARAM WPARAM, LPARAM LPARAM) {CString str= * (cstring*) (WParam); CListCtrl* Plistctrl = &GetListCtrl (); Plistctrl->insertitem (plistctrl->getitemcount (), str); return 0;}
5. Design of the worker thread
Creates a thread that can be created when this worker thread event is required to be triggered.
void Cchildfrm::createworkthread () { if (! M_hworkthread) { 0this0, &m_dwwordthreadid); Sleep (// Wait a minute, switch threads, wait for thread creation }}
In the framework, an event is created for the hold thread to exit. Sends an exit message in a destructor or other place where this worker thread is not required.
cchildfrm::cchildfrm () { =:: CreateEvent (NULL, True, True, _t ("")); Createworkthread ();} CCHILDFRM::~cchildfrm () { if (m_hworkthreadexit) { 0 0 ); - ); CloseHandle (m_hworkthreadexit); = NULL;} }
Worker threads handle different messages in the body, and other threads use PostThreadMessage to notify worker threads of work. When a worker exits, the event is set to a signaled state.
DWORD WINAPI cchildfrm::wordthreadfun (lpvoid lpparam) {cchildfrm* Pmain = (cchildfrm*) Lpparam; :: ResetEvent (Pmain-m_hworkthreadexit); BOOL Isrun=TRUE; Msg msg= {0}; ::P Eekmessage (&msg, NULL,0,0, Pm_remove); while(Isrun) {GetMessage (&msg, NULL,0,0); Switch(msg.message) { CaseWm_quit:isrun=FALSE; Break; Casewm_gettime: {SYSTEMTIME systime= {0}; :: Getlocaltime (&systime); CString* PStr =NewCString (); PStr->format (_t ("%04d-%02d-%02d%02d:%02d:%02d"), Systime.wyear, Systime.wmonth, Systime.wday, Systime.whour, Systime.wminute, Systime.wsecond); Pmain->postmessage (Um_add_text, (WPARAM) PStr,0); } Break; default: Break; } } if(pmain->m_hworkthread) {CloseHandle (Pmain-m_hworkthread); Pmain->m_hworkthread =NULL; }:: SetEvent (Pmain-m_hworkthreadexit); return 0;}
Source:
http://download.csdn.net/detail/diysoul/9631904
MFC single document multi-view programming and splitter splitter window