Archived

This topic is now archived and is closed to further replies.

MFC+Splitterbars inside views

This topic is 6017 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I want to create a sdi mfc app with splitter bars inside views created by other splitter bars if you see what i mean. This is the sort of thing i want the window to look like:
________a_______________
|	|		|
|	|_______________|
|______	|		|
|	|		|
|_______|_______________|

  
I can get it so that there are 2 views with (a) to split them (mfc wizard does that). I can also get it so that i have 4 views in a:
  
_|_
 |
 
sort of format but i dont know how to arrange it so that the horizontal bar is split as in the above diagram. I know this sounds confusing but I dont know how to make it any clearer. If anyone has any info or help to offer on this I would be most grateful. Thanks for your time Edited by - Zeke on June 22, 2001 9:08:59 AM Edited by - Zeke on June 22, 2001 9:09:48 AM Edited by - Zeke on June 22, 2001 9:12:39 AM

Share this post


Link to post
Share on other sites
I''m working on stuff like this myself at the mo so I''ll try and help.

I think you need to think of what is going to be in each view.

I would recommend you split your MainFrm into 2 columns
giving....

--------------
| | |
| A | B |
| | |
--------------

you''ll need to attach RUNTME_CLASS in the splitter to each side.

then split these two in half.
giving.....

-----------------
| | |
|A(a)| B(a) |
|----| |
|A(b)|----------|
| | B(b) |
---------------

like I said I''m working on this myself at the mo and it is a bit of a bitch setting up the splitters with the proper view, frame classes etc

Hope this helps

BiGCyC

Share this post


Link to post
Share on other sites
Thanks for the reply.

I figured that you must have to split the window vertically and then in each view you need to split it horizontally, its just at the moment i just keep getting asserts when the app tries to split the views horizontally.

Share this post


Link to post
Share on other sites
Hmmmm

I had a lot of asserts myself, this was usually due to the RUNTIME_CLASS param in the Create functions.

One way of getting it to at least appear, was to pass the programs main view class into it and it would split with no problems.

can you get some code to show or something?

Share this post


Link to post
Share on other sites
Thanks BiGCyC. I dont think it is the RUNTIME_CLASS parameter because if i use any of the RUNTIME_CLASS params when trying to split the window into 2 views or 3 its fine.

Ill have to wait till monday to show you some code because my main computer is at my week home whereas im at my weekend home right now.

Thanks for the reply

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Hmmm...I want to learn the same thing but I hate working in MFC. Obviously you can do this in normal windows programming because all MFC is is just trying to make win programming easier ( i guess by making it worse?? ) by sorting it all out. Anyway, does anyone know how this is done?

Share this post


Link to post
Share on other sites
Anonymous Poster:

While working last year for my professor, he wanted a splitter bar put in. At the same time, I wasn''t using MFC.

As far as I know, there aren''t any easy ways of accomplishing a splitter bar without MFC.

What I ended up doing.

Create a frame window. Create 2 child windows within the frame window (each with a border). (Make the frame window the color you want your splitter bar to be). Keep track of which window the mouse is over. If the user clicks on the frame window, start resizing the other windows depending upon where he is dragging it.

If you want, I''ll put up a demo of a splitter bar non mfc style on my website.

(You have to understand though, I am far from a windows programming non mfc god though, so my code might not exactly be optimized or the best in the world, but at least it works)

Share this post


Link to post
Share on other sites
Creating Static Splitters with MFC

Ok lets see if this helps ya any Zeke. For more info and some source I suggest checking out the article here on gameDev "Creating 3D Tools with MFC" by Joe Houston. I took a lookesy and it had some decent beginner info in it and I found I make mine pretty much in the same way anyways, it might be good to grab the tut and src.

You said in your post you wanted a view that looked like this:
a
----------------------------------
| | |
| | |
| |----------------------| c
| | |
b |----------| |
| | |
-----------------------------------

I have labeled the splitters you will need to add as a,b,c
You must first subdivide the area using splitter a then again subdivide those spaces using splitters b and c.

I will walk you through this a step at a time but I take for granted that you have some experience with MFC generated code and class architecture.

We will start in MainFrm.h:

We need to add these member variables to the CMainFrame class.

CSplitterWnd Splitter1,
Splitter2,
Splitter3;
bool InitSplitters

Now we move onto MainFrm.cpp:

Here we need to use the class wizard to add two message handling functions to the CMainFrame class. We need to add the OnCreateClient function and the OnSize (WM_SIZE message handler) function

Now in CMainFrame''s constructor we add this line:

InitSplitters = false;

This variable will be explained when I get to recalculating the layout.

Next Edit the code for the function OnCreateClient
add this code to it:

if( !Splitter1.CreateStatic( this, 1,2 )) {
// Error message code here if desired
return false; }

This call to CreateStatic takes the parent window as an argument and creates a one row two column splitter...you can picture it like this

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

Now to split the two sections on either side of this splitter we must nest two more splitters...heres how

if( !Splitter2.CreateStatic( &Splitter1, 2,1, WS_CHILD |
WS_VISIBLE, Splitter1.IdFromRowCol(0,0) )) {
return false; }
if( !Splitter3.CreateStatic( &Splitter1, 2,1, WS_CHILD |
WS_VISIBLE, Splitter1.IdFromRowCol(0,1) )) {
return false; }

Instead of sending the this pointer (the CMainFrame class) we send the address of the splitter we just created. The rest of the arguments are self explanatory, instead of creating a view at the locations (0,0) and (0,1) we create new splitters We can now visualize this as:

---------- ------------ Diagram 1 shows the first nested
| | | | | | splitter and Diagram 2 shows what
|---| | |----|-----| the second would look like. You
| | | | | | can see that by changing the
---------- ------------ rows to 2 and columns to 1 we
achieve the split window look we
were after.
Now to create the four views:

if( !Splitter2.CreateView( 0,0,
RUNTIME_CLASS(CYourProjectNameView),
CSize( 25,100 ), pContext )) {
return false; }
if( !Splitter2.CreateView(1,0,
RUNTIME_CLASS(CYourProjectNameView),
CSize( 25,100 ), pContext )) {
return false; }

Now just follow this same method to create the two views for Splitter3. Creating the view involves sending the row/column indexs, the view class which I will explain more in a sec, the initial size which I find does not particularly matter but that seems to work well, and the last just feed pContext in.

The RUNTIME_CLASS macro enables MFC to create your class at runtime, if you want to know more about this there is more info in the MSDN Library. CYourProjectNameView simply means that if your project was call foobar it would be RUNTIME_CLASS(CFooBarView). All this does is provide a generic view so we can compile and check our splitter layouts, you can replace these with other classes derived from CView later on.

After you finish creating the views for the third splitter set the InitSplitters variable to true and return BUT
You have to change the defualt return value to just return true.
This way all the work we just did above we not be destroyed.

Phew! Anyone still reading this? If so we will move onto the OnSize function.

Here we will place the code to change the layout of the splitters everytime the app changes its size, so they will always stay in the right position.

Add this code underneath the line CFrameWnd::OnSize(....);

if( nType != SIZE_MINIMIZED && InitSplitters ) {

Splitter1.SetColumnInfo(0, cx / 2, 10 );
Splitter1.SetColumnInfo(1, cx / 2, 10 );
Splitter2.SetRowInfo( 0, cy / 2, 10 );
Splitter2.SetRowInfo( 1, cy / 2, 10 );
Splitter3.SetRowInfo( 0, cy / 2, 10 );
Splitter3.SetRowInfo( 1, cy / 2, 10 );

Splitter1.RecalcLayout();
Splitter2.RecalcLayout();
Splitter3.RecalcLayout();
}

