mfccsplitterwnd

CSplitterWnd flip between horizontal and vertical splitter?


Suppose I have a splitter with 2 rows.

--------
|        |
--------
|        |
--------

How do I make it to this

---------
|    |    |
|    |    |
|    |    |
---------

switch from horizontal split to vertical split

without having to re-create the whole splitter?

Code is:

if (!m_wndSplitter.CreateStatic(this, 1, 2, WS_CHILD|WS_VISIBLE))
{
    TRACE0("Failed to create splitter window\n");
    return FALSE;
}
if (!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CWnd), CSize(200, 100), NULL))
{
    TRACE0("Failed to create CView1\n");
    return FALSE;
}
if (!m_wndSplitter.CreateView(0, 2, RUNTIME_CLASS(CWnd), CSize(500, 100), NULL))
{
    TRACE0("Failed to create CView2\n");
    return FALSE;
}

Solution

  • Don't use CreateStatic, just use Create on the splitter. Then you have a so called dynamic splitter, see more here.

    When converting the splitter from horz to vert, you have to remove the views from the splitter and attach them again afterwards. You have to do this in your document-class. I can post a method to do this if needed.

    Ok, here is a method to switch views in a pane:

    CView* CGMBefundDoc::SwitchToView(CView* pNewView,int row,int col)
    {
    CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
    CSplitterWnd* pSplitter = &pMainWnd->m_wndSplitter;
    
    CView* pOldActiveView = reinterpret_cast<CView*>(pSplitter->GetPane(row,col));
    ASSERT(pOldActiveView != pNewView);
    
    // set flag so that document will not be deleted when view is destroyed
    m_bAutoDelete = FALSE;    
    // Dettach existing view
    RemoveView(pOldActiveView);
    // set flag back to default 
    m_bAutoDelete = TRUE;
    
    // Set the child window ID of the active view to the ID of the corresponding
    // pane. Set the child ID of the previously active view to some other ID.
    ::SetWindowLong(pOldActiveView->m_hWnd, GWL_ID, 0);
    ::SetWindowLong(pNewView->m_hWnd,GWL_ID,pSplitter->IdFromRowCol(row,col));
    
    // Show the newly active view and hide the inactive view.
    pNewView->ShowWindow(SW_SHOW);
    pOldActiveView->ShowWindow(SW_HIDE);
    
    // Attach new view
    AddView(pNewView);
    
    // Set active 
    pSplitter->GetParentFrame()->SetActiveView(pNewView);
    pSplitter->RecalcLayout(); 
    
    return pOldActiveView;
    }
    

    I hope you get the idea, otherwise just ask.