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.
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 , WPARAM ,
LPARAM , BOOL& )
{
...
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
Version |
Comments |
1.0 - 14 Feb 2003 |
First release version. |