Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 532
  • Last Modified:

Static Splitter on the fly?

This is 1 of 2 related questions on MFC, asked on same day.

My App is MFC, Doc/View, SDI.  Using MFC 4.2 with Visual C++ 6

The main view contains a FormView derived class

When the app is opened only this is View is shown

When the user takes some action (like a Special File New/Open) I want to open up a splitter.  The splitter is vertical.  On left pane, my formview derived class.  On the right pane there is a special scrolling list (see other question if you are interested in detail of this)

I do not believe a dynamic splitter will do the job, as this requires all the views to be of the same time

Therefore I think I need a static splitter

The question is how can I create a static splitter after the app is already running?

The possible trick I have thought of is to make the 2 panes always at start, and hide (or make zero width) the right pane.  

What is the best way to solve this.  Needs to be bullet proof as I can not rely on friendly users to with limitations. (example: if I make a zero with pane, there must be no way a user can make it bigger unless I saw so)


I realize this could be hard, so if it someone spends a lot of time (like makes a test program or gives actual code), I will give exrta points, as I have lots to spare.
0
Answers2000
Asked:
Answers2000
  • 5
  • 3
1 Solution
 
migelCommented:
Hi!
it is no big problem:
1. in the your frame window class add method : ShowSplitter
   also you have to add member CSplitterWnd m_wndSplit;
2. Code for this method in general must
a) Get view curently showed on the frame
b) Create static splitter
c) Create one pane for splitter (Form View)
d) Set for your view proper Window ID (getted from splitter for second plane)
e)Change parent for view to the splitter
f) Call ReclacLayout for splitter.
here is code( I`m not test this but general rule you can catch :-) )
   
CMyFrame::ShowSplitter()
{
   CWnd* pWnd = GetWindow(GW_CHILD); // get current view
   if (!m_wndSplitter.CreateStatic(this, 1,2)
        return;

   if (!m_wndSplitter.CreateView(1,0, RUNTIME_CLASS(CFormView), CSize(120, 0), pContext))
                  {
                  TRACE0("Failed to create !");
                  return;
                  }
    ::SetWindowLong(pWnd->m_hWnd, GWL_ID, m_wndHorzSplitter.IdFromRowCol(0, 0));
    pWnd->SetParent(&m_wndSplitter);
    m_wndSplitter.RecalcLayout();
}
0
 
Answers2000Author Commented:
Neat idea, get the concept, but can't make it work.

1. pContext - where does this come from? I tried making an empty CCreateContext structure and passing pointer to that (actually just declare it, as Docs and MFC sources show it's all initialized to NULLs)

2. I think it's CreateView(0,1,etc..) to match the set up above? (if not I get an ASSERT in MFC sources on a line checking the rows/columns parameters)

3. Fixing 1+2 with CSize(120,0) - the existing view appears to go dead (won't respond) get ASSERT in MFC WINGDI.CPP line 417. Seems to suggest something like the original view has been lost or lost it's data

4. Tried with CSize(120,120). CreateView now fails.  After that original view appears to go dead (won't respond to mouse etc), and when exit the app, I get another asset in MFC sources. This one inside GetPane function - WINSPLIT.CPP line 364. Basically a pane is NULL (my original view) when it shouldn't be.

I don't know but 3+4 seem to suggest that I'm missing some vital detail? Perhaps item 2?
0
 
migelCommented:
hmm
ok I will check it in the test project
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
migelCommented:
Ok
here is working code:
void CMainFrame::OnSplit()
{
     // TODO: Add your command handler code here
     CWnd* pWndChild = GetWindow(GW_CHILD);
     m_wndSplit.CreateStatic(this, 1, 2);
     CCreateContext context;
     context.m_pCurrentDoc = this->GetActiveDocument();
     context.m_pCurrentFrame = this;
     context.m_pLastView = NULL;
     context.m_pNewDocTemplate = NULL;
     context.m_pNewViewClass = RUNTIME_CLASS(CMyFormView);
     m_wndSplit.CreateView(0, 0, RUNTIME_CLASS(CMyFormView), CSize(100,100), &context);
     int nID = m_wndSplit.IdFromRowCol(0, 1);
     ::SetWindowLong(pWndChild->GetSafeHwnd(), GWL_ID, nID);
     pWndChild->SetParent(&m_wndSplit);
     CRect rc;
     GetClientRect(&rc);
     m_wndSplit.MoveWindow(&rc);
     m_wndSplit.RecalcLayout();
}
0
 
Answers2000Author Commented:
Close not quite

1. It creates the new view on the left (should be right)

2. The new view is supposed to be my new view class, the list properties thing. I changed CMyFormView in code to CEditView for testing for now (as my existing form view can't handle being alive twice)

3. This works, with above limitations except the new view overlaps the toolbars (and possibly status - not sure as it gets repainted immediately). If you mouse over where the toolbar should be, you can then get bits of the toolbar to leak thru. The MoveWindow is definitely necessary - but it needs to be the rect minus the (dockable) toolbars etc.  Incidentally if you resize the window once or twice or start dragging the toolbar around, you can get it to recover, so the toolbar stops leaking into the view.
0
 
migelCommented:
Okay
1. It isn`t matter - the technique works :-)
2. See above
3. Hmmm it is bad...
so You have to use this code
{
        RECT rcWindow;
         RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery, &rcWindow);
}

instead GetClientRect();
0
 
migelCommented:
?
0
 
Answers2000Author Commented:
I'll give you the points

I'm probably not going to go this route in the app now (going with modeless floating windows).  The other properties list question is going to get some action soon.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now