145 lines
3.6 KiB
C++
145 lines
3.6 KiB
C++
|
// SplitWnd.cpp : implementation file
|
||
|
//
|
||
|
#include "stdafx.h"
|
||
|
#include "SplitterWndEx.h"
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
// HitTest return values (values and spacing between values is important)
|
||
|
// Had to adopt this because it has module scope
|
||
|
enum HitTestValue
|
||
|
{
|
||
|
noHit = 0,
|
||
|
vSplitterBox = 1,
|
||
|
hSplitterBox = 2,
|
||
|
bothSplitterBox = 3, // just for keyboard
|
||
|
vSplitterBar1 = 101,
|
||
|
vSplitterBar15 = 115,
|
||
|
hSplitterBar1 = 201,
|
||
|
hSplitterBar15 = 215,
|
||
|
splitterIntersection1 = 301,
|
||
|
splitterIntersection225 = 525
|
||
|
};
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CSplitterWndEx
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CSplitterWndEx, CSplitterWnd)
|
||
|
//{{AFX_MSG_MAP(CSplitterWndEx)
|
||
|
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||
|
//}}AFX_MSG_MAP
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
CWnd* CSplitterWndEx::GetActivePane(int* pRow, int* pCol)
|
||
|
{
|
||
|
ASSERT_VALID(this);
|
||
|
CWnd* pView = GetFocus();
|
||
|
// make sure the pane is a child pane of the splitter
|
||
|
if (pView != NULL && !IsChildPane(pView, pRow, pCol))
|
||
|
{
|
||
|
pView = NULL;
|
||
|
}
|
||
|
return pView;
|
||
|
}
|
||
|
|
||
|
void CSplitterWndEx::SetActivePane( int row, int col, CWnd* pWnd)
|
||
|
{
|
||
|
// set the focus to the pane
|
||
|
CWnd* pPane = pWnd == NULL ? GetPane(row, col) : pWnd;
|
||
|
pPane->SetFocus();
|
||
|
}
|
||
|
|
||
|
void CSplitterWndEx::StartTracking(int ht)
|
||
|
{
|
||
|
ASSERT_VALID(this);
|
||
|
if (ht == noHit)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// GetHitRect will restrict 'm_rectLimit' as appropriate
|
||
|
GetInsideRect(m_rectLimit);
|
||
|
if (ht >= splitterIntersection1 && ht <= splitterIntersection225)
|
||
|
{
|
||
|
// split two directions (two tracking 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)
|
||
|
{
|
||
|
// hit on splitter boxes (for keyboard)
|
||
|
GetHitRect(vSplitterBox, m_rectTracker);
|
||
|
int yTrackOffset = m_ptTrackOffset.y;
|
||
|
m_bTracking2 = TRUE;
|
||
|
GetHitRect(hSplitterBox, m_rectTracker2);
|
||
|
m_ptTrackOffset.y = yTrackOffset;
|
||
|
|
||
|
// center it
|
||
|
m_rectTracker.OffsetRect(0, m_rectLimit.Height()/2);
|
||
|
m_rectTracker2.OffsetRect(m_rectLimit.Width()/2, 0);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// only hit one bar
|
||
|
GetHitRect(ht, m_rectTracker);
|
||
|
}
|
||
|
|
||
|
// steal focus and capture
|
||
|
SetCapture();
|
||
|
SetFocus();
|
||
|
|
||
|
// make sure no updates are pending
|
||
|
RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
|
||
|
|
||
|
// set tracking state and appropriate cursor
|
||
|
m_bTracking = TRUE;
|
||
|
OnInvertTracker(m_rectTracker);
|
||
|
if (m_bTracking2)
|
||
|
{
|
||
|
OnInvertTracker(m_rectTracker2);
|
||
|
}
|
||
|
m_htTrack = ht;
|
||
|
SetSplitCursor(ht);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CSplitterWnd command routing
|
||
|
BOOL CSplitterWndEx::OnCommand(WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
if (CWnd::OnCommand(wParam, lParam))
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
// route commands to the splitter to the parent frame window
|
||
|
return (BOOL) GetParent()->SendMessage(WM_COMMAND, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
BOOL CSplitterWndEx::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult )
|
||
|
{
|
||
|
if (CWnd::OnNotify(wParam, lParam, pResult))
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
// route commands to the splitter to the parent frame window
|
||
|
*pResult = GetParent()->SendMessage(WM_NOTIFY, wParam, lParam);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CSplitterWndEx::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
|
||
|
{
|
||
|
// The code line below is necessary if using CSplitterWndEx in a regular dll
|
||
|
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||
|
return CWnd::OnWndMsg(message, wParam, lParam, pResult);
|
||
|
}
|