更换CSplitterWnd中的pane

来源:互联网 发布:房子设计图软件 编辑:程序博客网 时间:2024/04/28 22:09

 更换CSplitterWnd中的pane

在一些软件设置的界面中,通常左边是项目,右边是项目中具体的设置内容
如果用CSplitterWnd实现,需要根据左边的项目选择,更改右边pane的显示内容

更换CSplitterWnd中某一个pane(即某个格子中的view),应该如何实现?

一种简单的做法是,每次更改时,调用DeleteView删掉原来的view,再CreateView重建一个
但这样除了做法恶心外,对于view中的状态难以保存

CSplitterWnd没有提供更换view的成员方法

分析CSplitterWnd::CreateView,pane中view创建的关键代码是:
    ......
    if (!pWnd->Create(NULL, NULL, dwStyle,
        rect, this, IdFromRowCol(row, col), pContext))
    ......
而判断view是否重复创建的代码是:
    ......
    if (GetDlgItem(IdFromRowCol(row, col)) != NULL)
    {
    TRACE2("Error: CreateView - pane already exists for row %d, col %d./n", row, col);
    ......
此外,CSplitterWnd::GetPane:
    ......
    CWnd* pView = GetDlgItem(IdFromRowCol(row, col));
    ......
由此,可以得出结论,一个view与一个pane的绑定关系,通过view的子窗口id

因此,修改view的子窗口id,即可将view与pane绑定或解绑,再配合窗口的显示或隐藏,即可实现view的更换

class CMySplitterWnd : public CSplitterWnd
{
    ......

void CMySplitterWnd::ChangeView(int row, int col, CWnd * pView)
{
    CWnd * pViewCur = GetPane(row, col);
    pViewCur->SetDlgCtrlID(1000);  // 1000是一个任意的id,只要大于256即可          
    m_pViewCur->ShowWindow(SW_HIDE);
    m_pViewCur->EnableWindow(FALSE);

    pView->SetDlgCtrlID(IdFromRowCol(row, col));
    pView->EnableWindow(TRUE);
    pView->ShowWindow(SW_SHOW);

    RecalcLayout();  // 重画一下
}

另外注意,splitter window创建的时候仍然需要用CreateView在每个pane中创建最初的view,并设好大小,以完成pane的初始化