📄 cmycontrolbar.cpp
字号:
// CMYControlBar.cpp : implementation file
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CMYControlBar.h"
#include <afxpriv.h> // for CDockContext
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMyControlBar
#define IDC_BUTTON_HIDE 1000
#define IDC_BUTTON_MINI 1001
CMyControlBar::CMyControlBar()
{
m_sizeMin = CSize(32, 32);
m_sizeHorz = CSize(200, 200);
m_sizeVert = CSize(200, 200);
m_sizeFloat = CSize(200, 200);
m_bTracking = FALSE;
m_bInRecalcNC = FALSE;
m_cxEdge = 5;
m_menuID = 0;
m_bGripper = TRUE;
m_bButtons = TRUE;
}
CMyControlBar::~CMyControlBar()
{
}
IMPLEMENT_DYNAMIC(CMyControlBar, CControlBar)
BEGIN_MESSAGE_MAP(CMyControlBar, CControlBar)
//{{AFX_MSG_MAP(CMyControlBar)
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_SETCURSOR()
ON_WM_WINDOWPOSCHANGED()
ON_WM_NCPAINT()
ON_WM_NCLBUTTONDOWN()
ON_WM_NCHITTEST()
ON_WM_NCCALCSIZE()
ON_WM_LBUTTONDOWN()
ON_WM_CAPTURECHANGED()
ON_WM_LBUTTONDBLCLK()
ON_WM_PAINT()
ON_WM_CREATE()
ON_COMMAND(IDC_BUTTON_HIDE, OnButtonClose)
ON_UPDATE_COMMAND_UI(IDC_BUTTON_HIDE, OnUpdateButtonClose)
ON_COMMAND(IDC_BUTTON_MINI, OnButtonMinimize)
ON_UPDATE_COMMAND_UI(IDC_BUTTON_MINI, OnUpdateButtonMinimize)
ON_WM_CONTEXTMENU()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyControlBar message handlers
void CMyControlBar::OnUpdateCmdUI(CFrameWnd * pTarget, BOOL bDisableIfNoHndler)
{
UpdateDialogControls(pTarget, bDisableIfNoHndler);
}
BOOL CMyControlBar::Create(CWnd * pParentWnd, UINT nID, LPCTSTR lpszWindowName, CSize sizeDefault, DWORD dwStyle)
{
ASSERT_VALID(pParentWnd); // must have a parent
ASSERT (((dwStyle & CBRS_SIZE_FIXED) != CBRS_SIZE_FIXED) &&
((dwStyle & CBRS_SIZE_DYNAMIC) != CBRS_SIZE_DYNAMIC));
// save the style
SetBarStyle(dwStyle & CBRS_ALL);
CString wndclass = ::AfxRegisterWndClass(CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW),
::GetSysColorBrush(COLOR_BTNFACE), 0);
m_sizeHorz = m_sizeVert = m_sizeFloat = sizeDefault;
dwStyle &= ~CBRS_ALL;
dwStyle &= WS_VISIBLE | WS_CHILD;
return CWnd::Create(wndclass, lpszWindowName, dwStyle,
CRect(0,0,0,0), pParentWnd, nID);
}
CSize CMyControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
CRect rc;
m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_TOP)->GetWindowRect(rc);
int nHorzDockBarWidth = bStretch ? 32767 : rc.Width() + 4;
m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_LEFT)->GetWindowRect(rc);
int nVertDockBarHeight = bStretch ? 32767 : rc.Height() + 4;
if (bHorz)
return CSize(nHorzDockBarWidth, m_sizeHorz.cy);
else
return CSize(m_sizeVert.cx, nVertDockBarHeight);
}
CSize CMyControlBar::CalcDynamicLayout(int nLength, DWORD dwMode)
{
if (dwMode & (LM_HORZDOCK | LM_VERTDOCK))
{
if (nLength == -1)
GetDockingFrame()->DelayRecalcLayout();
return CControlBar::CalcDynamicLayout(nLength,dwMode);
}
if (dwMode & LM_MRUWIDTH)
return m_sizeFloat;
if (dwMode & LM_COMMIT)
{
m_sizeFloat.cx = nLength;
return m_sizeFloat;
}
if (dwMode & LM_LENGTHY)
return CSize(m_sizeFloat.cx,
m_sizeFloat.cy = max(m_sizeMin.cy, nLength));
else
return CSize(max(m_sizeMin.cx, nLength), m_sizeFloat.cy);
}
void CMyControlBar::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos)
{
CControlBar::OnWindowPosChanged(lpwndpos);
// Find on which side are we docked
m_nDockBarID = GetParent()->GetDlgCtrlID();
if (m_bInRecalcNC == FALSE)
{
m_bInRecalcNC = TRUE;
// Force recalc the non-client area
SetWindowPos(NULL, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE |
SWP_NOACTIVATE | SWP_NOZORDER |
SWP_FRAMECHANGED);
m_bInRecalcNC = FALSE;
}
if (m_bButtons)
{
ASSERT(m_ImageList);
if (IsFloating()) {
m_btnClose.ShowWindow(SW_HIDE);
m_btnMinim.ShowWindow(SW_HIDE);
return;
}
else {
m_btnClose.ShowWindow(SW_SHOW);
m_btnMinim.ShowWindow(SW_SHOW);
}
CRect rcClose(GetButtonRect());
CRect rcMinim(GetButtonRect());
if (IsHorzDocked()) {
rcMinim.OffsetRect(0,14);
m_btnMinim.SetIcon(m_ImageList->ExtractIcon(2),CSize(13,13));
}
else {
rcClose.OffsetRect(14,0);
m_btnMinim.SetIcon(m_ImageList->ExtractIcon(1),CSize(13,13));
}
m_btnClose.MoveWindow(rcClose);
m_btnMinim.MoveWindow(rcMinim);
}
Invalidate();
}
BOOL CMyControlBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if ((nHitTest != HTSIZE) || m_bTracking)
return CControlBar::OnSetCursor(pWnd, nHitTest, message);
#if defined(MFCXLIB_STATIC)
HINSTANCE hInst = AfxFindResourceHandle(
MAKEINTRESOURCE(AFX_IDC_VSPLITBAR), RT_GROUP_CURSOR);
if (IsHorzDocked())
::SetCursor(::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_VSPLITBAR)));
else
::SetCursor(::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_HSPLITBAR)));
#else
if (IsHorzDocked())
::SetCursor(::LoadCursor(NULL, IDC_SIZENS));
else
::SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
#endif
return TRUE;
}
BOOL CMyControlBar::IsHorzDocked() const
{
return (m_nDockBarID == AFX_IDW_DOCKBAR_TOP ||
m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);
}
BOOL CMyControlBar::IsVertDocked() const
{
return (m_nDockBarID == AFX_IDW_DOCKBAR_LEFT ||
m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT);
}
void CMyControlBar::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
{
// Compute the rectangle of the mobile edge
GetWindowRect(m_rectBorder);
m_rectBorder.OffsetRect(-m_rectBorder.left, -m_rectBorder.top);
m_rectBorder.DeflateRect(1,1);
CRect rcWnd = lpncsp->rgrc[0];
DWORD dwBorderStyle = m_dwStyle | CBRS_BORDER_ANY;
switch (m_nDockBarID)
{
case AFX_IDW_DOCKBAR_TOP:
{
dwBorderStyle &= ~CBRS_BORDER_BOTTOM;
rcWnd.DeflateRect(2, 2, 2, m_cxEdge + 2);
m_rectBorder.top = m_rectBorder.bottom - m_cxEdge;
break;
}
case AFX_IDW_DOCKBAR_BOTTOM:
{
dwBorderStyle &= ~CBRS_BORDER_TOP;
rcWnd.DeflateRect(2, m_cxEdge + 2, 2, 2);
m_rectBorder.bottom = m_rectBorder.top + m_cxEdge;
lpncsp->rgrc[0].left += 10;
break;
}
case AFX_IDW_DOCKBAR_LEFT:
{
dwBorderStyle &= ~CBRS_BORDER_RIGHT;
rcWnd.DeflateRect(2, 2, m_cxEdge + 2, 6);
m_rectBorder.left = m_rectBorder.right - m_cxEdge;
break;
}
case AFX_IDW_DOCKBAR_RIGHT:
{
dwBorderStyle &= ~CBRS_BORDER_LEFT;
rcWnd.DeflateRect(m_cxEdge + 2, 2, 2, 6);
m_rectBorder.right = m_rectBorder.left + m_cxEdge;
break;
}
default:
{
m_rectBorder.SetRectEmpty();
break;
}
}
lpncsp->rgrc[0] = rcWnd;
SetBarStyle(dwBorderStyle);
}
void CMyControlBar::OnPaint()
{
CPaintDC dc(this); // device context for painting
DrawGripper(&dc);
}
void CMyControlBar::OnNcPaint()
{
// get window DC that is clipped to the non-client area
CWindowDC dc(this);
CRect rectWindow;
GetWindowRect(rectWindow);
ScreenToClient(rectWindow);
CRect rectClient;
GetClientRect(rectClient);
rectClient.OffsetRect(-rectWindow.left, -rectWindow.top);
dc.ExcludeClipRect(rectClient);
// draw borders in non-client area
rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);
DrawBorders(&dc, rectWindow);
// erase parts not drawn
dc.IntersectClipRect(rectWindow);
// erase NC background the hard way
dc.FillRect(rectWindow, &CBrush(::GetSysColor(COLOR_BTNFACE)));
// paint the mobile edge
dc.Draw3dRect(m_rectBorder, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNSHADOW));
ReleaseDC(&dc);
}
UINT CMyControlBar::OnNcHitTest(CPoint point)
{
if (IsFloating())
return CControlBar::OnNcHitTest(point);
CRect rc;
GetWindowRect(rc);
point.Offset(-rc.left, -rc.top);
if (m_rectBorder.PtInRect(point))
return HTSIZE;
else
return HTCLIENT;
}
BOOL CMyControlBar::IsFloating()
{
return (!IsHorzDocked() && !IsVertDocked());
}
void CMyControlBar::StartTracking()
{
SetCapture();
// make sure no updates are pending
RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
m_pDockSite->LockWindowUpdate();
m_ptOld = m_rectBorder.CenterPoint();
m_bTracking = TRUE;
m_rectTracker = m_rectBorder;
if (!IsHorzDocked()) m_rectTracker.bottom -= 4;
OnInvertTracker(m_rectTracker);
}
void CMyControlBar::StopTracking(BOOL bAccept)
{
OnInvertTracker(m_rectTracker);
m_pDockSite->UnlockWindowUpdate();
m_bTracking = FALSE;
ReleaseCapture();
if (!bAccept)
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -