MFC中窗口静态分割&视图切换

目录
  • 窗口静态分割
    • 单个分割器
      • 声明
      • 准备视图
      • 静态分割窗口&添加视图
      • 使视图大小随窗口大小改变
    • 多个分割器
      • 声明
      • 静态分割窗口&添加视图
      • 使视图大小随窗口大小改变
  • 视图切换
    • 视图之间的切换
      • 声明
      • 修改相应函数
        • 添加CMyView2和CMyView3的绘图代码
        • 修改OnCreateClient函数
        • 修改视图切换函数
    • 子分割器之间的切换
      • 声明
      • 准备视图
      • 修改相应函数
        • 修改OnCreateClient函数
        • 修改视图切换函数
  • 篇尾声明

窗口静态分割

单个分割器

声明

首先在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();
    }
}

效果图
MFC中窗口静态分割&视图切换_第1张图片

多个分割器

声明

声明两个分割器

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();
    }
}

效果图
MFC中窗口静态分割&视图切换_第2张图片

视图切换

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
子分割器之间的切换 原创

你可能感兴趣的:(MFC中窗口静态分割&视图切换)