📄 fixedsizecontrolbar.cpp
字号:
// FixedSizeControlBar.cpp : implementation file
//
#include "stdafx.h"
#include "gstools.h"
#include "FixedSizeControlBar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern SEC_AUX_DATA secData;
/////////////////////////////////////////////////////////////////////////////
// Unnamed namespace
namespace
{
/////////////////////////////////////////////////////////////////////////////
// t_dock_context class
void AdjustRectangle(CRect& rect, CPoint pt)
{
int nXOffset = (pt.x < rect.left) ? (pt.x - rect.left) :
(pt.x > rect.right) ? (pt.x - rect.right + secData.cxBorder2) : 0;
int nYOffset = (pt.y < rect.top) ? (pt.y - rect.top) :
(pt.y > rect.bottom) ? (pt.y - rect.bottom + secData.cxBorder2) : 0;
rect.OffsetRect(nXOffset, nYOffset);
}
class t_dock_context : public SECDockContext
{
public:
// Constructor
t_dock_context( CFixedSizeControlBar * bar ) : SECDockContext( bar ) {}
// Member functions
virtual void StartDrag(CPoint pt);
void EndDrag(); // drop
private:
BOOL Track();
};
void t_dock_context::StartDrag(CPoint pt)
{
ASSERT_VALID(m_pBar);
m_bDragging = TRUE;
m_ptStartDrag = pt;
m_nPosDockingRow = -1;
// put the "Control to prevent docking" message in the status bar
CWnd *pMainWnd = AfxGetMainWnd();
ASSERT(pMainWnd != NULL);
pMainWnd->SendMessage(WM_SETMESSAGESTRING, (WPARAM)IDS_SEC_STARTDOCKING);
InitLoop();
// get true bar size (including borders)
CRect rect;
m_pBar->GetWindowRect(rect);
m_ptLast = pt;
CSize sizeHorz = m_pBar->CalcDynamicLayout(-1, LM_HORZ | LM_HORZDOCK);
CSize sizeVert = m_pBar->CalcDynamicLayout(-1, LM_VERTDOCK);
// calculate frame dragging rectangle
m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
m_rectDragVert = CRect(rect.TopLeft(), sizeVert);
m_rectFrameDragHorz = CRect( rect.TopLeft(), m_pBar->CalcDynamicLayout( -1, LM_HORZ ) );
m_rectFrameDragVert = CRect( rect.TopLeft(), m_pBar->CalcDynamicLayout( -1, 0 ) );
CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
m_rectFrameDragHorz.InflateRect(-secData.cxBorder2, -secData.cyBorder2);
m_rectFrameDragVert.InflateRect(-secData.cxBorder2, -secData.cyBorder2);
// adjust rectangles so that point is inside
AdjustRectangle(m_rectDragHorz, pt);
AdjustRectangle(m_rectDragVert, pt);
AdjustRectangle(m_rectFrameDragHorz, pt);
AdjustRectangle(m_rectFrameDragVert, pt);
// initialize tracking state and enter tracking loop
m_dwOverDockStyle = CanDock();
Move(pt); // call it here to handle special keys
Track();
}
void t_dock_context::EndDrag()
{
if (m_dwOverDockStyle != 0 && (!m_pBar->IsFloating() || (m_pBar->IsFloating() &&
(abs(m_ptLast.x - m_ptStartDrag.x) + abs(m_ptLast.y - m_ptStartDrag.y)) > 4)))
SECDockContext::EndDrag();
else
{
CancelLoop();
if ((m_dwStyle & CBRS_SIZE_DYNAMIC) || ( ( m_dwStyle & CBRS_ORIENT_HORZ ) != 0 && !m_bFlip) ||
( ( m_dwStyle & CBRS_ORIENT_VERT ) != 0 && m_bFlip))
m_dwMRUFloatStyle = CBRS_ALIGN_TOP;
else
m_dwMRUFloatStyle = CBRS_ALIGN_LEFT;
m_dwMRUFloatStyle |= ( m_dwDockStyle & CBRS_FLOAT_MULTI );
m_ptMRUFloatPos = m_rectFrameDragVert.TopLeft();
if (m_pDockSite->IsKindOf(RUNTIME_CLASS(SECMDIFrameWnd)))
((SECMDIFrameWnd*)m_pDockSite)->FloatControlBar(m_pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle);
else if (m_pDockSite->IsKindOf(RUNTIME_CLASS(SECFrameWnd)))
((SECFrameWnd*)m_pDockSite)->FloatControlBar(m_pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle);
else
m_pDockSite->FloatControlBar(m_pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle);
m_bDragging = FALSE;
}
}
BOOL t_dock_context::Track()
{
// don't handle if capture already set
if (::GetCapture() != NULL)
return FALSE;
// set capture to the window which received this message
m_pBar->SetCapture();
ASSERT(m_pBar == CWnd::GetCapture());
// get messages until capture lost or cancelled/accepted
while (CWnd::GetCapture() == m_pBar)
{
MSG msg;
if (!::GetMessage(&msg, NULL, 0, 0))
{
AfxPostQuitMessage(msg.wParam);
break;
}
switch (msg.message)
{
case WM_LBUTTONUP:
if (m_bDragging)
EndDrag();
else
EndResize();
return TRUE;
case WM_MOUSEMOVE:
if (m_bDragging)
Move(msg.pt);
else
Stretch(msg.pt);
break;
case WM_KEYUP:
if (m_bDragging)
OnKey((int)msg.wParam, FALSE);
break;
case WM_KEYDOWN:
if (m_bDragging)
OnKey((int)msg.wParam, TRUE);
if (msg.wParam == VK_ESCAPE)
{
CancelLoop();
return FALSE;
}
break;
case WM_RBUTTONDOWN:
CancelLoop();
return FALSE;
// just dispatch rest of the messages
default:
DispatchMessage(&msg);
break;
}
}
CancelLoop();
return FALSE;
}
} // Unnamed namespace
/////////////////////////////////////////////////////////////////////////////
// CFixedSizeControlBar
CFixedSizeControlBar::CFixedSizeControlBar()
{
}
CFixedSizeControlBar::CFixedSizeControlBar( char const * class_name, char const * caption, UINT id, DWORD style, DWORD style_ex, CSize const & size, CWnd* parent )
{
bool bret = initialize( class_name, caption, id, style, style_ex, size, parent );
assert ( bret );
}
bool CFixedSizeControlBar::initialize( char const * class_name, char const * caption, UINT id, DWORD style, DWORD style_ex, CSize const & size, CWnd* parent )
{
m_size = size;
style &= ~CBRS_SIZE_DYNAMIC;
style |= CBRS_SIZE_FIXED;
style_ex &= ~CBRS_EX_GRIPPER_EXPAND;
style_ex |= CBRS_EX_UNIDIRECTIONAL;
return SECControlBar::Create( class_name, caption, id, style, style_ex, CRect( 0, 0, 0, 0 ), parent ) != FALSE;
}
CFixedSizeControlBar::~CFixedSizeControlBar()
{
}
void CFixedSizeControlBar::SetSize(CSize size)
{
m_size = size;
}
BEGIN_MESSAGE_MAP(CFixedSizeControlBar, SECControlBar)
//{{AFX_MSG_MAP(CFixedSizeControlBar)
ON_WM_WINDOWPOSCHANGING()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
CSize CFixedSizeControlBar::CalcDynamicLayout( int nLength, DWORD dwMode )
{
CSize result = m_size;
if ( ( m_dwExStyle & CBRS_EX_GRIPPER ) != 0 )
{
result.cx += m_GripperInfo.m_nGripperOffSidePadding * 2;
result.cy += m_GripperInfo.m_nGripperOffSidePadding * 2;
if ( !IsFloating() )
{
if ( ( dwMode & LM_HORZ ) != 0 )
result.cx += m_GripperInfo.GetWidth() - m_GripperInfo.m_nGripperOffSidePadding;
else
result.cy += m_GripperInfo.GetHeight() - m_GripperInfo.m_nGripperOffSidePadding;
}
}
else if ( ( m_dwExStyle & CBRS_EX_BORDERSPACE ) != 0 )
{
result.cx += m_rcBorderSpace.left + m_rcBorderSpace.right;
result.cy += m_rcBorderSpace.top + m_rcBorderSpace.bottom;
}
if ( ( dwMode & LM_COMMIT ) != 0 && IsFloating() )
{
result.cx -= 2;
result.cy -= 2;
}
return result;
}
/////////////////////////////////////////////////////////////////////////////
void CFixedSizeControlBar::GetInsideRect( CRect & rectInside ) const
{
GetClientRect(rectInside);
BOOL bIsHorz=m_dwStyle & CBRS_ORIENT_HORZ;
// if using gripper, pad all remaining sides with
// extra border space as dictated by CBRS_EX_BORDERSPACE
if((m_dwExStyle & CBRS_EX_GRIPPER)) {
rectInside.left += m_GripperInfo.m_nGripperOffSidePadding;
rectInside.top += m_GripperInfo.m_nGripperOffSidePadding;
rectInside.right -= m_GripperInfo.m_nGripperOffSidePadding;
rectInside.bottom -= m_GripperInfo.m_nGripperOffSidePadding;
if ( !IsFloating() )
{
if ( bIsHorz )
rectInside.left += const_cast< CFixedSizeControlBar * >( this )->m_GripperInfo.GetWidth() - m_GripperInfo.m_nGripperOffSidePadding;
else
rectInside.top += const_cast< CFixedSizeControlBar * >( this )->m_GripperInfo.GetHeight() - m_GripperInfo.m_nGripperOffSidePadding;
}
}
// CBRS_EX_BORDERSPACE is only used if no gripper
else if (m_dwExStyle & CBRS_EX_BORDERSPACE) {
rectInside.left += m_rcBorderSpace.left;
rectInside.right -= m_rcBorderSpace.right;
rectInside.top += m_rcBorderSpace.top;
rectInside.bottom -= m_rcBorderSpace.bottom;
}
}
/////////////////////////////////////////////////////////////////////////////
void CFixedSizeControlBar::DrawBorders( CDC * pDC, CRect & rect )
{
ASSERT_VALID(this);
ASSERT_VALID(pDC);
if (!(m_dwStyle & CBRS_BORDER_ANY))
return;
if(m_dwExStyle & CBRS_EX_COOLBORDERS)
{
COLORREF clr = (m_dwStyle & CBRS_BORDER_3D) ? secData.clrBtnHilite
: secData.clrBtnShadow;
if(m_dwStyle & CBRS_BORDER_LEFT)
pDC->FillSolidRect(0, 0, CX_BORDER, rect.Height() - 1, clr);
if(m_dwStyle & CBRS_BORDER_TOP)
pDC->FillSolidRect(0, 0, rect.Width()-1 , CY_BORDER, clr);
if(m_dwStyle & CBRS_BORDER_RIGHT)
pDC->FillSolidRect(rect.right, 1, -CX_BORDER, rect.Height() - 2, secData.clrBtnShadow);
if(m_dwStyle & CBRS_BORDER_BOTTOM)
pDC->FillSolidRect(0, rect.bottom, rect.Width()-1, -CY_BORDER, secData.clrBtnShadow);
// if undockable toolbar at top of frame, apply special formatting to mesh
// properly with frame menu
if(!m_pDockContext) {
pDC->FillSolidRect(0,0,rect.Width(),1,secData.clrBtnShadow);
pDC->FillSolidRect(0,1,rect.Width(),1,secData.clrBtnHilite);
}
}
else
if(!rect.IsRectEmpty())
{
rect.right-=1;
rect.bottom-=1;
}
SECControlBar::DrawBorders(pDC,rect);
}
/////////////////////////////////////////////////////////////////////////////
SECDockContext * CFixedSizeControlBar::NewDockContext()
{
return new t_dock_context( this );
}
/////////////////////////////////////////////////////////////////////////////
// CFixedSizeControlBar message handlers
void CFixedSizeControlBar::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
// TODO: Add your message handler code here
DWORD dwStyle = m_dwStyle;
m_dwStyle &= ~(CBRS_BORDER_ANY);
SECControlBar::OnWindowPosChanging(lpwndpos);
m_dwStyle = dwStyle;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -