MFC CSplitterWnd窗口分割

http://blog.csdn.net/csdnmicrosoftcsdn/article/details/47952895

鉴于CSplitterWnd资料很少(MSDN上也说的很简单,Sample我也就不想吐槽了),同时网上博客又几乎是千篇一律的转载。现将个人的一点经验拿出来和大家分享,希望对他人有所帮助。不足之处还望批评指正。

       最终效果如下:

      分割窗体就是把一个窗体分割成多个面板,面板就是放各种控件或视图的容器。分割窗体有两种形式,静态和动态。两种形式的区别在于动态的可以收拢和展开,静态的则不能。动态分割只能创建2*2的分割窗口,而静态分割可以创建16*16的分割窗口。

       好了,进入正题。在VS或VC++6.0中建立一个多文档或者单文档,按照向导一直下一步即可。本文创建的是多文档,单文档相对简单一些。

       创建好之后,在ChildFrm.h中添加两个窗口分割变量:

[cpp] view plain copy
 
  1. // Attributes  
  2. protected:  
  3.     CSplitterWnd m_wndSplitter1;  
  4.     CSplitterWnd m_wndSplitter;  

然后选择工程的类视图,右键ChildFrm属性,添加Overrides中的OnCreateClient方法。如果是单文档的话在MainFrm中添加!

修改OnCreateClient方法如下:

[cpp] view plain copy
 
  1. BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)  
  2. {  
  3.     ////// Create 2*2 nested dynamic splitter  
  4.     ////    // TODO: Add your specialized code here and/or call the base class  
  5.     ////    return m_wndSplitter.Create(this,  
  6.     ////        2, 2,           // TODO: adjust the number of rows, columns  
  7.     ////        CSize(10, 10),  // TODO: adjust the minimum pane size  
  8.     ////        pContext);  
  9.     ////    //return CMDIChildWnd::OnCreateClient(lpcs, pContext);  
  10.   
  11.     //// Create a  static splitter with 1 rows, 3 columns  
  12.     //m_wndSplitter.CreateStatic(this, 1, 3);   // create a splitter with 1 rows, 3 columns  
  13.     //m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CViewLeft), CSize(0, 0), pContext);  // create view with 0 rows, 0 columns  
  14.     //m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CViewMiddle), CSize(0, 0), pContext);    // create view with 0 rows, 1 columns  
  15.     //m_wndSplitter.CreateView(0, 2, RUNTIME_CLASS(CViewRight), CSize(0, 0), pContext); // create view with 0 rows, 2 columns  
  16.   
  17.     //m_wndSplitter.SetColumnInfo(0, 400, 10);  // set the width of column, 0 column, ideal width is 200dip,min width is 10dip  
  18.     //m_wndSplitter.SetColumnInfo(1, 400, 10);  // set the width of column, 0 column, ideal width is 200dip,min width is 10dip  
  19.     //m_wndSplitter.SetColumnInfo(2, 400, 10);  // set the width of column, 0 column, ideal width is 200dip,min width is 10dip  
  20.     //// m_wndSplitter.SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);  
  21.   
  22.     //Create a static splitter with 2 rows,1 columns  
  23.     if (!m_wndSplitter.CreateStatic(this, 2, 1, WS_CHILD|WS_VISIBLE))  
  24.     {  
  25.         TRACE("Failed to Create StaticSplitter ");  
  26.         return NULL;  
  27.     }  
  28.     //set view  
  29.     pContext->m_pNewViewClass = RUNTIME_CLASS(CViewRight);  
  30.       
  31.     CRect rect;       
  32.     this->GetClientRect(&rect);  
  33.     SIZE size;  
  34.     size.cx = rect.Width();  
  35.     size.cy = rect.Height()/3;  
  36.   
  37.     m_wndSplitter.CreateView(0, 0, pContext->m_pNewViewClass, size, pContext);  
  38.     //m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CViewLeft), CSize(0, 0), pContext);  // create view with 0 rows, 0 columns  
  39.     //m_wndSplitter.SetRowInfo(0, 200, 10); // set the width of column, 0 column, ideal width is 250dip,min width is 10dip  
  40.   
  41.   
  42.     pContext->m_pNewViewClass = RUNTIME_CLASS(CViewMiddle);  
  43.     if (!m_wndSplitter1.Create(  
  44.         &m_wndSplitter,     // our parent window is the first splitter  
  45.         2, 2,          // TODO: adjust the number of rows, columns  
  46.         CSize(10, 10), // TODO: adjust the minimum pane size  
  47.         pContext,  
  48.         WS_CHILD|WS_VISIBLE|SPLS_DYNAMIC_SPLIT|WS_HSCROLL|WS_VSCROLL,  
  49.         m_wndSplitter.IdFromRowCol(1, 0)))  
  50.     {  
  51.         TRACE("Failed to create the nested dynamic splitter ");  
  52.     }  
  53.   
  54.     return TRUE;  
  55. }  

