我按照以前的教材编了一个视图静态分割的程序 先分成上下两个视图,然后上面的视图再分割成左右两个视图,编译时没有问题,但运行时总是莫名其妙的报错。
问题代码如下:
下部视图类的代码:
// CBottomView 视图class CBottomView : public CEditView
{
DECLARE_DYNCREATE(CBottomView)
protected:
CBottomView();           // 动态创建所使用的受保护的构造函数
virtual ~CBottomView();
public:
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endif
protected:
DECLARE_MESSAGE_MAP()
public:
virtual void OnInitialUpdate();
protected:
virtual void OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/);
};/ BottomView.cpp : 实现文件
重载函数:
// CBottomView 消息处理程序void CBottomView::OnInitialUpdate()
{
CEditView::OnInitialUpdate(); // TODO: 在此添加专用代码和/或调用基类
CEdit& m_Edit=GetEditCtrl();
m_Edit.SetWindowText(L"等待用户输入");
m_Edit.EnableWindow(FALSE);
}void CBottomView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
// TODO: 在此添加专用代码和/或调用基类
CMutiViewDemoDoc* pDoc=(CMutiViewDemoDoc*)GetDocument();
if(pDoc->add)
{
CString str;
str=L"添加了学号"+pDoc->infoArray[0].GetAt(0)+L"的学生信息";
CEdit & m_Edit=GetEditCtrl();
m_Edit.SetWindowTextW(str);
}
}左上部分视图的代码:
// CLeftView 窗体视图class CLeftView : public CFormView
{
DECLARE_DYNCREATE(CLeftView)protected:
CLeftView();           // 动态创建所使用的受保护的构造函数
virtual ~CLeftView();public:
enum { IDD = IDD_DIALOG1 };
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endifprotected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持 DECLARE_MESSAGE_MAP()
public:
CString m_Number;
CString m_Name;
CString m_Major;
CString m_Address;
afx_msg void OnBnClickedCheckin();
};
/ LeftView.cpp : 实现文件
// CLeftView 消息处理程序void CLeftView::OnBnClickedCheckin()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
if(m_Number.IsEmpty()||m_Name.IsEmpty())
{
AfxMessageBox(L"学号和姓名不能为空");
return;
}
CMutiViewDemoDoc* pDoc=(CMutiViewDemoDoc*)GetDocument();
pDoc->infoArray[0].InsertAt(0,m_Number);
pDoc->infoArray[1].InsertAt(0,m_Name);
pDoc->infoArray[2].InsertAt(0,m_Major);
pDoc->infoArray[3].InsertAt(0,m_Address);
pDoc->add=TRUE;
pDoc->UpdateAllViews(NULL);
m_Number=_T("");
m_Name=_T("");
m_Major=_T("");
m_Address=_T("");
UpdateData(FALSE);
}右上部分视图类代码:
#include"MutiViewDemoDoc.h"
// CTopView 视图class CTopView : public CListView
{
DECLARE_DYNCREATE(CTopView)protected:
CTopView();           // 动态创建所使用的受保护的构造函数
virtual ~CTopView();public:
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endifprotected:
DECLARE_MESSAGE_MAP()
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
public:
virtual void OnInitialUpdate();
protected:
virtual void OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/);
};#include "stdafx.h"
#include "MutiViewDemo.h"
#include "TopView.h"
// CTopView
// CTopView 消息处理程序BOOL CTopView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此添加专用代码和/或调用基类
cs.style=cs.style|LVS_REPORT;
return CListView::PreCreateWindow(cs);
}void CTopView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
CString m_ColumnLabelStr[5]={L"学号",L"姓名",L"专业",L"籍贯"}; // TODO: 在此添加专用代码和/或调用基类
CListCtrl& listCtrl=GetListCtrl();
listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_UNDERLINEHOT);
int width[5]={80,80,110,150};
for(int i=0;i<4;i++)
{
listCtrl.InsertColumn(i,m_ColumnLabelStr[i],LVCFMT_LEFT,width[i]);
}
}void CTopView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
// TODO: 在此添加专用代码和/或调用基类
CMutiViewDemoDoc* pDoc=(CMutiViewDemoDoc*)GetDocument();
if(pDoc->add)
{
CListCtrl & m_listCtrl=GetListCtrl();
m_listCtrl.DeleteAllItems();
for(int i=0;i<pDoc->infoArray[0].GetSize();i++)
{
m_listCtrl.InsertItem(i,pDoc->infoArray[0].GetAt(i));
m_listCtrl.SetItemText(i,1,pDoc->infoArray[1].GetAt(i));
m_listCtrl.SetItemText(i,2,pDoc->infoArray[1].GetAt(i));
m_listCtrl.SetItemText(i,3,pDoc->infoArray[1].GetAt(i));
}
}}
MainFrm类的代码:
#include"MutiViewDemoView.h"#pragma onceclass CMainFrame : public CFrameWnd
{

protected: // 仅从序列化创建
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
// 属性
public:// 操作
public:// 重写
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);// 实现
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endifprotected:  // 控件条嵌入成员
CStatusBar  m_wndStatusBar;
CToolBar    m_wndToolBar;
CSplitterWnd m_Splitter;(自行添加的数据)
// 生成的消息映射函数
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP()
virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
};MainFrm类实现文件中修改部分:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;

if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("未能创建工具栏\n");
return -1;      // 未能创建
} if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
  sizeof(indicators)/sizeof(UINT)))
{
TRACE0("未能创建状态栏\n");
return -1;      // 未能创建
} // TODO: 如果不需要可停靠工具栏,则删除这三行
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar); return 0;
}
重载了OnCreateClient函数,进行上下视图的分割
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: 在此添加专用代码和/或调用基类
CRect rt;
GetClientRect(&rt);
m_Splitter.CreateStatic(this,2,1);
m_Splitter.CreateView(0,0,RUNTIME_CLASS(CMutiViewDemoView),CSize(rt.Width(),rt.Height()-rt.Height()/5),pContext);
m_Splitter.CreateView(1,0,RUNTIME_CLASS(CBottomView),CSize(rt.Width(),rt.Height()/5),pContext);
return TRUE; //return CFrameWnd::OnCreateClient(lpcs, pContext);//不在调用基类函数,但是会出错}View视图类代码:class CMutiViewDemoView : public CView
{
protected: // 仅从序列化创建
CMutiViewDemoView();
DECLARE_DYNCREATE(CMutiViewDemoView)
CSplitterWnd m_Splitter1;// 属性(自定义变量由于窗口分割)
public:
CMutiViewDemoDoc* GetDocument() const;// 操作
public:// 重写
public:
virtual void OnDraw(CDC* pDC);  // 重写以绘制该视图
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);// 实现
public:
virtual ~CMutiViewDemoView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endifprotected:// 生成的消息映射函数
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
};#ifndef _DEBUG  // MutiViewDemoView.cpp 中的调试版本
inline CMutiViewDemoDoc* CMutiViewDemoView::GetDocument() const
   { return reinterpret_cast<CMutiViewDemoDoc*>(m_pDocument); }
#endif
实现文件中修改部分:
添加OnCreate函数,进行左上部分视图和右上部分视图分割:int CMutiViewDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1; // TODO:  在此添加您专用的创建代码
CRect rt;
GetClientRect(&rt);
CCreateContext *pContext=(CCreateContext*)lpCreateStruct->lpCreateParams;
m_Splitter1.CreateStatic(this,1,2);
m_Splitter1.CreateView(0,0,RUNTIME_CLASS(CLeftView),CSize(rt.Width()/4,rt.Height()),pContext);
m_Splitter1.CreateView(0,1,RUNTIME_CLASS(CTopView),CSize(1,1),pContext);
return 0;
}
添加OnSize函数:void CMutiViewDemoView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
CRect rt;
GetClientRect(&rt);
int x =rt.Width();
int y=rt.Height();
m_Splitter1.MoveWindow(0,0,x,y+3);
m_Splitter1.SetColumnInfo(0,x/4,0);
m_Splitter1.SetColumnInfo(1,x-x/4,0);
m_Splitter1.RecalcLayout(); // TODO: 在此处添加消息处理程序代
}运行时总是显示错误,据图错误位置在红色代码地方,调试跟踪到错误的地方原因是
CWnd* CSplitterWnd::GetPane(int row, int col) const
{
ASSERT_VALID(this);CWnd* pView = GetDlgItem(IdFromRowCol(row, col));
ASSERT(pView != NULL); // panes can be a CWnd, but are usually CViews(此句错误)
return pView;
}
但如果我在CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
函数中将return TRUE语句去掉,并将//return CFrameWnd::OnCreateClient(lpcs, pContext);的注释去掉后,就不会出错,但是窗口只分成左右两个窗口了,下部的视图就没有了,百思不得其解,还请高手指点一下