1

我编写了一个 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;
}
*/
}

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

谢谢。

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

由于 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)”

4

2 回答 2

3

静态拆分器用于静态拆分,即始终拆分的窗口。当您希望在拆分的每个窗格中具有不同的视图时,通常会使用它(例如,在一个窗格中显示一列数字,在另一个窗格中显示图表)。

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

至少在通常情况下,您会在创建视图时创建拆分器。这将创建一个窗口,该窗口的右上角有一个句柄,用户将其下拉以拆分视图:

在此处输入图像描述

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

在此处输入图像描述

当拆分在他们想要的位置时,他们释放鼠标按钮,视图拆分为两个单独的可滚动部分:

在此处输入图像描述

由于您没有指定是要垂直拆分还是水平拆分,因此我将其设置为允许其中一个或两个:

在此处输入图像描述

代码如下所示:

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

wheremy_splitter是这样定义的:

CSplitterWnd my_splitter;
于 2014-11-21T07:11:51.360 回答
1

如果要按需使用拆分器窗口,则需要更改当前视图的父级。所以步骤是:

  • 创建一个简单的 SDI 应用程序
  • 按需创建拆分窗口
  • 对当前视图使用 SetParent 并将其设置为拆分器窗口中的父级。
  • 在第二个拆分器中创建另一个窗口。

和回来的路。

  • 使用 SetParent 并将普通视图附加到主框架。
  • 破坏分离器

有一些活动示例如何在当前文档 ( MSDN ) 中切换视图。它可以帮助您如何更换和更改 ID。

于 2014-11-21T09:46:07.317 回答