RUNTIME_CLASS是MFC中的一个宏,用来动态创建一个类。
这里是我做了三种分割方式的测试,第一种是直接创建了一个2*2的动态分割窗口,没有修改视图;第二种是创建的一个一行三列的静态分割窗口,并且分别为之创建了三个视图,然后设置的了每一列的宽度;最后一种是静态分割和动态分割嵌套使用,先使用静态分割,将整个窗口分割成为两行一列,分割完成后为第一行创建视图,设置视图高度为整个窗口的1/3,然后更改视图,使得随后动态分割的窗口绑定不同的视图,再对第二行使用动态分割,将第二行分割成2*2的动态分割窗口。

       CViewLeft、CViewRight、CViewMiddle这三个类均继承自CView,只需重写下每个类的OnDraw方法即可

[cpp] view plain copy
 
  1. void CViewLeft::OnDraw(CDC* pDC)  
  2. {  
  3.     CDocument* pDoc = GetDocument();  
  4.     // TODO: add draw code here  
  5.     CPaintDC* dc = (CPaintDC*)pDC;  
  6.     CRect rect,fillrect;  
  7.     CBrush brush;  
  8.     brush.CreateSolidBrush(RGB(255, 0, 0));  
  9.     this->GetClientRect(&rect);  
  10.     dc->FillRect(&rect,&brush);  
  11.     brush.DeleteObject();  
  12. }  
[cpp] view plain copy
 
  1. void CViewMiddle::OnDraw(CDC* pDC)  
  2. {  
  3.     CDocument* pDoc = GetDocument();  
  4.     // TODO: add draw code here  
  5.     CPaintDC* dc = (CPaintDC*)pDC;  
  6.     CRect rect,fillrect;  
  7.     CBrush brush;  
  8.     brush.CreateSolidBrush(RGB(0, 255, 0));  
  9.     this->GetClientRect(&rect);  
  10.     dc->FillRect(&rect,&brush);  
  11.     brush.DeleteObject();  
  12. }  
[cpp] view plain copy
 
  1. void CViewRight::OnDraw(CDC* pDC)  
  2. {  
  3.  CDocument* pDoc = GetDocument();  
  4.  // TODO: add draw code here  
  5.  CPaintDC* dc = (CPaintDC*)pDC;  
  6.  CRect rect,fillrect;  
  7.  CBrush brush;  
  8.  brush.CreateSolidBrush(RGB(0, 0, 255));  
  9.  this->GetClientRect(&rect);  
  10.  dc->FillRect(&rect,&brush);  
  11.  brush.DeleteObject();  
  12. }  

       一个CSplitterWnd对象通常被嵌入CFrameWnd或CMDIChildWnd父对象。一般使用Create或者CreateStatic分割窗口完毕,可使用SetColumnInfo和SetRowInfo来调整这些最小值,为使用其设置过的行或列则会自动分配大小。

定制属于自己的SplitterWnd:拖动滚动条时只显示一行或者一列

