CSplitterWnd窗口分割之——动态静态嵌套分割(二)

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

       最终效果如下:

CSplitterWnd窗口分割之——动态静态嵌套分割(二)_第1张图片

CSplitterWnd窗口分割之——动态静态嵌套分割(二)_第2张图片

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


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

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

// Attributes
protected:
	CSplitterWnd m_wndSplitter1;
	CSplitterWnd m_wndSplitter;

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

修改OnCreateClient方法如下:

BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
	////// Create 2*2 nested dynamic splitter
	//// 	// TODO: Add your specialized code here and/or call the base class
	//// 	return m_wndSplitter.Create(this,
	//// 		2, 2,			// TODO: adjust the number of rows, columns
	//// 		CSize(10, 10),	// TODO: adjust the minimum pane size
	//// 		pContext);
	//// 	//return CMDIChildWnd::OnCreateClient(lpcs, pContext);

	//// Create a  static splitter with 1 rows, 3 columns
	//m_wndSplitter.CreateStatic(this, 1, 3);	// create a splitter with 1 rows, 3 columns
	//m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CViewLeft), CSize(0, 0), pContext);	// create view with 0 rows, 0 columns
	//m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CViewMiddle), CSize(0, 0), pContext);	// create view with 0 rows, 1 columns
	//m_wndSplitter.CreateView(0, 2, RUNTIME_CLASS(CViewRight), CSize(0, 0), pContext);	// create view with 0 rows, 2 columns

	//m_wndSplitter.SetColumnInfo(0, 400, 10);	// set the width of column, 0 column, ideal width is 200dip,min width is 10dip
	//m_wndSplitter.SetColumnInfo(1, 400, 10);	// set the width of column, 0 column, ideal width is 200dip,min width is 10dip
	//m_wndSplitter.SetColumnInfo(2, 400, 10);	// set the width of column, 0 column, ideal width is 200dip,min width is 10dip
	//// m_wndSplitter.SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);

	//Create a static splitter with 2 rows,1 columns
	if (!m_wndSplitter.CreateStatic(this, 2, 1, WS_CHILD|WS_VISIBLE))
	{
		TRACE("Failed to Create StaticSplitter\n");
		return NULL;
	}
	//set view
	pContext->m_pNewViewClass = RUNTIME_CLASS(CViewRight);
	
	CRect rect;     
	this->GetClientRect(&rect);
	SIZE size;
	size.cx = rect.Width();
	size.cy = rect.Height()/3;

	m_wndSplitter.CreateView(0, 0, pContext->m_pNewViewClass, size, pContext);
	//m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CViewLeft), CSize(0, 0), pContext);	// create view with 0 rows, 0 columns
	//m_wndSplitter.SetRowInfo(0, 200, 10);	// set the width of column, 0 column, ideal width is 250dip,min width is 10dip


	pContext->m_pNewViewClass = RUNTIME_CLASS(CViewMiddle);
	if (!m_wndSplitter1.Create(
		&m_wndSplitter,     // our parent window is the first splitter
		2, 2,          // TODO: adjust the number of rows, columns
		CSize(10, 10), // TODO: adjust the minimum pane size
		pContext,
		WS_CHILD|WS_VISIBLE|SPLS_DYNAMIC_SPLIT|WS_HSCROLL|WS_VSCROLL,
		m_wndSplitter.IdFromRowCol(1, 0)))
	{
		TRACE("Failed to create the nested dynamic splitter\n");
	}

	return TRUE;
}

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

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

void CViewLeft::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
	CPaintDC* dc = (CPaintDC*)pDC;
	CRect rect,fillrect;
	CBrush brush;
	brush.CreateSolidBrush(RGB(255, 0, 0));
	this->GetClientRect(&rect);
	dc->FillRect(&rect,&brush);
	brush.DeleteObject();
}

void CViewMiddle::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
	CPaintDC* dc = (CPaintDC*)pDC;
	CRect rect,fillrect;
	CBrush brush;
	brush.CreateSolidBrush(RGB(0, 255, 0));
	this->GetClientRect(&rect);
	dc->FillRect(&rect,&brush);
	brush.DeleteObject();
}


void CViewRight::OnDraw(CDC* pDC)
{
 CDocument* pDoc = GetDocument();
 // TODO: add draw code here
 CPaintDC* dc = (CPaintDC*)pDC;
 CRect rect,fillrect;
 CBrush brush;
 brush.CreateSolidBrush(RGB(0, 0, 255));
 this->GetClientRect(&rect);
 dc->FillRect(&rect,&brush);
 brush.DeleteObject();
}


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


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

/*****************************************************************

Filename:			Splitter.h
Contents:			Implemetation of CSplitter class

Authors:	
Created date: 	  	
Last Modified date:	
Revision History: 

Used by:			
Uses:				
Build Notes:		

See Also:			

Copyright: 		(c) 2015 by All rights reserved.                           

*****************************************************************/

