Xtreme实现MFC视图分割
需求:将MFC单文档分割为4个视图,可以每个视图分别进行控制
使用工具:VS2005,Xtreme v12.0.0(源码版本)
步骤一:VS2005中新建工程VC++ -> MFC -> Toolkit Pro Application。在向导里选择“单文档”,其他选项全部默认。
PS1:安装Xtreme若没有选择Unicode,那么需要在VS中更改设置。Project -> Configuration Properties -> General -> Character Set选择“Use Multi-Byte Character Set”
PS2:Toolkit Pro Application框架基于MFC框架,只是在MainFrame类中增加一些内容,具体在此不详述。
步骤二:新建三个View类用于显示。本框架新增的View类为CSliceView0,CSliceView1,CSliceView2,并且只是在OnDraw函数中用TextOut输出语句。
步骤三:在MainFrame类中新建View类的对象
CSliceView0* m_pSliceView0;
CSliceView1* m_pSliceView1;
CSliceView2* m_pSliceView2;
步骤四:为新增的三个View增加ID
首先在Resource.h中新增宏IDR_PANE_VIEW0,IDR_PANE_VIEW1,IDR_PANE_VIEW2,这些宏就是View对应的ID
之后在rc管理器中设置宏的Caption
IDR_PANE_VIEW0 4000 View0
IDR_PANE_VIEW1 4001 View1
IDR_PANE_VIEW2 4002 View2
步骤五:在MainFrame类的OnCreate函数中创建View的容器Pane
CXTPDockingPane* pwndPane1 = m_paneManager.CreatePane(
IDR_PANE_VIEW0, CRect(0, 0, 400, 348), xtpPaneDockBottom);
CXTPDockingPane* pwndPane2 = m_paneManager.CreatePane(
IDR_PANE_VIEW1, CRect(0, 0, 400, 300), xtpPaneDockLeft);
CXTPDockingPane* pwndPane3 = m_paneManager.CreatePane(
IDR_PANE_VIEW2, CRect(0, 0, 400, 300), xtpPaneDockBottom, pwndPane2);
在此创建了View的容器Pane,并实现了界面中每个View的布局。
容器的大小与相对位置由CreatePane函数指定,注意指定顺序也会对界面的布局产生影响。
此外还需要设置icon与pane对应,每个pane都有一个图标icon
int nIDIcons[] = {IDR_PANE_VIEW0, IDR_PANE_VIEW1, IDR_PANE_VIEW2};
m_paneManager.SetIcons(IDB_BITMAP_ICONS, nIDIcons,
_countof(nIDIcons), RGB(0, 255, 0));
如果需要像VS2005那样灵活移动Pane的位置,可以增加以下语句
m_paneManager.SetAlphaDockingContext(TRUE);
m_paneManager.SetShowDockingContextStickers(TRUE);
m_paneManager.SetDockingContextStickerStyle(xtpPaneStickerStyleVisualStudio2005);
m_paneManager.SetShowContentsWhileDragging();
步骤六:修改MainFrame类的OnDockingPaneNotify函数
OnDockingPaneNotify负责对Pane相应事件进行响应,在MainFrame.cpp中可以看到此函数与消息XTPWM_DOCKINGPANE_NOTIFY对应。
OnDockingPaneNotify函数中有一串Switch-Case语句,负责响应不同的Pane。
switch (pPane->GetID())
{
case IDR_PANE_VIEW0:
{
if (!m_pSliceView0)
{
m_pSliceView0 = DYNAMIC_DOWNCAST(CSliceView0,
pPane->AttachView(this, RUNTIME_CLASS(CSliceView0)));
}
else
{
pPane->Attach(m_pSliceView0->GetParent());
}
break;
}
case IDR_PANE_VIEW1:
{
if (!m_pSliceView1)
{
m_pSliceView1 = DYNAMIC_DOWNCAST(CSliceView1,
pPane->AttachView(this, RUNTIME_CLASS(CSliceView1)));
}
else
{
pPane->Attach(m_pSliceView1->GetParent());
}
break;
}
case IDR_PANE_VIEW2:
{
if (!m_pSliceView2)
{
m_pSliceView2 = DYNAMIC_DOWNCAST(CSliceView2,
pPane->AttachView(this, RUNTIME_CLASS(CSliceView2)));
}
else
{
pPane->Attach(m_pSliceView2->GetParent());
}
break;
}
default:
break;
}
}