[cpp] view plain copy
 
  1. /***************************************************************** 
  2.  
  3. Filename:           Splitter.h 
  4. Contents:           Implemetation of CSplitter class 
  5.  
  6. Authors:     
  7. Created date:        
  8. Last Modified date:  
  9. Revision History:  
  10.  
  11. Used by:             
  12. Uses:                
  13. Build Notes:         
  14.  
  15. See Also:            
  16.  
  17. Copyright:      (c) 2015 by All rights reserved.                            
  18.  
  19. *****************************************************************/  
  20.   
  21. #pragma once  
  22.   
  23. // CSplitter  
  24.   
  25. class CSplitter : public CSplitterWnd  
  26. {  
  27.     DECLARE_DYNCREATE(CSplitter)  
  28.   
  29.     // Attributes  
  30. public:  
  31.     // this var saves the size of the pane before floating  
  32.     int m_iSize;  
  33.     // this var saves the pane orientation before floating  
  34.     BOOL m_bHorizontal;  
  35.   
  36.     SIZE m_szMinimumSize;  
  37. public:  
  38.     CSplitter();  
  39.     // added funciton for customize the splitter  
  40. public:  
  41.   
  42.     /**************************************** 
  43.     Function name:  void CSplitter::SetMinimumSize(const int cx = -1, const int cy = -1) 
  44.     Purpose:        Replaces a view with another in a given pane. 
  45.     Only for static splitters. 
  46.     Arguments:      row, col: pane coords 
  47.     pViewClass: a runtime class of the view 
  48.     size: min size 
  49.     Return value:   TRUE if successful, FALSE otherwise. 
  50.     **************************************/  
  51.     void SetMinimumSize(const int cx = -1, const int cy = -1);  
  52.   
  53.     // Operations  
  54. public:  
  55.     /**************************************** 
  56.     Function name:  void CSplitter::ReplaceView() 
  57.     Purpose:        Replaces a view with another in a given pane. 
  58.     Only for static splitters. 
  59.     Arguments:      row, col: pane coords 
  60.     pViewClass: a runtime class of the view 
  61.     size: min size 
  62.     Return value:   TRUE if successful, FALSE otherwise. 
  63.     **************************************/  
  64.     BOOL ReplaceView(int row, int col, CRuntimeClass* pViewClass, SIZE size);  
  65.   
  66.     /**************************************** 
  67.     Function name:  BOOL CSplitter::EmbedView() 
  68.     Purpose:        Resurrects the former column or row 
  69.     after the floating dlg is closed 
  70.     Arguments:      none 
  71.     Return value:   none 
  72.     **************************************/  
  73.     void EmbedView();  
  74.   
  75.     // overridables  
  76. public:  
  77.   
  78.     /**************************************** 
  79.     Function name:  BOOL CSplitter::SplitRow() 
  80.     Purpose:        Overrides the default function. 
  81.     Arguments:      cyBefore - pos of the split 
  82.     Return value:   TRUE if successful, FALSE otherwise. 
  83.     **************************************/  
  84.     virtual BOOL SplitRow(int cyBefore);  
  85.   
  86.     /**************************************** 
  87.     Function name:  BOOL CSplitter::SplitColumn() 
  88.     Purpose:        Overrides the default function. 
  89.     Arguments:      cxBefore - pos of the split 
  90.     Return value:   TRUE if successful, FALSE otherwise. 
  91.     **************************************/  
  92.     virtual BOOL SplitColumn(int cxBefore);  
  93.   
  94.     /**************************************** 
  95.     Function name:  BOOL CSplitter::DeleteRow() 
  96.     Purpose:        Overrides the default function. 
  97.     Arguments:      rowDelete - row to delete 
  98.     Return value:   none 
  99.     **************************************/  
  100.     virtual void DeleteRow(int rowDelete);  
  101.   
  102.     /**************************************** 
  103.     Function name:  BOOL CSplitter::DeleteColumn() 
  104.     Purpose:        Overrides the default function. 
  105.     Arguments:      colDelete - row to delete 
  106.     Return value:   none 
  107.     **************************************/  
  108.     virtual void DeleteColumn(int colDelete);  
  109.   
  110.     /**************************************** 
  111.     Function name:  BOOL CSplitter::GetActivePane() 
  112.     Purpose:        Overrides the default function. 
  113.     Arguments:      pRow and pCol - coords of the active pane 
  114.     Return value:   the active pane 
  115.  
  116.     Comments:       This function may return active pane 
  117.     that is not in this splitter at all, 
  118.     as opposed to the base class' implementation, 
  119.     which always check for it. In this case, the 
  120.     pRow and pCol will be -1 
  121.     **************************************/  
  122.     virtual CWnd* GetActivePane(int* pRow = NULL, int* pCol = NULL);  
  123.   
  124.     // Implementation  
  125. public:  
  126.     virtual ~CSplitter();  
  127.   
  128.     // Generated message map functions  
  129.     //{{AFX_MSG(CSplitter)  
  130.     afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);  
  131.     afx_msg void OnMouseMove(UINT nFlags, CPoint point);  
  132.     //}}AFX_MSG  
  133.     DECLARE_MESSAGE_MAP()  
  134. };  
  135.   
  136.   
  137. /////////////////////////////////////////////////////////////////////////////  
