2014-11-21 34 views
1

我有一个MFC程序写入,读取文件,存储数据,并将其作为文本绘制在客户端视图上。用菜单按钮分割两个视图? (MFC)

我想制作一个菜单按钮View-> Split,将客户区域拆分为两个,分别滚动显示相同数据的视图。

我在网上看到了一些关于CWndSplitter的内容,并通过一些文档进行了阅读,但没有一篇文章证明是有用的,因为他们谈论了使用OnCreate并删除默认视图以使其工作。这不是一个选项。我想保留默认视图,但如果用户单击按钮将其分成两部分。

我目前创建了一个CWndSplitter成员变量,并在SDI-1View.cpp中定义了一个菜单按钮事件处理程序。被调用时,它绝对不会导致屏幕闪烁,并且第二次点击会使程序崩溃。

void CSDI1View::OnViewSplit32778() 
{ 
// TODO: Add your command handler code here 

/* 
int rows = 2; 
int columns = 1; 
if (!m_wndSplitter.CreateStatic(this, rows, columns)) 
    return; 

if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CSDI1View), CSize(100, 100), NULL) || 
    (!m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CSDI1View), CSize(100, 100), NULL))) 
{ 
    m_wndSplitter.DestroyWindow(); 
    return; 
} 
*/ 
} 

任何人都可以告诉我什么将客户端视图分成两半的正常方法是?我只想将它集成到事件处理程序中。 任何帮助将不胜感激。

谢谢。

--------------------------------编辑------------- ---------------------

我现在在我的Split按钮事件处理程序中有以下代码,这要归功于xMRi提供的轮廓,但它仍然是工作不正常...

void CMainFrame::OnViewSplit() 
{ 
// TODO: Add your command handler code here 
//calculate client size 
CRect cr; 
GetClientRect(&cr); 

if (!m_mainSplitter.CreateStatic(this, 2, 1)) 
{ 
    MessageBox(_T("Error setting up splitter frames! (CreateStatic)"), 
     _T("Init Error!"), MB_OK | MB_ICONERROR); 
    return; 
} 

// Set the parent of the splitter window to the current view 
CSDI1View * view = CSDI1View::GetView(); 
m_mainSplitter.SetParent(this); 
view->SetParent(&m_mainSplitter); 

// Create a CCreateContext 
CCreateContext cc; 
CRuntimeClass* prt = RUNTIME_CLASS(CSDI1View); 
cc.m_pNewViewClass = prt; 
cc.m_pCurrentDoc = view->GetDocument(); 
cc.m_pNewDocTemplate = NULL; 
cc.m_pLastView = NULL; 
cc.m_pCurrentFrame = this; 

if (!m_mainSplitter.CreateView(0, 0, 
    cc.m_pNewViewClass, 
    CSize(cr.Width(), cr.Height()/2), &cc)) 
{ 
    MessageBox(_T("Error setting up splitter frames! (CreateView 1)"), 
     _T("Init Error!"), MB_OK | MB_ICONERROR); 
    return; 
} 

if (!m_mainSplitter.CreateView(1, 0, 
    cc.m_pNewViewClass, 
    CSize(cr.Width(), cr.Height()/2), &cc)) 
{ 
    MessageBox(_T("Error setting up splitter frames! (CreateView 2)"), 
     _T("Init Error!"), MB_OK | MB_ICONERROR); 
    return; 
} 

m_bInitSplitter = TRUE; 
} 

在点击查看 - >劈扣,我得到一个“调试断言错误”弹出式和第一次调用CreateView的返回FALSE,显示我的消息框:“错误设置分离器框!(CreateView 1)“

回答

3

sta tic分离器是针对静态分割 - 即,一个窗口是总是分割。当您想在拆分的每个窗格中显示不同的视图(例如,在一个窗格中显示一列数字,在另一个窗格中显示一个图形)时,通常会使用它。

对于像你的情况,你希望能够拥有这个窗口,然后再分割它,并有两个基本相同的视图,你(至少通常)要使用动态分配器。

至少通常在创建视图时创建分隔线。这将创建在用户下拉拆分视图顶部,右上角有一个把手的窗口:

enter image description here

要拆分的窗口中,用户拉下手柄:

enter image description here

当分流他们想要的,它们释放鼠标按钮,并且视图分成两个分别可滚动部分:

enter image description here

既然你没有指定你是否要垂直或水平分割,我设置一个最高允许一个或两个:

enter image description here

该代码,这看起来是这样的:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT, CCreateContext* pContext) { 
    return my_splitter.Create(this, 
     2, 2,    // 2 rows, 2 columns 
     CSize(20, 20),  // minimum pane size 
     pContext); 
} 

其中my_splitter的定义是这样的:

CSplitterWnd my_splitter; 
+0

感谢您的支持。我想创建一个静态分割,我可以通过切换父母的方式打开和关闭,本质上是xMRi在他的答案中描述的。我遇到了另一个问题,请看我的问题编辑。 – JayB 2014-11-21 15:30:00

1

如果您想要按需使用分隔窗口,则需要更改当前视图的父级。 因此,步骤是:

  • 创建一个简单的SDI应用程序
  • 根据需要创建一个拆分窗口
  • 使用的setparent到当前视图并将其设置为在拆分窗口父。
  • 在第二个分离器中创建另一个窗口。

而回来的路上。

  • 使用SetParent并将普通视图重新附加到主框架。
  • 销毁分离器

有活性的样品如何切换的视图一个当前文档(MSDN)英寸它可以帮助您如何替换和更改ID。

+0

感谢您的分解,这正是我一直在寻找的! – JayB 2014-11-21 14:48:45

+0

只是为了澄清,当你说“在第二个分离器中创建另一个窗口”时,你的意思是在第二个窗口(这是分离器)还是应该创建两个分离器? – JayB 2014-11-21 14:49:34

+1

我已更新我的问题 – JayB 2014-11-21 15:19:48