Introduction
Everyone who has tried to create a (nested) Splitter Window inside MDI or SDI applications knows how nasty that can get. So, I wanted to create a class that can be used to create nested splitter with oo-code, by simply adding rows and views. This project can easily be used to create SDI and MDI applications.
Doing It the MDI Way
- Create a sample MDI project with your VC Project Wizard and name it “MDISample”.
- Create a new MFC class of type CEditView and name it CSimpleView<./li>
- Create a new MFC class of type CDocument and name it CSimpleDoc.
- Create a new COMMON class of type ChyperSplitterMDI, name it CSimpleSplitter and put in DECLARE_DYNCREATE and IMPLEMNT_DYNCREATE Macros in .h and .cpp.
- Put in includes for HyperSplitterMDI.h and SimpleView.h and add the following code:
CSimpleSplitter::CSimpleSplitter() { CHyperSplitterChild* primarySplitter = AddSplitter(); primarySplitter->AddView(RUNTIME_CLASS(CSimpleView), 50, 0); CHyperSplitterChild* rightSplitter = primarySplitter->AddSplitter(); rightSplitter->AddView(RUNTIME_CLASS(CSimpleView), 25, 50); rightSplitter->AddView(RUNTIME_CLASS(CSimpleView), 75, 50); rightSplitter->AddRow(); rightSplitter->AddView(RUNTIME_CLASS(CSimpleView), 25, 50); rightSplitter->AddView(RUNTIME_CLASS(CSimpleView), 75, 50); }
- Include SimpleDoc.h and SimpleSplitter.h in your MDISample.cpp and insert or replace your DocTemplate:
CMultiDocTemplate* pDocTemplateSimple; pDocTemplateSimple = new CMultiDocTemplate( IDR_MDISAMTYPE, RUNTIME_CLASS(CSimpleDoc), // your Document class RUNTIME_CLASS(CSimpleSplitter), // Use HyperSplitter NULL); // instead of // Childframe // no view class here; // it's all defined in // SimpleSplitter AddDocTemplate(pDocTemplateSimple);
- Voilà, that’s it; you’ll receive a nice 1 to 4×4 Splitter Window with Edit Views:
- Okay, now to the explanation—what have you done in Step 5?
- First, you get the primary splitter with AddSpliter(); this has always to be done.
- Then, you add the first view to the left and give it 50% width and all the available height (0).
- Next, you have to add a right splitter because you don’t want one view to the left and 4×4 to the right.
- Then, you can simply add two views, one with 25% and one with 75% of the current width, and 50% in height.
- Add a new row.
- Again, add two new views the same size as the ones above.
- What you should keep in mind:
- Adding splitters or views is always done from left to right (x-axis).
- Sizes are always in percents and relative to the last (parent) splitter.
- With AddRow(), you can add a new row and move it on the y-axis.
- You have to add a new splitter if you want odd view counts in different parts of your window.
- You must have equal view counts in each row, or you again have to resplit.
- In some cases, the MFC splitter manager behaves strangely and your views are not shown in the way you’d expect them to be. If this happens, AddSplitter also takes size arguments.
- Because you have an MDI application here, you can now happily add more split Doc templates.
Doing It the SDI Way
- Create a sample MDI project with your VC Project Wizard and name it “SDISample”.
- Create three new MFC classes:
- Create a new MFC class of type CTreeView and name it CMyTreeView.
- Create a new MFC class of type CListView and name it CMyListView.
- Create a new MFC class of type CEditView and name it CMyTextView.
- Create a new MFC class of type CDocument and name it CMyDoc.
- Create a new COMMON class of type CHyperSplitterSDI. Name it CMainFrameSplitter and put DECLARE_DYNCREATE and IMPLEMNT_DYNCREATE Macros in .h and .cpp.
- Put in includes for HyperSplitterMDI.h, MyListView.h, MyTreeView, and MyTextView and add the following code:
- Include MyDoc.h and MainFrameSplitter.h in your SDISample.cpp and insert or replace your DocTemplate:
- Again, that’s it. You’ll get a nice tree/list combination with two text panes (bottom and top)
- Okay, now to the explanation. This example is a little more complicated:
- Again, you have to get the primary splitter at first.
- Then, you add the first upper splitter because you are going to have odd view counts in the upper part and only one textview to the bottom.
- Add the TreeView.
- Add the next splitter (right upper) to get a textview (top)/listview combination.
- Finally, add another row to the primary splitter and the bottom text view.
- Okay, that’s it so far. Have fun….
CMainFrameSplitter::CMainFrameSplitter() { CHyperSplitterChild* primarySplitter = AddSplitter(); CHyperSplitterChild* upperSplitter = primarySplitter->AddSplitter(); upperSplitter->AddView(RUNTIME_CLASS(CMyTreeView), 30, 100); CHyperSplitterChild* rightUpperSplitter = upperSplitter->AddSplitter(); rightUpperSplitter->AddView(RUNTIME_CLASS(CMyTextView), 100, 5); rightUpperSplitter->AddRow(); rightUpperSplitter->AddView(RUNTIME_CLASS(CMyListView), 100, 95); primarySplitter->AddRow(); primarySplitter->AddView(RUNTIME_CLASS(CMyTextView), 100, 10); }
CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS (CMainFrameSplitter), NULL); AddDocTemplate(pDocTemplate);