Notice the use of the variable InitSplitters in the if statement. Must make sure that we do not try to recalculate the layout if the splitters have not yet been created as this will cause a crash. Also no reason in recalculating the size if the app is minimized, so we check the nType arg to make sure it is not.

The SetRowInfo and SetColumnInfo set the positions of the splitters row/columns. The first argument is the index to the row or column, the next is the position, and the last is the minimum pixels the splitter can be shrinked to.

After setting all the row/column information for each of the splitters just call RecalcLayout for each and thats all. This may not be the actual positioning you wanted and/or may not even work as I have not tested this code and just wrote it on the fly. But it should give you some more understanding of implementing splitters into your app. And you should be able to play with the values to get them to look the way you want.

If you have any more questions or problems I would be happy to try and answer them. I hope you can follow this easily and I hope my wording is alright. Let me know if this helped ya at all, it at least gave me a break from writing code

Also I recommend using the MSDN Library there is a wealth of information on just about everything

In my world editor I use some fixed defined values for certain splitters
IE
#define TEXTURE_WINDOW_SPLITTER 170
#define MESSAGE_WINDOW_SPLITTER 110

Which means that the texture window is always 170 pixels and you can do this just by changing the Row/ColumnInfo calls to incorporate this....That way I take into account that this splitter ALWAYS takes up 160 pixels and I have that less area to work with...

email addy == nullPointer@collegeclub.com

Share this post


Link to post
Share on other sites
Sorry about the diagrams they did not come out as I had anticipated but I have little experience posting on here. That was actually my first post.

Hope it helps ya out Zeke

Share this post


Link to post
Share on other sites
If you want some src code and a bit longer tut I suggested in my original post to check out gameDev''s article "Creating 3D Tools with MFC" by Joe Houston.

I Don''t have a web page yet but I hope to soon. I am going to start writing some tuts as I go along building my world editor.
I find MFC pretty easy to work with myself, it may take you a bit to get used to it but I think its worth it.

My first MFC app took me about 10 hrs total to get everything working the way I wanted it to, but a few days ago I sat down to get the framework laid out for my world editor project and I completed it in about 2hrs. Once you get comfortable with MFC you can accomplish some neat stuff pretty quickly and it is great for making tools for your game.

If you want me to write up some source and email it to ya I can though.

Share this post


Link to post
Share on other sites
Ok, here's a very very cheap splitter demo without using mfc.

(Its really part of another program I wrote awhile back. Much faster stripping out code then writing it from scratch, but I might have forgotten to strip out certain things).

When I have time, if enough interest, I'll write one like what the original poster wanted, and make it look decent at least, but in the little time I had, this will just have to do.

A link to a cheaply made splitter bar demo without mfc.

Stupid geocities... Normally, I'd use my school webpage, but I can't remotely log in today.

Edited by - Nytegard on June 24, 2001 1:04:45 PM

Share this post


Link to post
Share on other sites
Synapse>Thankyou so much. I followed what you said and it works and the best thing is I know where I was going wrong. I did it in the same way that you said however I was passing in the wrong variable to CreateStatic (the 1st parameter).

Thanks very much

Share this post


Link to post
Share on other sites
No problem Zeke, my pleasure. Got me away from coding for a little bit that night. Besides I had just taught myself the same thing a few months ago and had similar problems at first.

My code creates 4 viewports that divide the client area up equally. I showed you how to nest splitters so that you could create the view you had pictured in your first post. To create the 4 equally spaced viewports you didn''t actually have to nest them but I figured you could play with the oreintation to get the look you desired.

Its actually nice to know I helped ya out
Once I get some webspace I plan on making some tuts on such things, and perhaps a series on how to create a simple brush based world editor for use with BSP type engines.

If you have any other problems I can try and help ya out, just email me at the address in one of the previous posts. I check it every once in awhile so it may be a few days before I respond at all.

Share this post


Link to post
Share on other sites