[cpp] view plain copy
 
  1. // Splitter.cpp : implementation file  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "sample.h"  
  6. #include "Splitter.h"  
  7.   
  8.   
  9. /***************************************************************** 
  10.  
  11. Filename:           Splitter.cpp 
  12. Contents:           Implemetation of CSplitter class 
  13.  
  14. Authors:         
  15. Created date:        
  16. Last Modified date:  
  17. Revision History: 
  18.  
  19. Used by:             
  20. Uses:                
  21. Build Notes: 
  22.  
  23. See Also:            
  24.  
  25. Copyright:      (c) 2015 by All rights reserved.                            
  26.  
  27. *****************************************************************/  
  28.   
  29. // Embedded Version Control String:    
  30. static char *versionstring =    "@(#) Splitter.cpp 8/25/15";  
  31.   
  32. #include "stdafx.h"  
  33. #include "splitter.h"  
  34.   
  35. #ifdef _DEBUG  
  36. #undef THIS_FILE  
  37. static char BASED_CODE THIS_FILE[] = __FILE__;  
  38. #endif  
  39.   
  40. /////////////////////////////////////////////////////////////////////////////  
  41. // CSplitter  
  42.   
  43. IMPLEMENT_DYNCREATE(CSplitter, CSplitterWnd)  
  44.   
  45. CSplitter::CSplitter()  
  46. {   
  47.     m_iSize = 0;  
  48.     // by default, we split vertically  
  49.     m_bHorizontal = FALSE;  
  50.     m_szMinimumSize.cx = -1;// not set  
  51.     m_szMinimumSize.cy = -1;// not set  
  52. }  
  53.   
  54. CSplitter::~CSplitter()  
  55. {                   
  56. }  
  57.   
  58.   
  59. /**************************************** 
  60. Function name:  void CSplitter::ReplaceView() 
  61. Purpose:        Replaces a view with another in a given pane. 
  62. Only for static splitters. 
  63. Arguments:      row, col: pane coords 
  64. pViewClass: a runtime class of the view 
  65. size: min size 
  66. Return value:   TRUE if successful, FALSE otherwise. 
  67. **************************************/  
  68. BOOL CSplitter::ReplaceView(int row, int col, CRuntimeClass* pViewClass, SIZE size)  
  69. {  
  70.     CCreateContext context;  
  71.     BOOL bSetActive;  
  72.   
  73.     if ((GetPane(row,col)->IsKindOf(pViewClass))==TRUE)  
  74.         return FALSE;  
  75.   
  76.   
  77.     // Get pointer to CDocument object so that it can be used in the creation   
  78.     // process of the new view  
  79.     CDocument * pDoc= ((CView *)GetPane(row,col))->GetDocument();  
  80.     CView * pActiveView=GetParentFrame()->GetActiveView();  
  81.     if (pActiveView==NULL || pActiveView==GetPane(row,col))  
  82.         bSetActive=TRUE;  
  83.     else  
  84.         bSetActive=FALSE;  
  85.   
  86.     // set flag so that document will not be deleted when view is destroyed  
  87.     pDoc->m_bAutoDelete=FALSE;      
  88.     // Delete existing view   
  89.     ((CView *) GetPane(row,col))->DestroyWindow();  
  90.     // set flag back to default   
  91.     pDoc->m_bAutoDelete=TRUE;  
  92.   
  93.     // Create new view                        
  94.   
  95.     context.m_pNewViewClass=pViewClass;  
  96.     context.m_pCurrentDoc=pDoc;  
  97.     context.m_pNewDocTemplate=NULL;  
  98.     context.m_pLastView=NULL;  
  99.     context.m_pCurrentFrame=NULL;  
  100.   
  101.     CreateView(row,col,pViewClass,size, &context);  
  102.   
  103.     CView* pNewView = (CView*)GetPane(row, col);  
  104.   
  105.     if (bSetActive==TRUE)  
  106.         GetParentFrame()->SetActiveView(pNewView);  
  107.   
  108.     RecalcLayout();   
  109.     GetPane(row,col)->SendMessage(WM_PAINT);  
  110.   
  111.     return TRUE;  
  112. }  
  113.   
  114. /**************************************** 
  115. Function name:  BOOL CSplitter::SplitRow() 
  116. Purpose:        Overrides the default function. 
  117. Arguments:      cyBefore - pos of the split 
  118. Return value:   TRUE if successful, FALSE otherwise. 
  119. **************************************/  
  120. BOOL CSplitter::SplitRow(int cyBefore)  
  121. {  
  122.     // first, leave only one column  
  123.     while (m_nCols > 1)  
  124.         DeleteColumn(m_nCols - 1);  
  125.   
  126.     BOOL bRet = CSplitterWnd::SplitRow(cyBefore);  
  127.   
  128.     // Show horizontal scroll bar of the upper view window,  
  129.     //  hide all the others.  
  130.     CWnd    *pUpperWnd = GetPane(0, 0);  
  131.     pUpperWnd->ShowScrollBar(SB_VERT, 0);  
  132.     pUpperWnd->ShowScrollBar(SB_HORZ, 1);  
  133.   
  134.     if (m_nRows > 1) {  
  135.         CWnd    *pLowerWnd = GetPane(1, 0);  
  136.         pLowerWnd->ShowScrollBar(SB_VERT, 0);  
  137.         pLowerWnd->ShowScrollBar(SB_HORZ, 0);  
  138.     }  
  139.   
  140.     return bRet;  
  141. }  
  142.   
  143. /**************************************** 
  144. Function name:  BOOL CSplitter::SplitColumn() 
  145. Purpose:        Overrides the default function. 
  146. Arguments:      cxBefore - pos of the split 
  147. Return value:   TRUE if successful, FALSE otherwise. 
  148. **************************************/  
  149. BOOL CSplitter::SplitColumn(int cxBefore)  
  150. {  
  151.     // first, leave only one row  
  152.     while (m_nRows > 1)  
  153.         DeleteRow(m_nRows - 1);  
  154.   
  155.     BOOL bRet = CSplitterWnd::SplitColumn(cxBefore);  
  156.   
  157.     // Show vertical scroll bar of the left view window,  
  158.     //  hide all the others.  
  159.     CWnd    *pLeftWnd = GetPane(0, 0);  
  160.     pLeftWnd->ShowScrollBar(SB_VERT, 1);  
  161.     pLeftWnd->ShowScrollBar(SB_HORZ, 0);  
  162.   
  163.     if (m_nCols > 1) {  
  164.         CWnd    *pRightWnd = GetPane(0, 1);  
  165.         pRightWnd->ShowScrollBar(SB_VERT, 0);  
  166.         pRightWnd->ShowScrollBar(SB_HORZ, 0);  
  167.     }  
  168.     return bRet;  
  169. }  
  170.   
  171. /**************************************** 
  172. Function name:  BOOL CSplitter::DeleteRow() 
  173. Purpose:        Overrides the default function. 
  174. Arguments:      rowDelete - row to delete 
  175. Return value:   none 
  176. **************************************/  
  177. void CSplitter::DeleteRow(int rowDelete)  
  178. {  
  179.     // save the state of the pane before deleting  
  180.     // note: since we always insert it later as a pane #0,  
  181.     // save the size of the pane #0. Later we can save the pane id too.  
  182.     m_bHorizontal = TRUE;  
  183.     int iDummy;  
  184.     GetRowInfo(0, m_iSize, iDummy);  
  185.     CSplitterWnd::DeleteRow(rowDelete);  
  186. }  
  187.   
  188. /**************************************** 
  189. Function name:  BOOL CSplitter::DeleteColumn() 
  190. Purpose:        Overrides the default function. 
  191. Arguments:      colDelete - row to delete 
  192. Return value:   none 
  193. **************************************/  
  194. void CSplitter::DeleteColumn(int colDelete)  
  195. {  
  196.     // save the state of the pane before deleting  
  197.     // note: since we always insert it later as a pane #0,  
  198.     // save the size of the pane #0. Later we can save the pane id too.  
  199.     m_bHorizontal = FALSE;  
  200.     int iDummy;  
  201.     GetColumnInfo(0, m_iSize, iDummy);  
  202.   
  203.     CSplitterWnd::DeleteColumn(colDelete);  
  204. }  
  205.   
  206. /**************************************** 
  207. Function name:  BOOL CSplitter::EmbedView() 
  208. Purpose:        Resurrects the former column or row 
  209. after the floating dlg is closed 
  210. Arguments:      none 
  211. Return value:   none 
  212. **************************************/  
  213. void CSplitter::EmbedView()  
  214. {  
  215.     if (m_bHorizontal && (m_nRows < m_nMaxRows))  
  216.         SplitRow(m_iSize + m_cyBorder);  
  217.     else if (m_nCols < m_nMaxCols)  
  218.         SplitColumn(m_iSize + m_cxBorder);  
  219. }  
  220.   
  221. BEGIN_MESSAGE_MAP(CSplitter, CSplitterWnd)  
  222.     //{{AFX_MSG_MAP(CSplitter)  
  223.     ON_WM_CREATE()  
  224.     ON_WM_MOUSEMOVE()  
  225.     //}}AFX_MSG_MAP  
  226. END_MESSAGE_MAP()  
  227.   
  228.   
  229. int CSplitter::OnCreate(LPCREATESTRUCT lpCreateStruct)   
  230. {  
  231.     if (CSplitterWnd::OnCreate(lpCreateStruct) == -1)  
  232.         return -1;  
  233.   
  234.     RECT ClientRect;  
  235.     if (::GetClientRect(lpCreateStruct->hwndParent, &ClientRect))  
  236.     {  
  237.         m_iSize = (ClientRect.left - ClientRect.right) / 2;  
  238.     }  
  239.   
  240.     return 0;  
  241. }  
  242.   
  243. /**************************************** 
  244. Function name:  BOOL CSplitter::GetActivePane() 
  245. Purpose:        Overrides the default function. 
  246. Arguments:      pRow and pCol - coords of the active pane 
  247. Return value:   the active pane 
  248.  
  249. Comments:       This function may return active pane 
  250. that is not in this splitter at all, 
  251. as opposed to the base class' implementation, 
  252. which always check for it. In this case, the 
  253. pRow and pCol will be -1 
  254. **************************************/  
  255. CWnd* CSplitter::GetActivePane(int* pRow, int* pCol)  
  256. {  
  257.     ASSERT_VALID(this);  
  258.   
  259.     // attempt to use active view of frame window  
  260.     CWnd* pView = NULL;  
  261.     CFrameWnd* pFrameWnd = GetParentFrame();  
  262.     ASSERT_VALID(pFrameWnd);  
  263.     pView = pFrameWnd->GetActiveView();  
  264.   
  265.     // failing that, use the current focus  
  266.     if (pView == NULL)  
  267.         pView = GetFocus();  
  268.   
  269.     // check if the view is in this splitter (it may not),  
  270.     // but don't return NULL if it is not, like the base class does.  
  271.     // instead, just   
  272.     if (pView != NULL && !IsChildPane(pView, pRow, pCol))  
  273.     {  
  274.         if (pRow)  
  275.             *pRow = -1;  
  276.         if (pCol)  
  277.             *pCol = -1;  
  278.     }  
  279.   
  280.     return pView;  
  281. }  
  282.   
  283. void CSplitter::OnMouseMove(UINT nFlags, CPoint point)   
  284. {  
  285.     // TODO: Add your message handler code here and/or call default  
  286.     if(point.y < m_szMinimumSize.cy)  
  287.     {  
  288.         point.y = m_szMinimumSize.cy;  
  289.     }  
  290.     if(point.x < m_szMinimumSize.cx)  
  291.     {  
  292.         point.x = m_szMinimumSize.cx;  
  293.     }  
  294.   
  295.     CSplitterWnd::OnMouseMove(nFlags, point);  
  296. }  
  297.   
  298. /**************************************** 
  299. Function name:  void CSplitter::SetMinimumSize(const int cx = -1, const int cy = -1) 
  300. Purpose:        Replaces a view with another in a given pane. 
  301. Only for static splitters. 
  302. Arguments:      row, col: pane coords 
  303. pViewClass: a runtime class of the view 
  304. size: min size 
  305. Return value:   TRUE if successful, FALSE otherwise. 
  306. **************************************/  
  307. void CSplitter::SetMinimumSize(const int cx, const int cy)  
  308. {   
  309.     m_szMinimumSize.cx = cx;  
  310.     m_szMinimumSize.cy = cy;  
  311. }  

