更换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的初始化