Solved

Splitter windows

Posted on 1998-09-03
15
594 Views
Last Modified: 2013-11-20
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
0
Comment
Question by:bmelling9
15 Comments
 

Author Comment

by:bmelling9
Comment Utility
Edited text of question
0
 
LVL 3

Expert Comment

by:Norbert
Comment Utility
Did You try m_wndSplitter->Invalidate() ?
0
 
LVL 2

Expert Comment

by:milenvk
Comment Utility
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;
0
 

Author Comment

by:bmelling9
Comment Utility
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.
0
 
LVL 2

Expert Comment

by:jstolan
Comment Utility
I've never done a dynamic splitter like your application, but Invalidate() followed by UpdateWindow() will almost always work.
0
 
LVL 6

Expert Comment

by:snoegler
Comment Utility
CSplitterWnd::RecalcLayout() should be working, i think ...
It is called upon WM_SIZE messages, and should be called after layout changes.
Hope this works :)
0
 
LVL 1

Expert Comment

by:sudhirbrat
Comment Utility
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.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:bmelling9
Comment Utility
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...
0
 
LVL 1

Expert Comment

by:subbaiah
Comment Utility

Have U tried using UpdateAllViews().
0
 

Expert Comment

by:TangCheng
Comment Utility
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);
}

0
 
LVL 6

Expert Comment

by:snoegler
Comment Utility
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.
0
 

Author Comment

by:bmelling9
Comment Utility
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.  
0
 
LVL 6

Expert Comment

by:snoegler
Comment Utility
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

}
0
 

Author Comment

by:bmelling9
Comment Utility
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.
0
 
LVL 6

Accepted Solution

by:
snoegler earned 70 total points
Comment Utility
You need to have an open question (which is not yet rejected) to give the points.
So i'll post this here as a dummy :)
Thanks, BTW :)
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now