Click here to Skip to main content
15,882,152 members
Articles / Desktop Programming / WTL
Article

WTL Snapping Splitter Window

Rate me:
Please Sign up or sign in to vote.
3.29/5 (7 votes)
14 Feb 20032 min read 58.8K   1.4K   14   6
A simple adaptation of the WTL CSplitterWindow to add snap-to support.

Image 1

Introduction

I was developing an application that used the calendar control and needed to control the behavior of the splitter window that contained the calendar control so I thought I would create a splitter window that supported a snap-to behavior.

Background

My original decision led me astray as I tried to reimplement the entire CSplitterWindow as a new class, when it hit me, just override the OnMouseMove method. So this is where we stand. Its a simple change to the code but I thought it would be an interesting contribution so I decided to wrap it up and submit it to CodeProject.

Using the code

The code is very easy and straightforward to use. You use it just like the CSplitterWindow class but there is one additional method SetSnapSize that controls how big a snap to perform. The code takes care of whether you are using a vertical splitter or a horizontal splitter.

The "biggest" change to the class was a few lines of code that were added to the CSnapSplitterWindow class that derives from CSplitterWindow. In the OnSize method the following code was added to support the snap-to place. The variable m_nSnapSize holds the size that the programmer wants the window to snap-to. During a mouse move I determine if the new position of the splitter is greater than 1/2 the snap size and if it is, I adjust the splitter to the next snap position. This is a simple operation but is really the "meat" of the code.

// this is all that is required to make it snappable
if( static_cast<UINT>(abs( xyNewSplitPos - m_xySplitterPos )) > 
    ( m_nSnapSize / 2 ))
{
    if( xyNewSplitPos < m_xySplitterPos )
        xyNewSplitPos = m_xySplitterPos - m_nSnapSize;
    else
        xyNewSplitPos = m_xySplitterPos + m_nSnapSize;
}
else
    xyNewSplitPos = m_xySplitterPos;

To use the code declare a variable of CSnapSplitterWindow if you want a vertical splitter that snaps on left and right movements or use CHorSnapSplitterWindow to create a horizontal splitter that snaps on up and down movements. The following code would be placed in your CMainFrame class in the OnCreate method.

class CMainFrame : public CFrameWindowImpl<CMainFrame>, 
    public CUpdateUI<CMainFrame>,
    public CMessageFilter, public CIdleHandler
{
public:
    DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)

    CSnapSplitterWindow    m_splitterContent;
    
    ...
    
    LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, 
        LPARAM /*lParam*/, BOOL& /*bHandled*/)
    {
        
        ...
        
        m_hWndClient = m_splitterContent.Create( m_hWnd, rcDefault, 
                NULL, WS_CHILD | WS_VISIBLE );
        m_splitterContent.SetSnapSize( 75 );
        
        ...
        
    }
    
    ...
    
};    

Points of Interest

It wasn't very hard to write this class once I got over my initial attempt to try to rewrite the entire CSplitterWindow class but the one problem that I had was using the CMonthCalendarCtrl class. I made the call to GetMinReqRect expecting to get the minimum size the control needs to display itself. Thinking that the minimum size would be all that is required to set the snap size for both horizontal and vertical I used it but I noticed that the control wouldn't display another month in the display. So I had to play around with some different height and width adjustments before I found some values that were the smallest possible and still allow the control to behave as expected when it snapped to a larger size.

History

VersionComments
1.0 - 14 Feb 2003First release version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Architect Match.com
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralEnhancements Pin
Terry Denham19-Feb-03 5:01
Terry Denham19-Feb-03 5:01 
GeneralNo offense... Pin
Shog915-Feb-03 7:20
sitebuilderShog915-Feb-03 7:20 
GeneralRe: No offense... Pin
Terry Denham15-Feb-03 12:56
Terry Denham15-Feb-03 12:56 
GeneralRe: No offense... Pin
Shog917-Feb-03 11:33
sitebuilderShog917-Feb-03 11:33 
Terry Denham wrote:
Not that is a defense but this is exactly the way Outlook works.

Yeah... i agree it looks nice, you never end up with a month cut off (or, lots of whitespace as the case may be).

Terry Denham wrote:
Well you can do this, but I even trap it when its in full drag mode, it doesn't draw the ghostbar and you keep moving the resize pointer until you get to the next snap point and then it will snap-to.

Well, i've thought about this some more, and while i see your point, it still seems like there'd be some way to implement it while providing instant feedback. Perhaps, you could keep track of the mouse motion over time, such that dragging the bar in either direction immediately snaps it to the next point, but requires a greater motion in the opposite direction to snap it back...?

shog
nine

  Ever since i heard the voice
i thought i had no choice...

GeneralRe: No offense... Pin
Terry Denham17-Feb-03 11:50
Terry Denham17-Feb-03 11:50 
GeneralRe: No offense... Pin
Shog917-Feb-03 14:01
sitebuilderShog917-Feb-03 14:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.