另外还给我们的View类(我们以CViewLeft为例,其他同理)添加右键菜单,添加步骤为:

1.点击资源视图的Menu右键Insert Menu,自动生成IDR_MENU1的菜单(可右键属性修改IDR),点击菜单双击Type Here添加第一个菜单View,然后同样的方法在其下面添加子菜单Horizonal,Vertical,Float,Swap等等,单击菜单即可在VS中看到相应菜单的属性,可以做相应修改;

2.添加菜单完毕,需要显示菜单,在视图类中添加右键响应函数OnRButtonDown,如下:

[cpp] view plain copy
 
  1. // CViewLeft message handlers  
  2.   
  3. void CViewLeft::OnRButtonDown(UINT nFlags, CPoint point)  
  4. {  
  5.     // TODO: Add your message handler code here and/or call default  
  6.   
  7.     CPoint ptScreen = point;//Current Mouse position int view  
  8.     ClientToScreen(&ptScreen);//to Screen  
  9.     CMenu Menu;//define menu  
  10.     if (Menu.LoadMenu(IDR_VIEW_MENU))  
  11.     {  
  12.         CMenu *pSubMenu = Menu.GetSubMenu(0);  
  13.         pSubMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, ptScreen.x, ptScreen.y, this);//shown menu at point  
  14.     }  
  15.       
  16.   
  17.     CView::OnRButtonDown(nFlags, point);  
  18. }  

3.完成2之后右键就可以看到我们添加的右键菜单了,最后一步就是响应菜单了,资源视图中单击相应菜单,右键Add Event Handler,如下所示:

然后完成相应的处理函数即可:

[cpp] view plain copy
 
  1. void CViewLeft::OnViewHorz()  
  2. {  
  3.     // TODO: Add your command handler code here  
  4.     MessageBox(L"Horz command", L"Horz", 0);  
  5. }  
  6.   
  7. void CViewLeft::OnViewVert()  
  8. {  
  9.     // TODO: Add your command handler code here  
  10.     MessageBox(L"Vert command", L"Vert", 0);  
  11. }  
  12.   
  13. void CViewLeft::OnViewFloat()  
  14. {  
  15.     // TODO: Add your command handler code here  
  16.     MessageBox(L"Float command", L"Float", 0);  
  17. }  
  18.   
  19. void CViewLeft::OnViewSwap()  
  20. {  
  21.     // TODO: Add your command handler code here  
  22.     MessageBox(L"Swap command!", L"Swap", 0);  
  23. }  

添加Splitter.h到ChildFrm.h,修改CSplitterWnd为CSplitter,运行即可看到效果如下

Base Class Members

CObject Members

CCmdTarget Members

CWnd Members

Construction

Create

