MFC单文档绘图(一)——窗体分割

1. VS2010新建MFC单文档项目


2. 添加基于 CSplitterWnd 基类的类CSplitter类(不直接使用CSplitterWnd成员变量,方便对分割线的消息事件处理)

class CSplitter : public CSplitterWnd
{
	DECLARE_DYNAMIC(CSplitter)

public:
	CSplitter();
	virtual ~CSplitter();

protected:
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
};

其中OnLButtonDown和OnMouseMove函数可以修改你对分割条的消息响应。如屏蔽鼠标左键和移动消息可如下:

void CSplitter::OnLButtonDown(UINT nFlags, CPoint point)
{
	return;
	//CSplitterWnd::OnLButtonDown(nFlags, point);
}


void CSplitter::OnMouseMove(UINT nFlags, CPoint point)
{
	return;
	//CSplitterWnd::OnMouseMove(nFlags, point);
}
还可以在构造函数中对分割线进行宽度等配置:

CSplitter::CSplitter()
{
	m_cxSplitter = 1;
	m_cySplitter = 1;
	m_cxSplitterGap = 1;
	m_cySplitterGap = 1;
	m_cxBorder = 0;
	m_cyBorder = 0;
}

3. 在CMainFrame类中添加成员变量

public:
	CSplitter			m_wndSplitter;

添加Dialog,Border为none,Style为Child(否则报错viewform.cpp line:91的Debug Assertion Failed错误),并创建基于CFormView基类的类ProcessArea

class ProcessArea : public CFormView
{
	DECLARE_DYNCREATE(ProcessArea)

public:
	ProcessArea();           // 动态创建所使用的受保护的构造函数
	virtual ~ProcessArea();

public:
	enum { IDD = IDD_PROCESS_AREA };
#ifdef _DEBUG
	virtual void AssertValid() const;
……


4. 为CMainFrame类添加OnCreateClient函数(类向导)

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
	
	// TODO: 在此添加专用代码和/或调用基类
	if(!m_wndSplitter.CreateStatic(this,1,2))
	{
		return FALSE;
	}
	CRect rect;
	GetClientRect(&rect);
	if(!m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(ProcessArea),CSize(400,rect.Height()),pContext)||
	!m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CCADProjectView), CSize(rect.Width() - 400,rect.Height()),pContext))
	{
		return FALSE;
	}

	SetActiveView((CCADProjectView*)m_wndSplitter.GetPane(0,0)); //指定类视图

	m_bInitSplitter = TRUE;

	return TRUE;
	//return CFrameWndEx::OnCreateClient(lpcs, pContext);//导致窗口重绘
}
CreateStatic函数创建一个一行两列的静态窗口,CreateView函数给以上创建的对应窗口根据对应的类创建需要的窗口,SetActiveView函数设定默认激活的窗口。效果如下图(tabctrl控件是后来加),如果需要CSplitter类型的成员变量,再对需要分割的窗体进行拆分。(详情)

MFC单文档绘图(一)——窗体分割_第1张图片


5. 放大缩小自动调整:放大缩小时,可能会出现分割的窗口消失或不完全显示问题,需要进行调整。

添加WM_SIZE消息,重新按要求布局分割的窗口。

void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
	CFrameWndEx::OnSize(nType, cx, cy);

	// TODO: 在此处添加消息处理程序代码
	CRect rect;
	GetClientRect(&rect);
	if (m_bInitSplitter && nType != SIZE_MINIMIZED)
	{
		m_wndSplitter.SetRowInfo(0, cy, 0);
		m_wndSplitter.SetColumnInfo(0, rect.Width() - 400, 100);
		m_wndSplitter.SetColumnInfo(1, 400, 100);
		m_wndSplitter.RecalcLayout();
	}
}
详情

你可能感兴趣的:(MFC,C++)