• MFC中Frame-Splitter模型


    1. 新建一个SDI工程,去掉“Document/View architecture support”

    2. 添加 CTreeView 类的派生类 CLeftView 作为分隔器的左侧视图,添加 CListView 的派生类 CRightView 作为右边视图。可能需要 #include <afxcview.h>

    3. 在CLeftView类中添加成员变量 CTreeCtrl& m_tree;  在CRightView类中添加成员变量 CListCtrl& m_list;  并在构造函数中初始化

    CLeftView::CLeftView() :m_tree(GetTreeCtrl())
    {
    }
    CRightView::CRightView() :m_list(GetListCtrl())
    {
    }

    4. 在主框架类 CMainFrame 类的头文件中,去掉 CChildView 类变量,添加 CSplitterWnd m_split;CLeftView* m_pLeftView;CRightView* m_pRightView;在CMainFrame的cpp文件中去掉CChildView的相关代码。
    在CMainFrame类中添加虚函数OnCreateClient,该函数是在基类函数 CFrameWnd::OnCreate 执行的过程中回调OnCreateClient函数,主要用于创建视图类等客户区子窗口。
    在CLeftView类中添加虚函数OnInitUpdate,该函数创建类之后第一个进入的函数,类似对话框的OnInitDialog函数。再添加TVN_SELCHANGEED消息映射函数,并修改代码调用CRightView的Refresh函数。
    在CRightView类中添加虚函数OnInitUpdate,添加普通成员函数 Refresh。

    代码如下:

    MainFrm.cpp

    // MainFrm.cpp : CMainFrame 类的实现
    //
    
    #include "stdafx.h"
    #include "sp.h"
    
    #include "MainFrm.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    // CMainFrame
    
    IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
    
    BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
        ON_WM_CREATE()
        ON_WM_SETFOCUS()
    END_MESSAGE_MAP()
    
    static UINT indicators[] =
    {
        ID_SEPARATOR,           // 状态行指示器
        ID_INDICATOR_CAPS,
        ID_INDICATOR_NUM,
        ID_INDICATOR_SCRL,
    };
    
    // CMainFrame 构造/析构
    
    CMainFrame::CMainFrame()
    {
        // TODO:  在此添加成员初始化代码
    }
    
    CMainFrame::~CMainFrame()
    {
    }
    
    BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
    {
        // TODO:  在此添加专用代码和/或调用基类
        if (!m_split.CreateStatic(this, 1, 2))
            return FALSE;
        m_split.CreateView(0, 0, RUNTIME_CLASS(CLeftView), CSize(150, 0), NULL);
        m_split.CreateView(0, 1, RUNTIME_CLASS(CRightView), CSize(0, 0), NULL);
        m_pLeftView = (CLeftView*)m_split.GetPane(0, 0);
        m_pRightView = (CRightView*)m_split.GetPane(0, 1);
        return TRUE;
    
        //    return CFrameWnd::OnCreateClient(lpcs, pContext);
    }
    
    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
            return -1;
    
        // 创建一个视图以占用框架的工作区
        //if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
        //{
        //    TRACE0("未能创建视图窗口
    ");
        //    return -1;
        //}
    
        if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
            !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
        {
            TRACE0("未能创建工具栏
    ");
            return -1;      // 未能创建
        }
    
        if (!m_wndStatusBar.Create(this))
        {
            TRACE0("未能创建状态栏
    ");
            return -1;      // 未能创建
        }
        m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
    
        // TODO:  如果不需要可停靠工具栏,则删除这三行
        m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
        EnableDocking(CBRS_ALIGN_ANY);
        DockControlBar(&m_wndToolBar);
    
    
        return 0;
    }
    
    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
        if( !CFrameWnd::PreCreateWindow(cs) )
            return FALSE;
        // TODO:  在此处通过修改
        //  CREATESTRUCT cs 来修改窗口类或样式
    
        cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
        cs.lpszClass = AfxRegisterWndClass(0);
        
        return TRUE;
    }
    
    // CMainFrame 诊断
    
    #ifdef _DEBUG
    void CMainFrame::AssertValid() const
    {
        CFrameWnd::AssertValid();
    }
    
    void CMainFrame::Dump(CDumpContext& dc) const
    {
        CFrameWnd::Dump(dc);
    }
    #endif //_DEBUG
    
    
    // CMainFrame 消息处理程序
    
    void CMainFrame::OnSetFocus(CWnd* /*pOldWnd*/)
    {
        // 将焦点前移到视图窗口
    //    m_wndView.SetFocus();
        m_pLeftView->SetFocus();
    }
    
    BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
    {
        // 让视图第一次尝试该命令
        //if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
        //    return TRUE;
        CWnd* pWnd = GetFocus();
        if (pWnd && pWnd != this && pWnd->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
        {
            return TRUE;
        }
    
        // 否则,执行默认处理
        return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
    }
    View Code

    LeftView.cpp

    // LeftView.cpp : 实现文件
    //
    
    #include "stdafx.h"
    #include "sp.h"
    #include "LeftView.h"
    
    
    // CLeftView
    
    IMPLEMENT_DYNCREATE(CLeftView, CTreeView)
    
    CLeftView::CLeftView() :m_tree(GetTreeCtrl())
    {
    
    }
    
    CLeftView::~CLeftView()
    {
    }
    
    BEGIN_MESSAGE_MAP(CLeftView, CTreeView)
        ON_NOTIFY_REFLECT(TVN_SELCHANGED, &CLeftView::OnTvnSelchanged)
    END_MESSAGE_MAP()
    
    
    // CLeftView 诊断
    
    #ifdef _DEBUG
    void CLeftView::AssertValid() const
    {
        CTreeView::AssertValid();
    }
    
    #ifndef _WIN32_WCE
    void CLeftView::Dump(CDumpContext& dc) const
    {
        CTreeView::Dump(dc);
    }
    #endif
    #endif //_DEBUG
    
    
    // CLeftView 消息处理程序
    
    
    void CLeftView::OnInitialUpdate()
    {
        CTreeView::OnInitialUpdate();
    
        // TODO:  在此添加专用代码和/或调用基类
        if (m_tree.GetChildItem(NULL))
            return;
        m_tree.ModifyStyle(0, TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS);
        HTREEITEM hItem = m_tree.InsertItem(_T("我的电脑"));
        char buf[100];
        DWORD len = GetLogicalDriveStringsA(sizeof(buf) / sizeof(buf[0]), buf);//获取的buf,例如c:<null>d:<null><null> 
        char *p = buf;
        CString str;
        while (*p)
        {
            str = p;
            int nLen = str.GetLength();
            if (nLen < 1)
                break;
            if ('\' == str[nLen - 1])
                str = str.Left(nLen - 1);
            m_tree.InsertItem(str, hItem);
            p += nLen + 1;
        }
        m_tree.Expand(hItem, TVE_EXPAND);
    }
    
    #include "MainFrm.h"
    void CLeftView::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult)
    {
        LPNMTREEVIEW p = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
        // TODO:  在此添加控件通知处理程序代码
        HTREEITEM hItem = p->itemNew.hItem;
        CString szPath;
        if (hItem != m_tree.GetRootItem())
            szPath = m_tree.GetItemText(hItem);
        CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
        pFrame->m_pRightView->Refresh(szPath);
    
        *pResult = 0;
    }
    View Code

    RightView.cpp

    // RightView.cpp : 实现文件
    //
    
    #include "stdafx.h"
    #include "sp.h"
    #include "RightView.h"
    
    
    // CRightView
    
    IMPLEMENT_DYNCREATE(CRightView, CListView)
    
    CRightView::CRightView() :m_list(GetListCtrl())
    {
    
    }
    
    CRightView::~CRightView()
    {
    }
    
    BEGIN_MESSAGE_MAP(CRightView, CListView)
    END_MESSAGE_MAP()
    
    
    // CRightView 诊断
    
    #ifdef _DEBUG
    void CRightView::AssertValid() const
    {
        CListView::AssertValid();
    }
    
    #ifndef _WIN32_WCE
    void CRightView::Dump(CDumpContext& dc) const
    {
        CListView::Dump(dc);
    }
    #endif
    #endif //_DEBUG
    
    
    // CRightView 消息处理程序
    
    
    void CRightView::OnInitialUpdate()
    {
        CListView::OnInitialUpdate();
    
        // TODO:  在此添加专用代码和/或调用基类
        if (m_list.GetStyle() & LVS_REPORT)
            return;
        m_list.ModifyStyle(0, LVS_REPORT);
        m_list.InsertColumn(0, _T("名称"), 0, 120);
        m_list.InsertColumn(1, _T("大小"), 0, 120);
        m_list.InsertColumn(2, _T("类型"), 0, 120);
        m_list.InsertColumn(3, _T("修改日期"), 0, 120);
    }
    
    
    void CRightView::Refresh(CString szPath)
    {
        m_list.DeleteAllItems();
        if (szPath.IsEmpty())
            return;
        CFileFind ff;
        BOOL b = ff.FindFile(szPath + _T("/*.*"));
        int i = 0;
        while (b)
        {
            b = ff.FindNextFile();
            if (ff.IsDots())
                continue;
            m_list.InsertItem(i, ff.GetFileName());
            if (ff.IsDirectory())
                m_list.SetItemText(i, 2, _T("文件夹"));
            else
            {
                int nLen = ff.GetLength() / 1024;
                if (!nLen)
                    nLen = 1;
                szPath.Format(_T("%d kb"), nLen);
                m_list.SetItemText(i, 1, szPath);
                m_list.SetItemText(i, 2, _T("文件"));
            }
            FILETIME ft;
            ff.GetLastWriteTime(&ft);
            COleDateTime time(ft);
            szPath.Format(_T("%d-%02d-%02d %02d:%02d:%02d"),
                time.GetYear(), time.GetMonth(), time.GetDay(), 
                time.GetHour(), time.GetMinute(), time.GetSecond());
            m_list.SetItemText(i, 3, szPath);
            ++i;
        }
    }
    View Code

    运行结果:

    常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。

    昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。
  • 相关阅读:
    Facade Pattern简单随笔
    Bridge Pattern简单随笔
    重构:Encapsulate Collection
    VS2008 + Silverlight初步学习
    Proxy Pattern设计模式简单随笔
    Composite Pattern简单随笔
    重构:Move Method 笔记
    [ubuntu] ubuntu13.04 添加右键脚本功能
    Flex的“事件之旅”
    Flex与JavaScript交互(二)
  • 原文地址:https://www.cnblogs.com/htj10/p/11722695.html
Copyright © 2020-2023  润新知