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.
Split Windows
本文介绍了一种Outlook风格的应用程序设计实现方法。该应用采用SDI窗口结构,通过静态分割窗实现左右两栏布局。左侧栏使用CFormView派生类并内置树形控件,右侧栏为包含多种视图的框架,支持不同视图间的切换。
开发板推荐:天空星STM32F407VET6开发板
超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印
开发板推荐:天空星STM32F407VET6开发板
超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印


被折叠的 条评论
为什么被折叠?