#pragma once

// CSplitter

class CSplitter : public CSplitterWnd
{
	DECLARE_DYNCREATE(CSplitter)

	// Attributes
public:
	// this var saves the size of the pane before floating
	int m_iSize;
	// this var saves the pane orientation before floating
	BOOL m_bHorizontal;

	SIZE m_szMinimumSize;
public:
	CSplitter();
	// added funciton for customize the splitter
public:

	/****************************************
	Function name:	void CSplitter::SetMinimumSize(const int cx = -1, const int cy = -1)
	Purpose:		Replaces a view with another in a given pane.
	Only for static splitters.
	Arguments:		row, col: pane coords
	pViewClass: a runtime class of the view
	size: min size
	Return value:	TRUE if successful, FALSE otherwise.
	**************************************/
	void SetMinimumSize(const int cx = -1, const int cy = -1);

	// Operations
public:
	/****************************************
	Function name:	void CSplitter::ReplaceView()
	Purpose:		Replaces a view with another in a given pane.
	Only for static splitters.
	Arguments:		row, col: pane coords
	pViewClass: a runtime class of the view
	size: min size
	Return value:	TRUE if successful, FALSE otherwise.
	**************************************/
	BOOL ReplaceView(int row, int col, CRuntimeClass* pViewClass, SIZE size);

	/****************************************
	Function name:	BOOL CSplitter::EmbedView()
	Purpose:		Resurrects the former column or row
	after the floating dlg is closed
	Arguments:		none
	Return value:	none
	**************************************/
	void EmbedView();

	// overridables
public:

	/****************************************
	Function name:	BOOL CSplitter::SplitRow()
	Purpose:		Overrides the default function.
	Arguments:		cyBefore - pos of the split
	Return value:	TRUE if successful, FALSE otherwise.
	**************************************/
	virtual BOOL SplitRow(int cyBefore);

	/****************************************
	Function name:	BOOL CSplitter::SplitColumn()
	Purpose:		Overrides the default function.
	Arguments:		cxBefore - pos of the split
	Return value:	TRUE if successful, FALSE otherwise.
	**************************************/
	virtual BOOL SplitColumn(int cxBefore);

	/****************************************
	Function name:	BOOL CSplitter::DeleteRow()
	Purpose:		Overrides the default function.
	Arguments:		rowDelete - row to delete
	Return value:	none
	**************************************/
	virtual void DeleteRow(int rowDelete);

	/****************************************
	Function name:	BOOL CSplitter::DeleteColumn()
	Purpose:		Overrides the default function.
	Arguments:		colDelete - row to delete
	Return value:	none
	**************************************/
	virtual void DeleteColumn(int colDelete);

	/****************************************
	Function name:	BOOL CSplitter::GetActivePane()
	Purpose:		Overrides the default function.
	Arguments:		pRow and pCol - coords of the active pane
	Return value:	the active pane

	Comments:		This function may return active pane
	that is not in this splitter at all,
	as opposed to the base class' implementation,
	which always check for it. In this case, the
	pRow and pCol will be -1
	**************************************/
	virtual CWnd* GetActivePane(int* pRow = NULL, int* pCol = NULL);

	// Implementation
public:
	virtual ~CSplitter();

	// Generated message map functions
	//{{AFX_MSG(CSplitter)
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};


/////////////////////////////////////////////////////////////////////////////

// Splitter.cpp : implementation file
//

#include "stdafx.h"
#include "sample.h"
#include "Splitter.h"


/*****************************************************************

Filename:			Splitter.cpp
Contents:			Implemetation of CSplitter class

Authors:		
Created date: 	  	
Last Modified date:	
Revision History:

Used by:			
Uses:				
Build Notes:

See Also:			

Copyright: 		(c) 2015 by All rights reserved.                           

*****************************************************************/

// Embedded Version Control String:  
static char *versionstring =	"@(#) Splitter.cpp 8/25/15";

#include "stdafx.h"
#include "splitter.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSplitter

IMPLEMENT_DYNCREATE(CSplitter, CSplitterWnd)

CSplitter::CSplitter()
{ 
	m_iSize = 0;
	// by default, we split vertically
	m_bHorizontal = FALSE;
	m_szMinimumSize.cx = -1;// not set
	m_szMinimumSize.cy = -1;// not set
}

CSplitter::~CSplitter()
{                 
}


/****************************************
Function name:	void CSplitter::ReplaceView()
Purpose:		Replaces a view with another in a given pane.
Only for static splitters.
Arguments:		row, col: pane coords
pViewClass: a runtime class of the view
size: min size
Return value:	TRUE if successful, FALSE otherwise.
**************************************/
BOOL CSplitter::ReplaceView(int row, int col, CRuntimeClass* pViewClass, SIZE size)
{
	CCreateContext context;
	BOOL bSetActive;

	if ((GetPane(row,col)->IsKindOf(pViewClass))==TRUE)
		return FALSE;


	// Get pointer to CDocument object so that it can be used in the creation 
	// process of the new view
	CDocument * pDoc= ((CView *)GetPane(row,col))->GetDocument();
	CView * pActiveView=GetParentFrame()->GetActiveView();
	if (pActiveView==NULL || pActiveView==GetPane(row,col))
		bSetActive=TRUE;
	else
		bSetActive=FALSE;

	// set flag so that document will not be deleted when view is destroyed
	pDoc->m_bAutoDelete=FALSE;    
	// Delete existing view 
	((CView *) GetPane(row,col))->DestroyWindow();
	// set flag back to default 
	pDoc->m_bAutoDelete=TRUE;

	// Create new view                      

	context.m_pNewViewClass=pViewClass;
	context.m_pCurrentDoc=pDoc;
	context.m_pNewDocTemplate=NULL;
	context.m_pLastView=NULL;
	context.m_pCurrentFrame=NULL;

	CreateView(row,col,pViewClass,size, &context);

	CView* pNewView = (CView*)GetPane(row, col);

	if (bSetActive==TRUE)
		GetParentFrame()->SetActiveView(pNewView);

	RecalcLayout(); 
	GetPane(row,col)->SendMessage(WM_PAINT);

	return TRUE;
}

/****************************************
Function name:	BOOL CSplitter::SplitRow()
Purpose:		Overrides the default function.
Arguments:		cyBefore - pos of the split
Return value:	TRUE if successful, FALSE otherwise.
**************************************/
BOOL CSplitter::SplitRow(int cyBefore)
{
	// first, leave only one column
	while (m_nCols > 1)
		DeleteColumn(m_nCols - 1);

	BOOL bRet = CSplitterWnd::SplitRow(cyBefore);

	// Show horizontal scroll bar of the upper view window,
	//	hide all the others.
	CWnd	*pUpperWnd = GetPane(0, 0);
	pUpperWnd->ShowScrollBar(SB_VERT, 0);
	pUpperWnd->ShowScrollBar(SB_HORZ, 1);

	if (m_nRows > 1) {
		CWnd	*pLowerWnd = GetPane(1, 0);
		pLowerWnd->ShowScrollBar(SB_VERT, 0);
		pLowerWnd->ShowScrollBar(SB_HORZ, 0);
	}

	return bRet;
}

/****************************************
Function name:	BOOL CSplitter::SplitColumn()
Purpose:		Overrides the default function.
Arguments:		cxBefore - pos of the split
Return value:	TRUE if successful, FALSE otherwise.
**************************************/
BOOL CSplitter::SplitColumn(int cxBefore)
{
	// first, leave only one row
	while (m_nRows > 1)
		DeleteRow(m_nRows - 1);

	BOOL bRet = CSplitterWnd::SplitColumn(cxBefore);

	// Show vertical scroll bar of the left view window,
	//	hide all the others.
	CWnd	*pLeftWnd = GetPane(0, 0);
	pLeftWnd->ShowScrollBar(SB_VERT, 1);
	pLeftWnd->ShowScrollBar(SB_HORZ, 0);

	if (m_nCols > 1) {
		CWnd	*pRightWnd = GetPane(0, 1);
		pRightWnd->ShowScrollBar(SB_VERT, 0);
		pRightWnd->ShowScrollBar(SB_HORZ, 0);
	}
	return bRet;
}

/****************************************
Function name:	BOOL CSplitter::DeleteRow()
Purpose:		Overrides the default function.
Arguments:		rowDelete - row to delete
Return value:	none
**************************************/
void CSplitter::DeleteRow(int rowDelete)
{
	// save the state of the pane before deleting
	// note: since we always insert it later as a pane #0,
	// save the size of the pane #0. Later we can save the pane id too.
	m_bHorizontal = TRUE;
	int iDummy;
	GetRowInfo(0, m_iSize, iDummy);
	CSplitterWnd::DeleteRow(rowDelete);
}

/****************************************
Function name:	BOOL CSplitter::DeleteColumn()
Purpose:		Overrides the default function.
Arguments:		colDelete - row to delete
Return value:	none
**************************************/
void CSplitter::DeleteColumn(int colDelete)
{
	// save the state of the pane before deleting
	// note: since we always insert it later as a pane #0,
	// save the size of the pane #0. Later we can save the pane id too.
	m_bHorizontal = FALSE;
	int iDummy;
	GetColumnInfo(0, m_iSize, iDummy);

	CSplitterWnd::DeleteColumn(colDelete);
}

