Split Windows

本文介绍了一种Outlook风格的应用程序设计实现方法。该应用采用SDI窗口结构,通过静态分割窗实现左右两栏布局。左侧栏使用CFormView派生类并内置树形控件,右侧栏为包含多种视图的框架,支持不同视图间的切换。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

Here is a another Outlook lookalike example source code.

The OutlookStyle application is an SDI window. The main frame consist of a
static splitter window with one row and two columns.

The left column CLeftPaneView is derived from CFormView and CRightPaneFrame
is derived from CFrameWnd.

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext*
pContext)
{
// TODO: Add your specialized code here and/or call the base class
if (!m_wndSplitter.CreateStatic(this, 1, 2))
{
TRACE0("Failed to create splitter window/n");
return FALSE;
}

// Get the client rect first for calc left pane size
CRect rect;
GetClientRect(&rect);

// create the left tree view first.
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftPaneView),
CSize(rect.Width()/3, 0), pContext))
{
TRACE0("Failed to create left pane view/n");
return FALSE;
}

// The right pane is a frame which and contain several different views.
// The is can be set to active or non-active
if (!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CRightPaneFrame),
CSize(0, 0), pContext))
{
TRACE0("Failed to create right pane frame/n");
return FALSE;
}

// Set the left pane as the active view
SetActiveView((CView*) m_wndSplitter.GetPane(0, 0));

return TRUE;
}


Since the right pane is a frame, it can have views created from any CViews
types such as CFromView.
The left pane is CFormView with a tree control in it which resize itself
during OnSize.

I have added several items to the tree and process the tree selection
change message.
Based on the tree selected, I call the right pane to switch views.

The right pane OnCreateClient creates all the different views and set one
to be the active view.
The views in the right pane can also be splitter windows.

BOOL CRightPaneFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext*
pContext)
{
// TODO: Add your specialized code here and/or call the base class

m_pSplitterView = new CSplitterView;
m_pSplitterView->Create(NULL, NULL, 0L, CFrameWnd::rectDefault, this,
VIEW_SPLITTER, pContext);
SetActiveView(m_pSplitterView);
m_pSplitterView->ShowWindow(SW_SHOW);
m_pSplitterView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);

m_pListCtrlView = new CListCtrlView;
((CView*) m_pListCtrlView)->Create(NULL, NULL, 0L, CFrameWnd::rectDefault,
this, VIEW_LISTCTRL, pContext);
m_pListCtrlView->ShowWindow(SW_HIDE);
m_pListCtrlView->SetDlgCtrlID(VIEW_LISTCTRL);

m_pEditView = new CEditView;
m_pEditView->Create(NULL, NULL, 0L, CFrameWnd::rectDefault, this,
VIEW_EDIT, pContext);
m_pEditView->ShowWindow(SW_HIDE);
m_pEditView->SetDlgCtrlID(VIEW_EDIT);


RecalcLayout();

return TRUE;
}


The right pane OnCreateClient must return TRUE and RecalcLayout().
The right pane member SwithToView is called by the left pane when an item
is selected.

void CRightPaneFrame::SwitchToView(UINT nView)
{
CView* pOldActiveView = GetActiveView();
CView* pNewActiveView;

switch (nView)
{
case VIEW_SPLITTER:
pNewActiveView = (CView*) m_pSplitterView;
break;

case VIEW_LISTCTRL:
pNewActiveView = (CView*) m_pListCtrlView;
break;

case VIEW_EDIT:
pNewActiveView = (CView*) m_pEditView;
break;
}

// don't switch when views are the same
if (pOldActiveView == pNewActiveView) return;

SetActiveView(pNewActiveView);
pNewActiveView->ShowWindow(SW_SHOW);
pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
pOldActiveView->ShowWindow(SW_HIDE);
pOldActiveView->SetDlgCtrlID(m_nCurrentViewID);
m_nCurrentViewID = nView;

RecalcLayout();
}


The switch code is tricky, it has to hide the old active view, show the new
active view and
set the current dialog control id.

Finally, the left pane tree selection needs to call the right pane switch
function.
The left pane needs a referrence to the right pane window.

When the main frame creates the left and right pane it sets the right pane
window pointer to
the left pane member.

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext*
pContext)
{
.
.
.
CLeftPaneView* pLeftPaneView     = (CLeftPaneView*) 
m_wndSplitter.GetPane(0,0);
pLeftPaneView->m_pRightPaneFrame = (CRightPaneFrame*)
m_wndSplitter.GetPane(0,1);
.
.
.
}


void CLeftPaneView::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here

UINT     nView         = 0;
HTREEITEM hSelectedItem = m_treeCtrl.GetSelectedItem();

if (hSelectedItem == m_hSplitterView)
nView = VIEW_SPLITTER;
else
if (hSelectedItem == m_hListCtrlView)
nView = VIEW_LISTCTRL;
else
if (hSelectedItem == m_hEditView)
nView = VIEW_EDIT;

if (nView) m_pRightPaneFrame->SwitchToView(nView);

*pResult = 0;
}


The left pane OnSelchangedTree checks the selected item for a match and
then call
the SwitchToView to change view on the right pane.

 

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值