BeMDI SDK
left  4. Add a MDI view menu
up  Tutorial Index
5. Create some MDI views

Before we can display anything inside a MDI view we need a view class which is later used as sub-view of your MDI view.

When a MDI view is maximized its first child (ChildAt(0)) replaces the MDI client view. So if you want to display more than one view inside a maximizable MDI view add them to a common parent view, which is the first child of the MDI view.

When you create a BWindow the frame rectangle you pass to the constructor specifies the content area of the window. CMDIView behaves a bit different. When you pass a frame rectangle to the CMDIView constructor you really specify the frame rectangle of the view. Depending on the flags you've passed to the constructor the content area may be a lot smaller.

If you only care about the size of the frame rectangle and not about the size of the content area simply pass the frame rectangle to the CMDIView constructor. Later you can request the size of the content area by calling the ClientRect() method.

But normally you care about the size of the content area. Then you can call the constructor with 'resizeToClient' set to true. Then the MDI view ignores the size of the frame rectangle and adjusts itself to the size of the passed client view. The content area is then big enough to hold the client view.

In the example below I use the first variant to construct a MDI view. The example client view simply displays a pattern of red and blue lines.

class CExampleView : public BView
{
    public:
    CExampleView(BRect frame) : 
        BView(frame, "ExampleView", B_FOLLOW_ALL_SIDES, 
            B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE) {}
            
    virtual void Draw(BRect updateRect)
    {
        SetHighColor(CColor::White);
        FillRect(updateRect);
    
        const int32 lines = 20;
        
        float width  = Bounds().Width();
        float height = Bounds().Height();
        
        float dx = width / lines;
        float dy = height / lines;
        
        SetHighColor(CColor::Red);
        
        for(int i=0 ; i<lines ; i++) {
            StrokeLine(BPoint(i*dx, 0), BPoint(0, height-i*dy));
        }
    
        SetHighColor(CColor::Blue);
        
        for(int i=0 ; i<lines ; i++) {
            StrokeLine(BPoint(i*dx, height), BPoint(width,height-i*dy));
        }
    }
    
    virtual void AttachedToWindow()
    {
        SetViewColor(B_TRANSPARENT_COLOR);
    }
};

CExampleWindow::CExampleWindow(...)
{
    ....

    CMDIView *mdiView = 
        new CMDIView(BRect(20, 20, 160, 160), "MDI Test");
                                
    CExampleView *exampleView = 
        new CExampleView(mdiView->ClientRect());
        
    mdiView->AddChild(exampleView);
    
    client->AddMDIView(mdiView);
}

Please note that I set the view color to B_TRANSPARENT_COLOR and erase the background in the implementation of Draw(). Instead I could also set the view color to white. But the used solution looks a lot better. When you use a view color other than B_TRANSPARENT_COLOR the view flickers during resize and move, while the above solution is almost flicker free.

  Top


© 2000 by 3rd-evolution