Call to create a dynamic splitter window and attach it to the CSplitterWnd object.创建一个动态的分隔器窗口并将它与一个CSplitterWnd对象连接

CreateStatic

Call to create a static splitter window and attach it to the CSplitterWnd object.创建一个静态的分隔器窗口并将它与一个CSplitterWnd对象连接

CreateView

Call to create a pane in a splitter window.在一个分隔器窗口中创建一个窗格

CSplitterWnd

Call to construct a CSplitterWnd object.构造一个CSplitterWnd对象

Operations

GetColumnCount

Returns the current pane column count.返回当前窗格列的计数值

GetColumnInfo

Returns information on the specified column.返回指定列的信息

GetPane

Returns the pane at the specified row and column.返回位于指定行和列处的窗格

GetRowCount

Returns the current pane row count.返回当前窗格行的计数值

GetRowInfo

Returns information on the specified row.返回指定行的信息

GetScrollStyle

Returns the shared scroll-bar style.返回共享滚动条的风格

IdFromRowCol

Returns the child window ID of the pane at the specified row and column.返回位于指定行和列处的窗格的子窗口ID

IsTracking

Determines if splitter bar is currently being moved.判定分隔条是否正在移动

IsChildPane

Call to determine whether the window is currently a child pane of this splitter window.确定窗口是否是此分隔器窗口的当前子窗格

