zoukankan      html  css  js  c++  java
  • MFC中窗口静态分割&视图切换

    窗口静态分割

    单个分割器

    声明

    首先在MainFrm.h中声明分割对象

    CSplitterWnd m_wndSplitter;
    

    准备视图

    CView或其派生类中派生四个类:CMyView1CMyView2CMyView3CMyView4

    静态分割窗口&添加视图

    MainFrm.cpp中添加虚函数OnCreateClient,添加如下代码

    BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
    {
        // TODO: 在此添加专用代码和/或调用基类
        CRect rectClient;
        GetClientRect(&rectClient);
    
        if (!m_wndSplitter.CreateStatic(this, 2, 2) ||
            !m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CListView), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext) ||
            !m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CListView), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext) ||
            !m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CListView), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext) ||
            !m_wndSplitter.CreateView(1, 1, RUNTIME_CLASS(CListView), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext))
                return FALSE;
    
    
        // return CFrameWnd::OnCreateClient(lpcs, pContext);
        return TRUE;
    }
    

    使视图大小随窗口大小改变

    MainFrm.h中声明变量

    BOOL m_bSplitter;
    

    MainFrm.cpp构造函数中初始化m_bSplitter

    CMainFrame::CMainFrame() noexcept :
        m_bSplitter(FALSE)
    {
    }
    

    MainFrm.cpp虚函数OnCreateClient窗口分割之后添加对m_bSplitter的赋值

    BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
    {
        // TODO: 在此添加专用代码和/或调用基类
        CRect rectClient;
        GetClientRect(&rectClient);
    
        if (!m_wndSplitter.CreateStatic(this, 2, 2) ||
            !m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CListView), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext) ||
            !m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CListView), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext) ||
            !m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CListView), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext) ||
            !m_wndSplitter.CreateView(1, 1, RUNTIME_CLASS(CListView), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext))
                return FALSE;
    
        m_bSplitter = TRUE; // 窗口已完成分割,视图已经动态创建
    
        // return CFrameWnd::OnCreateClient(lpcs, pContext);
        return TRUE;
    }
    

    MainFrm.cpp中添加WM_SIZE消息映射,添加如下代码

    void CMainFrame::OnSize(UINT nType, int cx, int cy)
    {
        CFrameWnd::OnSize(nType, cx, cy);
    
        // TODO: 在此处添加消息处理程序代码
        if (m_bSplitter == TRUE)
        {
            m_wndSplitter.SetColumnInfo(0, cx / 2, 0);
            // 另外一列将自适应宽度
            m_wndSplitter.SetRowInfo(0, cy / 2, 0);
            // 另外一行将自适应高度
    
            // 重新计算
            m_wndSplitter.RecalcLayout();
        }
    }
    

    效果图

    多个分割器

    声明

    声明两个分割器

    CSplitterWnd m_wndSplitter1; // 主分割器
    CSplitterWnd m_wndSplitter2; // 子分割器
    

    静态分割窗口&添加视图

    MainFrm.cpp中修改虚函数OnCreateClient

    BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
    {
        // TODO: 在此添加专用代码和/或调用基类
        CRect rectClient;
        GetClientRect(&rectClient);
    
        if (!m_wndSplitter1.CreateStatic(this, 2, 1) ||
            !m_wndSplitter1.CreateView(0, 0, RUNTIME_CLASS(CListView), CSize(rectClient.Width(), rectClient.Height() / 2), pContext))
                return FALSE;
    
        if (!m_wndSplitter2.CreateStatic(&m_wndSplitter1, 1, 2, WS_CHILD | WS_VISIBLE, m_wndSplitter1.IdFromRowCol(1, 0)) ||
            !m_wndSplitter2.CreateView(0, 0, RUNTIME_CLASS(CListView), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext) ||
            !m_wndSplitter2.CreateView(0, 1, RUNTIME_CLASS(CListView), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext))
                return FALSE;
    
        m_bSplitter = TRUE; // 窗口已完成分割,视图已经动态创建
    
        // return CFrameWnd::OnCreateClient(lpcs, pContext);
        return TRUE;
    }
    

    使视图大小随窗口大小改变

    相应地修改OnSize函数

    void CMainFrame::OnSize(UINT nType, int cx, int cy)
    {
        CFrameWnd::OnSize(nType, cx, cy);
    
        // TODO: 在此处添加消息处理程序代码
        if (m_bSplitter == TRUE)
        {
            m_wndSplitter1.SetRowInfo(0, cy / 2, 0);
            m_wndSplitter2.SetColumnInfo(0, cx / 2, 0);
    
            // 重新计算
            m_wndSplitter1.RecalcLayout();
            m_wndSplitter2.RecalcLayout();
        }
    }
    

    效果图

    视图切换

    CMainFrame添加切换视图的函数BOOL CMainFrame::Switch(int nIndex),添加如下代码建立框架

    BOOL CMainFrame::Switch(int nIndex)
    {
        switch (nIndex)
        {
        case 0:
            break;
        case 1:
            break;
        default:
            return FALSE;
        }
        return TRUE;
    }
    

    视图之间的切换

    声明

    CSplitterWnd m_wndSplitter;
    

    修改相应函数

    添加CMyView2和CMyView3的绘图代码

    CMyView2

    void CMyView2::OnDraw(CDC* pDC)
    {
        CRect rectClient;
        GetClientRect(rectClient);
    
        pDC->FillSolidRect(rectClient, RGB(255, 255, 255));
    }
    

    CMyView3

    void CMyView3::OnDraw(CDC* pDC)
    {
        CRect rectClient;
        GetClientRect(rectClient);
    
        pDC->FillSolidRect(rectClient, RGB(0, 0, 0));
    }
    

    修改OnCreateClient函数

    BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
    {
        // TODO: 在此添加专用代码和/或调用基类
        CRect rectClient;
        GetClientRect(&rectClient);
    
        if (!m_wndSplitter.CreateStatic(this, 1, 2) ||
            !m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CMyView1), CSize(rectClient.Width() / 2, rectClient.Height()), pContext) ||
            !m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CMyView2), CSize(rectClient.Width() / 2, rectClient.Height()), pContext))
                return FALSE;
    
    	m_bSplitter = TRUE; // 窗口已完成分割,视图已经动态创建
    
    	Switch(0); // 更改数值以获得切换效果
    
    	// return CFrameWnd::OnCreateClient(lpcs, pContext);
    	return TRUE;
    }
    

    修改视图切换函数

    BOOL CMainFrame::Switch(int nIndex)
    {
        CRect rectClient;
        GetClientRect(rectClient);
    
        switch (nIndex)
        {
        case 0:
            m_wndSplitter.DeleteView(0, 1);
            m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CMyView2), CSize(rectClient.Width() / 2, rectClient.Height()), NULL);
            m_wndSplitter.RecalcLayout();
            break;
        case 1:
            m_wndSplitter.DeleteView(0, 1);
            m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CMyView3), CSize(rectClient.Width() / 2, rectClient.Height()), NULL);
            m_wndSplitter.RecalcLayout();
            break;
        default:
            return FALSE;
        }
        return TRUE;
    }
    

    子分割器之间的切换

    声明

    CSplitterWnd m_wndSplitter; // 主分割器
    CSplitterWnd m_wndSplitter1; // 子分割器1
    CSplitterWnd m_wndSplitter2; // 子分割器2
    

    准备视图

    CView或其派生类中派生第五个类:CMyView5

    修改相应函数

    修改OnCreateClient函数

    BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
    {
        // TODO: 在此添加专用代码和/或调用基类
        CRect rectClient;
        GetClientRect(&rectClient);
    
        if (!m_wndSplitter.CreateStatic(this, 1, 2) ||
            !m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CMyView1),CSize(rectClient.Width() / 2, rectClient.Height()),pContext))
                return FALSE;
    
        if (!m_wndSplitter1.CreateStatic(&m_wndSplitter, 2, 1, WS_CHILD) ||
            !m_wndSplitter1.CreateView(0, 0, RUNTIME_CLASS(CMyView2), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext) ||
    	!m_wndSplitter1.CreateView(1, 0, RUNTIME_CLASS(CMyView3), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext))
                return FALSE;
    
        if (!m_wndSplitter2.CreateStatic(&m_wndSplitter, 2, 1, WS_CHILD) ||
            !m_wndSplitter2.CreateView(0, 0, RUNTIME_CLASS(CMyView4), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext) ||
            !m_wndSplitter2.CreateView(1, 0, RUNTIME_CLASS(CMyView5), CSize(rectClient.Width() / 2, rectClient.Height() / 2), pContext))
                return FALSE;
    
        m_bSplitter = TRUE; // 窗口已完成分割,视图已经动态创建
    
        Switch(0); // 更改数值以获得切换效果
    
        // return CFrameWnd::OnCreateClient(lpcs, pContext);
        return TRUE;
    }
    

    修改视图切换函数

    BOOL CMainFrame::Switch(int nIndex)
    {
        CRect rectClient;
        GetClientRect(rectClient);
    
        switch (nIndex)
        {
        case 0:
            ::SetWindowLong(m_wndSplitter1, GWL_ID, m_wndSplitter.IdFromRowCol(0, 1));
            m_wndSplitter1.ShowWindow(SW_SHOW);
            ::SetWindowLong(m_wndSplitter2, GWL_ID, AFX_IDW_PANE_FIRST);
            m_wndSplitter2.ShowWindow(SW_HIDE);
            break;
        case 1:
            ::SetWindowLong(m_wndSplitter1, GWL_ID, AFX_IDW_PANE_FIRST);
            m_wndSplitter1.ShowWindow(SW_HIDE);
            ::SetWindowLong(m_wndSplitter2, GWL_ID, m_wndSplitter.IdFromRowCol(0, 1));
            m_wndSplitter2.ShowWindow(SW_SHOW);
            break;
        default:
            return FALSE;
        }
        return TRUE;
    }
    

    篇尾声明

    单个分割器 参阅资料:https://blog.csdn.net/bao_bei/article/details/60136336
    多个分割器 参阅资料:https://blog.csdn.net/bao_bei/article/details/60136336
    视图之间的切换 参阅资料:https://www.cnblogs.com/chenzuoyou/p/3342003.html
    子分割器之间的切换 原创

  • 相关阅读:
    angular 写 文字省略显示指令
    REACT 学习之一:普通表单过滤
    怎么能够做到实时的邮件监听-- 求指点
    C++实现Behavioral
    private virtual in c++
    接口污染
    C++ 虚函数&纯虚函数&抽象类&接口&虚基类(转)
    c++ override 关键字
    virtual function c++
    删完垃圾代码2
  • 原文地址:https://www.cnblogs.com/fenggwsx/p/13205956.html
Copyright © 2011-2022 走看看