/****************************************
Function name:	BOOL CSplitter::EmbedView()
Purpose:		Resurrects the former column or row
after the floating dlg is closed
Arguments:		none
Return value:	none
**************************************/
void CSplitter::EmbedView()
{
	if (m_bHorizontal && (m_nRows < m_nMaxRows))
		SplitRow(m_iSize + m_cyBorder);
	else if (m_nCols < m_nMaxCols)
		SplitColumn(m_iSize + m_cxBorder);
}

BEGIN_MESSAGE_MAP(CSplitter, CSplitterWnd)
	//{{AFX_MSG_MAP(CSplitter)
	ON_WM_CREATE()
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


int CSplitter::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CSplitterWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	RECT ClientRect;
	if (::GetClientRect(lpCreateStruct->hwndParent, &ClientRect))
	{
		m_iSize = (ClientRect.left - ClientRect.right) / 2;
	}

	return 0;
}

/****************************************
Function name:	BOOL CSplitter::GetActivePane()
Purpose:		Overrides the default function.
Arguments:		pRow and pCol - coords of the active pane
Return value:	the active pane

Comments:		This function may return active pane
that is not in this splitter at all,
as opposed to the base class' implementation,
which always check for it. In this case, the
pRow and pCol will be -1
**************************************/
CWnd* CSplitter::GetActivePane(int* pRow, int* pCol)
{
	ASSERT_VALID(this);

	// attempt to use active view of frame window
	CWnd* pView = NULL;
	CFrameWnd* pFrameWnd = GetParentFrame();
	ASSERT_VALID(pFrameWnd);
	pView = pFrameWnd->GetActiveView();

	// failing that, use the current focus
	if (pView == NULL)
		pView = GetFocus();

	// check if the view is in this splitter (it may not),
	// but don't return NULL if it is not, like the base class does.
	// instead, just 
	if (pView != NULL && !IsChildPane(pView, pRow, pCol))
	{
		if (pRow)
			*pRow = -1;
		if (pCol)
			*pCol = -1;
	}

	return pView;
}

void CSplitter::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(point.y < m_szMinimumSize.cy)
	{
		point.y = m_szMinimumSize.cy;
	}
	if(point.x < m_szMinimumSize.cx)
	{
		point.x = m_szMinimumSize.cx;
	}

	CSplitterWnd::OnMouseMove(nFlags, point);
}

/****************************************
Function name:	void CSplitter::SetMinimumSize(const int cx = -1, const int cy = -1)
Purpose:		Replaces a view with another in a given pane.
Only for static splitters.
Arguments:		row, col: pane coords
pViewClass: a runtime class of the view
size: min size
Return value:	TRUE if successful, FALSE otherwise.
**************************************/
void CSplitter::SetMinimumSize(const int cx, const int cy)
{ 
	m_szMinimumSize.cx = cx;
	m_szMinimumSize.cy = cy;
}


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

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

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

// CViewLeft message handlers

void CViewLeft::OnRButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default

	CPoint ptScreen = point;//Current Mouse position int view
	ClientToScreen(&ptScreen);//to Screen
	CMenu Menu;//define menu
	if (Menu.LoadMenu(IDR_VIEW_MENU))
	{
		CMenu *pSubMenu = Menu.GetSubMenu(0);
		pSubMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, ptScreen.x, ptScreen.y, this);//shown menu at point
	}
	

	CView::OnRButtonDown(nFlags, point);
}

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

CSplitterWnd窗口分割之——动态静态嵌套分割(二)_第3张图片CSplitterWnd窗口分割之——动态静态嵌套分割(二)_第4张图片

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

void CViewLeft::OnViewHorz()
{
	// TODO: Add your command handler code here
	MessageBox(L"Horz command", L"Horz", 0);
}

void CViewLeft::OnViewVert()
{
	// TODO: Add your command handler code here
	MessageBox(L"Vert command", L"Vert", 0);
}

void CViewLeft::OnViewFloat()
{
	// TODO: Add your command handler code here
	MessageBox(L"Float command", L"Float", 0);
}

void CViewLeft::OnViewSwap()
{
	// TODO: Add your command handler code here
	MessageBox(L"Swap command!", L"Swap", 0);
}


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

CSplitterWnd窗口分割之——动态静态嵌套分割(二)_第5张图片

CSplitterWnd窗口分割之——动态静态嵌套分割(二)_第6张图片

CSplitterWnd窗口分割之——动态静态嵌套分割(二)_第7张图片

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相应方法。
下一篇将继续介绍静态动态嵌套分割以及动态分割后的窗口如何绑定不同的视图,我们目前看到的是动态分割之后的窗口共用一个视图,如何让(0, 0),(0, 1),(1, 0), (1, 1)分别显示不同的视图呢?预知后事如何且听下回分解。。。








你可能感兴趣的:(MFC)