RecalcLayout

Call to redisplay the splitter window after adjusting row or column size.在调整行或列尺寸后调用此函数来重新显示该分隔器窗口

SetColumnInfo

Call to set the specified column information.设置指定列的信息

SetRowInfo

Call to set the specified row information.设置指定行的信息

SetScrollStyle

Specifies the new scroll-bar style for the splitter window's shared scroll-bar support.为分隔器窗口的共享滚动条指定新的滚动条风格

Overridables

ActivateNext

Performs the Next Pane or Previous Pane command.执行Next Pane或Previous Pane命令

CanActivateNext

Checks to see if the Next Pane or Previous Pane command is currently possible.检查Next Pane或Previous Pane命令当前是否有效

CreateScrollBarCtrl

Creates a shared scroll bar control.创建一个共享的滚动条控件

DeleteColumn

Deletes a column from the splitter window.从分隔器窗口中删除一列

DeleteRow

Deletes a row from the splitter window.从分隔器窗口中删除一行

DeleteView

Deletes a view from the splitter window.从分隔器窗口中删除一个视图

DoKeyboardSplit

Performs the keyboard split command, usually "Window Split."执行键盘分隔命令,通常是“Window Split”

DoScroll

Performs synchronized scrolling of split windows.执行分隔窗口的同步滚动

DoScrollBy

Scrolls split windows by a given number of pixels.将分隔窗口滚动给定的像素数

GetActivePane

Determines the active pane from the focus or active view in the frame.根据焦点或框架中的活动视图来判定活动窗格

OnDrawSplitter

Renders an image of a split window.绘制一个分隔器窗口的图像

OnInvertTracker

Renders the image of a split window to be the same size and shape as the frame window.绘制一个分隔器窗口的图像,使它具有与框架窗口相同的大小和形状

SetActivePane

Sets a pane to be the active one in the frame.在框架中设置一个活动窗格

SplitColumn

Indicates where a frame window splits vertically.表明一个框架窗口是否是垂直分隔的

SplitRow

Indicates where a frame window splits horizontally.表明一个框架窗口是否是水平分隔的

 
需要定制属于自己的分割窗口可以根据情况重写Overridables相应方法。
原文地址:https://www.cnblogs.com/vipwtl/p/5681844.html