Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS General Discussion » How to leave space around my SplitterWnd? Collapse All
Subject Author Date
Suhai Gyorgy Sep 21, 2005 - 8:51 AM

Hi!


My SDI app uses a static horizontal SplitterWnd with two FormViews on each side. My problem is, that I would like to leave some space (like 5 pixel or so) around each side of the SlitterWnd (something like in the Outlook 2003 application). How could I do that, so that this "border" would be like a background, colored as if it was part of the non-client area (darker on the left, lighter on the right)?


I checked out your CExtSplitterWnd class, that nicely colors the splitBar between the two Views but has no way of leaving space around it.


 


Thank you for your help!  Chris.

Technical Support Sep 21, 2005 - 10:05 AM

The outer 5-pixel border can be implemented as a non-client area of the splitter window. The following CExtSplitterWnd-derived class uses this approach:

class CYourSplitterWnd : public CExtSplitterWnd
{
public:
    CRect m_rcNcAreaSizes;
    CYourSplitterWnd()
        : m_rcNcAreaSizes( 5, 5, 5, 5 )
    {
    }
protected:
    virtual LRESULT WindowProc(
        UINT message, WPARAM wParam, LPARAM lParam )
    {
        if( message == WM_NCCALCSIZE )
        {
            NCCALCSIZE_PARAMS * pNCCSP =
                reinterpret_cast < NCCALCSIZE_PARAMS * > ( lParam );
            ASSERT( pNCCSP != NULL );
            CRect rcInBarWnd( pNCCSP->rgrc[0] );
            rcInBarWnd.DeflateRect(
                m_rcNcAreaSizes.left,
                m_rcNcAreaSizes.top,
                m_rcNcAreaSizes.right,
                m_rcNcAreaSizes.bottom
                );
            ::CopyRect( &(pNCCSP->rgrc[0]), rcInBarWnd );
            return 0;
        }
        if( message == WM_NCPAINT )
        {
            CRect rcInBarWnd, rcInBarClient;
            GetWindowRect( &rcInBarWnd );
            GetClientRect( &rcInBarClient );
            ClientToScreen( &rcInBarClient );
            if( rcInBarWnd == rcInBarClient )
                return 0;
            CPoint ptDevOffset = -rcInBarWnd.TopLeft();
            rcInBarWnd.OffsetRect( ptDevOffset );
            rcInBarClient.OffsetRect( ptDevOffset );
            CWindowDC dc( this );
            ASSERT( dc.GetSafeHdc() != NULL );
            dc.ExcludeClipRect( &rcInBarClient );
            if(  (! g_PaintManager->GetCb2DbTransparentMode(this) )
                || (! g_PaintManager->PaintDockerBkgnd( true, dc, this ) )
                )
                dc.FillSolidRect(
                    &rcClient,
                    g_PaintManager->GetColor(
                        CExtPaintManager::CLR_3DFACE_OUT,
                        this
                        )
                    );
            return 0;
        }
        return CExtSplitterWnd::WindowProc(
            message, wParam, lParam );
    }
};

Suhai Gyorgy Sep 22, 2005 - 3:19 AM

One more thing I forgot to tell: When I use CExtSplitterWnd, everything works fine. When I put CYourSplitterWnd in instead, it gives me the failure. That’s why I thought it might have something to do with your code. Thanks.

Suhai Gyorgy Sep 22, 2005 - 3:08 AM

Hi!


Unfortunately I couldn’t say it looks good because I couldn’t make it work yet. My first problem was: There’s a variable I guess miswritten:


if(  (! g_PaintManager->GetCb2DbTransparentMode(this) )
                || (! g_PaintManager->PaintDockerBkgnd( true, dc, this ) )
                )
                dc.FillSolidRect(
                    &rcClient,
                    g_PaintManager->GetColor(
                        CExtPaintManager::CLR_3DFACE_OUT,
                        this
                        )
                    );


In this part rcClient is not recognized... But I guessed it was rcInBarClient, and with that I could rebuild it successfully.


Next problem: Assertion failure. It seems like when I call "CExtSplitterWnd::WindowProc(message, wParam, lParam );" at the very end, it calls "CWnd::WindowProc(message, wParam, lParam );" instead!!


I put the above code in my MainFrame.h file before my class CMainFrame : public CFrameWnd{...}  What could cause the problem?


 


Thank you.  Chris

Technical Support Sep 22, 2005 - 10:12 AM

Honestly speaking, the CYourSplitterWnd class in our previous message was written on-the-fly within two minutes and without any testing. We are sorry for any inconvenience. Here is a tested and debugged version of this class:

class CYourSplitterWnd : public CExtSplitterWnd
{
public:
    CRect m_rcNcAreaSizes;
    CYourSplitterWnd()
        : m_rcNcAreaSizes( 5, 5, 5, 5 )
    {
    }
protected:
    virtual LRESULT WindowProc(
        UINT message, WPARAM wParam, LPARAM lParam )
 
    {
        if( message == WM_NCCALCSIZE )
        {
            NCCALCSIZE_PARAMS * pNCCSP =
                reinterpret_cast < NCCALCSIZE_PARAMS * > ( lParam );
            ASSERT( pNCCSP != NULL );
            CRect rcInBarWnd( pNCCSP->rgrc[0] );
            rcInBarWnd.DeflateRect(
                m_rcNcAreaSizes.left,
                m_rcNcAreaSizes.top,
                m_rcNcAreaSizes.right,
                m_rcNcAreaSizes.bottom
                );
            ::CopyRect( &(pNCCSP->rgrc[0]), rcInBarWnd );
            return 0;
        }
        if( message == WM_NCPAINT )
        {
            CRect rcInBarWnd, rcInBarClient;
            GetWindowRect( &rcInBarWnd );
            GetClientRect( &rcInBarClient );
            ClientToScreen( &rcInBarClient );
            if( rcInBarWnd == rcInBarClient )
                return 0;
            CPoint ptDevOffset = -rcInBarWnd.TopLeft();
            rcInBarWnd.OffsetRect( ptDevOffset );
            rcInBarClient.OffsetRect( ptDevOffset );
            CWindowDC dc( this );
            ASSERT( dc.GetSafeHdc() != NULL );
            dc.ExcludeClipRect( &rcInBarClient );
            if(  (! g_PaintManager->GetCb2DbTransparentMode(this) )
                || (! g_PaintManager->PaintDockerBkgnd( false, dc, this ) )
                )
                dc.FillSolidRect(
                    &rcInBarWnd,
                    g_PaintManager->GetColor(
                        CExtPaintManager::CLR_3DFACE_OUT,
                        this
                        )
                    );
            return 0;
        }
        return CExtSplitterWnd::WindowProc(
            message, wParam, lParam );
    }
    virtual void RecalcLayout()
    {
        if( m_pColInfo == NULL || m_pRowInfo == NULL )
            return;
        CExtSplitterWnd::RecalcLayout();
    }
};


Suhai Gyorgy Sep 23, 2005 - 4:43 AM

Thank you, it works great now!