CodeGuru content and product recommendations are
editorially independent. We may make money when you click on links
to our partners.
Learn More
If you want to implement splitter window in your MFC based application
that redraws its panes dynamically
(like Microsoft Windows Explorer does when you have IE4.0 installed)
then you can use my simple
class CDynSplitterWnd. Dragging CDynSplitterWnd splitter bar does not
show a hatched line, instead it immediately redraws itself at a new
position as well as forces all its panes to redraw themselves.
To implement CDynSplitterWnd window simply:
1. Change declaration of your splitter window instances to be
instances of the CDynSplitterWnd class rather than CSplitterWnd class.
2. Or derive your own CSplitterWnd based classes (if you have them)
from CDynSplitterWnd instead, and
don’t forget about BEGIN_MESSAGE_MAP(CYourSplitterWnd,
CDynSplitterWnd) macro.
CDynSplitterWnd works best for the “1column 2 rows static
splitter” situation. If you have MFC dynamic splitters create them with
SIZE sizeMin parameter in CSplitterWnd ::Create(…) function set to
CSize(1,1) or CSize(0,0).
class CDynSplitterWnd : public CSplitterWnd
{
public:
CDynSplitterWnd();
public:
BOOL IsDynamic()
{ return m_bDynSplit; }
void SetDynamic(BOOL bDynSplit = TRUE)
{ m_bDynSplit = bDynSplit; }
public:
virtual void OnInvertTracker(const CRect& rect);
virtual void StartTracking(int ht);
virtual void StopTracking(BOOL bAccept);
public:
virtual ~CDynSplitterWnd();
protected:
CPoint m_OldPoint;
BOOL m_bDynSplit;
enum HitTestValue
{
noHit = 0,
vSplitterBox = 1,
hSplitterBox = 2,
bothSplitterBox = 3,
keyboard
vSplitterBar1 = 101,
vSplitterBar15 = 115,
hSplitterBar1 = 201,
hSplitterBar15 = 215,
splitterIntersection1 = 301,
splitterIntersection225 = 525
};
protected:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP()
};
#include "stdafx.h"
#include <afxext.h>
#include "DynSplitterWnd.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define CX_BORDER 1
#define CY_BORDER 1
#define FAR_POINT_XY -10000
CDynSplitterWnd::CDynSplitterWnd()
:m_OldPoint(FAR_POINT_XY,FAR_POINT_XY),
m_bDynSplit(TRUE)
{
}
CDynSplitterWnd::~CDynSplitterWnd()
{
}
void CDynSplitterWnd::OnInvertTracker(const CRect& rect)
{
if(!m_bDynSplit)
CSplitterWnd::OnInvertTracker(rect);
else
return;
}
void CDynSplitterWnd::StartTracking(int ht)
{
if(!m_bDynSplit)
{
CSplitterWnd::StartTracking(ht);
return;
}
ASSERT_VALID(this);
if (ht == noHit)
return;
GetInsideRect(m_rectLimit);
if (ht >= splitterIntersection1 && ht <=
splitterIntersection225)
{
rectangles)
int row = (ht - splitterIntersection1) / 15;
int col = (ht - splitterIntersection1) % 15;
GetHitRect(row + vSplitterBar1, m_rectTracker);
int yTrackOffset = m_ptTrackOffset.y;
m_bTracking2 = TRUE;
GetHitRect(col + hSplitterBar1, m_rectTracker2);
m_ptTrackOffset.y = yTrackOffset;
}
else if (ht == bothSplitterBox)
{
GetHitRect(vSplitterBox, m_rectTracker);
int yTrackOffset = m_ptTrackOffset.y;
m_bTracking2 = TRUE;
GetHitRect(hSplitterBox, m_rectTracker2);
m_ptTrackOffset.y = yTrackOffset;
m_rectTracker.OffsetRect(0,
m_rectLimit.Height()/2);
m_rectTracker2.OffsetRect(m_rectLimit.Width()/2,
0);
}
else
{
GetHitRect(ht, m_rectTracker);
}
SetCapture();
m_bTracking = TRUE;
m_htTrack = ht;
SetSplitCursor(ht);
}
void CDynSplitterWnd::StopTracking(BOOL bAccept)
{
ASSERT_VALID(this);
if (!m_bTracking)
return;
ReleaseCapture();
OnInvertTracker(m_rectTracker);
if (m_bTracking2)
OnInvertTracker(m_rectTracker2);
m_bTracking = m_bTracking2 = FALSE;
CWnd* pOldActiveView = GetActivePane();
(without border)
m_rectTracker.OffsetRect(-CX_BORDER , -CY_BORDER);
m_rectTracker2.OffsetRect(-CX_BORDER, -CY_BORDER);
if (bAccept)
{
if (m_htTrack == vSplitterBox)
{
SplitRow(m_rectTracker.top);
}
else if (m_htTrack >= vSplitterBar1 && m_htTrack
<= vSplitterBar15)
{
TrackRowSize(m_rectTracker.top,
m_htTrack - vSplitterBar1);
RecalcLayout();
}
else if (m_htTrack == hSplitterBox)
{
SplitColumn(m_rectTracker.left);
}
else if (m_htTrack >= hSplitterBar1 && m_htTrack
<= hSplitterBar15)
{
TrackColumnSize(m_rectTracker.left,
m_htTrack - hSplitterBar1);
RecalcLayout();
}
else if (m_htTrack >= splitterIntersection1 &&
m_htTrack <= splitterIntersection225)
{
int row = (m_htTrack -
splitterIntersection1) / 15;
int col = (m_htTrack -
splitterIntersection1) % 15;
TrackRowSize(m_rectTracker.top, row);
TrackColumnSize(m_rectTracker2.left,
col);
RecalcLayout();
}
else if (m_htTrack == bothSplitterBox)
{
rows)
cols)
SplitRow(m_rectTracker.top);
SplitColumn(m_rectTracker2.left);
}
}
if ( (pOldActiveView == GetActivePane()) &&
(pOldActiveView != NULL)
)
SetActivePane(-1, -1, pOldActiveView);
}
BEGIN_MESSAGE_MAP(CDynSplitterWnd, CSplitterWnd)
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
void CDynSplitterWnd::OnMouseMove(UINT nFlags, CPoint pt)
{
if(!m_bDynSplit)
{
CSplitterWnd::OnMouseMove(nFlags, pt);
return;
}
if (GetCapture() != this)
StopTracking(FALSE);
if (m_bTracking)
{
pt.Offset(m_ptTrackOffset);
right of hit detect
if (pt.y < m_rectLimit.top)
pt.y = m_rectLimit.top;
else if (pt.y > m_rectLimit.bottom)
pt.y = m_rectLimit.bottom;
if (pt.x < m_rectLimit.left)
pt.x = m_rectLimit.left;
else if (pt.x > m_rectLimit.right)
pt.x = m_rectLimit.right;
if (m_htTrack == vSplitterBox ||
m_htTrack >= vSplitterBar1 && m_htTrack
<= vSplitterBar15)
{
if (m_rectTracker.top != pt.y)
{
OnInvertTracker(m_rectTracker);
m_rectTracker.OffsetRect(0, pt.y
- m_rectTracker.top);
OnInvertTracker(m_rectTracker);
}
}
else if (m_htTrack == hSplitterBox ||
m_htTrack >= hSplitterBar1 && m_htTrack
<= hSplitterBar15)
{
if (m_rectTracker.left != pt.x)
{
OnInvertTracker(m_rectTracker);
m_rectTracker.OffsetRect(pt.x -
m_rectTracker.left, 0);
OnInvertTracker(m_rectTracker);
}
}
else if (m_htTrack == bothSplitterBox ||
(m_htTrack >= splitterIntersection1 &&
m_htTrack <= splitterIntersection225))
{
if (m_rectTracker.top != pt.y)
{
OnInvertTracker(m_rectTracker);
m_rectTracker.OffsetRect(0, pt.y
- m_rectTracker.top);
OnInvertTracker(m_rectTracker);
}
if (m_rectTracker2.left != pt.x)
{
OnInvertTracker(m_rectTracker2);
m_rectTracker2.OffsetRect(pt.x -
m_rectTracker2.left, 0);
OnInvertTracker(m_rectTracker2);
}
}
OnLButtonUp(MK_LBUTTON,pt);
OnLButtonDown(MK_LBUTTON,pt);
if(m_OldPoint != pt)
{
RedrawWindow(NULL, NULL, RDW_ALLCHILDREN
| RDW_UPDATENOW);
m_OldPoint = pt;
}
}
else
{
int ht = HitTest(pt);
SetSplitCursor(ht);
}
}
Download file 52K
Updated 4 April 1998