Link to home
Start Free TrialLog in
Avatar of bmelling9
bmelling9

asked on

Splitter windows

I am attempting to simulate dynamic splitter windows by creating a new static window as the user requests a new column or row.  The problem is that I can't get the splitter window (which is a child of the MainFrame window)to paint after the new splitter is created.  It will only paint if I minimize and restore.  Here is a section of code for adding a new row:

      delete m_wndSplitter;
      m_wndSplitter = new CSplitterWindow;

      CCreateContext context;
      context.m_pCurrentFrame = this/*MainFrame CWnd*/;

      if (m_nRows < 16)
            m_nRows++;

      BOOL returnVal = m_wndSplitter->CreateStatic(this,                                                                          m_nRows,
                                                                        m_nCols);

      CRect rect;
      GetClientRect(rect);

      int width = rect.right/m_nCols;
      int height = rect.bottom/m_nRows;

      for (int i = 0; i < m_nRows; i++)
      {
            for (int j = 0; j < m_nCols; j++)
            {
                  if (! m_wndSplitter->CreateView(i, j, RUNTIME_CLASS (CSplitterView), CSize(width,height), &context))
                        returnVal = FALSE;
            }
      }

m_wndSplitter is a member of the MainFrame class. I even put a posted a WM_PAINT message to m_wndSplitter at the end of the MainFrame's OnPaint function, but no luck.  Any help would be greatly appreciated.  Thanks
Avatar of bmelling9
bmelling9

ASKER

Edited text of question
Did You try m_wndSplitter->Invalidate() ?
Replace the lines:

if (! m_wndSplitter->CreateView(i, j, RUNTIME_CLASS (CSplitterView), CSize(width,height), &context))
  returnVal = FALSE;

with:

if (m_wndSplitter->CreateView(i, j, RUNTIME_CLASS (CSplitterView), CSize(width,height), &context))
  RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ALLCHILDREN );
else
  returnVal = FALSE;
this did not solve the problem- the splitter window is still not getting painted.  I have developed a work around for this situation- I am posting a WM_SIZE to the MainFrame Window at the end of the MainFrame Window's OnPaint function.  However, this seems unnecessary, so I would still be interested in knowing the source of this problem and/or a more logical solution.
I've never done a dynamic splitter like your application, but Invalidate() followed by UpdateWindow() will almost always work.
CSplitterWnd::RecalcLayout() should be working, i think ...
It is called upon WM_SIZE messages, and should be called after layout changes.
Hope this works :)
I think you are not associating the current document to the newly created views.

Give the current document to the context.

context.m_pCurrentDoc = ???//Current Document pointer

Try this.
I am not currently working with a document- all I have is a frame window and the splitter window.  I have tried nearly all possible combinations of calling Invalidate() and UpdateWindow() for both as well as RecalcLayout() for the Splitter.  I have also posted WM_PAINT messages to both windows at various points in the process of creating the splitter, but the only thing that has worked is the work around I mentioned in my note on 9/3.  I guess I don't have to have an answer to this, but my curiosity is piqued, so I'm upping the points a little...

Have U tried using UpdateAllViews().
If you want to Create a splitter window use static view, you must  overwrite OnCreateClient(...).
Now I give you this code.I set View is CMyView1 and CMyView2.

//in Hpp File
class CMyFrame : CFrameWnd
{
  .....
  CSplitterWnd m_wndSplitter; //This Value is by AppWizard Create
                              //If you Con't see it,
                              //you can write it
}


//in Cpp File
BOOL CMyFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
      // TODO: Add your specialized code here and/or call the base class
      if(!m_wndSplitter.CreateStatic(this, 2, 1) ||
         !m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CMyView1), CSize(100, 200), pContext) ||
         !m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CMyView2), CSize(100, 200), pContext))
         return FALSE;

      return TRUE;
       
        //Don't Call System OnCreateClient(...)
      //return CFrameWnd::OnCreateClient(lpcs, pContext);
}

This is the source code of CFrameWnd::OnSize():

(mainfrm.cpp)
void CFrameWnd::OnSize(UINT nType, int cx, int cy)
{
      CWnd::OnSize(nType, cx, cy);    // important for MDI Children
      if (nType != SIZE_MINIMIZED)
            RecalcLayout();
}

You said, when you post a WM_SIZE message at the end of a OnPaint() handler, it works.
Maybe you should try this in your splitter update function:

Invalidate(); // Invalidate client rectangle
UpdateWindow(); // Wait for WM_PAINT to be sent
RecalcLayout(); // called by WM_SIZE

This should have the same effect as what you did in the OnPaint() handler. If this doesn't work,
perhaps you could replace RecalcLayout() with your WM_SIZE posting.
I did override the OnCreateClient function and it works when the frame window is created.  The problem occurs after the frame has been created when, in response to a user command, I attempt to delete the static splitter and create another with different dimensions.  
When you set up a CCreateContext like the one passed to OnCreateClient, this should work:

C...Frame::OnUserAction()
{
  CCreateContext context;
  // set up context
  ...
 
  m_wndSplitter.DestroyWindow();
 
  // insert here the code part from OnCreateClient which creates the m_wndSplitter

}
Thanks snoegler, your comment of 9/13 worked.  I was calling RecalcLayout() on the CSplitterWnd derived class, not the CFrameWnd derived class.  Adding the RecalcLayout() call to the end of my CreateSplitter routine did the trick.  This is my first question at experts exchange, so I don't know how to get you the points for this question since you did not submit an "answer".  Let me know if I need to do anything.  Thanks again.
ASKER CERTIFIED SOLUTION
Avatar of snoegler
snoegler

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial