📄 dockbarex.cpp
字号:
// DockBarEx.cpp : implementation file
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <afxpriv.h>
#include "DockBarEx.h"
#define IDC_BUTTON_HIDE 1000
#define IDC_BUTTON_MINI 1001
////////////////////////////////////////////////////////////////////////////
// XButtonEx
XButtonEx::XButtonEx()
{
m_bLBtnDown = false;
m_bFlatLook = true;
}
XButtonEx::~XButtonEx()
{
}
IMPLEMENT_DYNAMIC(XButtonEx, CButton)
BEGIN_MESSAGE_MAP(XButtonEx, CButton)
//{{AFX_MSG_MAP(XButtonEx)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void XButtonEx::OnMouseMove(UINT nFlags, CPoint point)
{
SetTimer (1,10,NULL);
CButton::OnMouseMove(nFlags, point);
}
void XButtonEx::OnLButtonDown(UINT nFlags, CPoint point)
{
m_bLBtnDown = true;
CButton::OnLButtonDown(nFlags, point);
}
void XButtonEx::OnLButtonUp(UINT nFlags, CPoint point)
{
m_bLBtnDown = false;
CButton::OnLButtonUp(nFlags, point);
}
void XButtonEx::OnTimer(UINT nIDEvent)
{
CRect rcItem;
GetWindowRect(rcItem);
CPoint ptCursor;
GetCursorPos(&ptCursor);
static bool pPainted = false;
if( m_bLBtnDown )
{
KillTimer (1);
if( pPainted )
{
InvalidateRect(NULL);
pPainted = false;
}
return;
}
if( !rcItem.PtInRect(ptCursor) )
{
KillTimer (1);
if( pPainted )
{
InvalidateRect (NULL);
pPainted = false;
}
return;
}
// On mouse over, show raised button.
else if(m_bFlatLook)
{
// Get the device context for the client area.
CDC *pDC = GetDC();
if (pPainted == false)
{
// repaint client area.
GetClientRect(rcItem);
pDC->FillSolidRect(rcItem, ::GetSysColor(COLOR_BTNFACE));
// if an icon is associated with button, draw it.
if( GetIcon() )
{
SetIconRect();
DrawIconEx( pDC->GetSafeHdc(), m_rcIcon.left, m_rcIcon.top,
GetIcon(), m_rcIcon.Width(), m_rcIcon.Height(), NULL, (HBRUSH)NULL, DI_NORMAL );
}
// draw the button rect.
pDC->Draw3dRect(rcItem, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNSHADOW));
pPainted = true;
}
ReleaseDC (pDC);
}
CButton::OnTimer(nIDEvent);
}
void XButtonEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(lpDrawItemStruct != NULL);
CDC* pDC = GetDC();
m_nState = lpDrawItemStruct->itemState;
// copy the rect, and fill the background.
m_rcItem.CopyRect(&lpDrawItemStruct->rcItem);
pDC->FillSolidRect(m_rcItem, ::GetSysColor(COLOR_BTNFACE));
// define rect to be used for left button down.
SetIconRect();
if(m_bFlatLook)
{
// Draw button pressed.
if ((m_nState & ODS_SELECTED)) {
pDC->Draw3dRect (m_rcItem, ::GetSysColor(COLOR_BTNSHADOW),
::GetSysColor(COLOR_BTNHIGHLIGHT));
}
// Draw button flat.
else {
pDC->Draw3dRect (m_rcItem, ::GetSysColor(COLOR_BTNFACE),
::GetSysColor(COLOR_BTNFACE));
}
}
else
{
CRect rc(m_rcItem);
rc.DeflateRect(1,1);
// Draw button pressed.
if ((m_nState & ODS_SELECTED)) {
pDC->Draw3dRect (m_rcItem, ::GetSysColor(COLOR_3DDKSHADOW),
::GetSysColor(COLOR_BTNHIGHLIGHT));
pDC->Draw3dRect (rc, ::GetSysColor(COLOR_BTNSHADOW),
::GetSysColor(COLOR_BTNFACE));
}
// Draw button raised.
else {
pDC->Draw3dRect (m_rcItem, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_3DDKSHADOW));
pDC->Draw3dRect (rc, ::GetSysColor(COLOR_BTNFACE),
::GetSysColor(COLOR_BTNSHADOW));
}
}
// Save the item state, set background to transparent.
pDC->SetBkMode( TRANSPARENT );
// if an icon is associated with button, draw it.
if(GetIcon())
{
DrawIconEx (pDC->GetSafeHdc(), m_rcIcon.left, m_rcIcon.top,
GetIcon(), m_rcIcon.Width(), m_rcIcon.Height(), NULL, (HBRUSH)NULL, DI_NORMAL);
}
ReleaseDC (pDC);
}
void XButtonEx::SetIcon(HICON hIcon, CSize cSize)
{
CButton::SetIcon(hIcon);
m_cSize.cx = cSize.cx;
m_cSize.cy = cSize.cy;
}
void XButtonEx::SetIconRect()
{
CRect rcClient;
GetClientRect (&rcClient);
CRect rcWindow;
GetWindowRect (&rcWindow);
CPoint ptCursor;
GetCursorPos (&ptCursor);
CPoint ptCenter = rcClient.CenterPoint();
int x1 = (rcClient.Width() - ptCenter.x) / 2 - 1;
int x2 = x1 + rcClient.Width() - 1;
int y1 = (rcClient.Height() - ptCenter.y) / 2 - 1;
int y2 = y1 + rcClient.Height() - 1;
m_rcIcon.CopyRect (rcClient);
if( m_bLBtnDown ) {
if(rcWindow.PtInRect(ptCursor)) {
m_rcIcon.OffsetRect(1,1);
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CDockBarEx
CDockBarEx::CDockBarEx()
{
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;
}
CDockBarEx::~CDockBarEx()
{
}
IMPLEMENT_DYNAMIC(CDockBarEx, CControlBar)
BEGIN_MESSAGE_MAP(CDockBarEx, CControlBar)
//{{AFX_MSG_MAP(CDockBarEx)
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()
/////////////////////////////////////////////////////////////////////////////
// CDockBarEx message handlers
void CDockBarEx::OnUpdateCmdUI(CFrameWnd * pTarget, BOOL bDisableIfNoHndler)
{
UpdateDialogControls(pTarget, bDisableIfNoHndler);
}
BOOL CDockBarEx::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));
// 装载按钮图标
m_ImageList.Create(IDB_DOCKBAR, 13, 1, RGB(255, 255, 255));
// 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 CDockBarEx::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 CDockBarEx::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 CDockBarEx::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 CDockBarEx::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if ((nHitTest != HTSIZE) || m_bTracking)
return CControlBar::OnSetCursor(pWnd, nHitTest, message);
if (IsHorzDocked())
::SetCursor(::LoadCursor(NULL, IDC_SIZENS));
else
::SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
return TRUE;
}
BOOL CDockBarEx::IsHorzDocked() const
{
return (m_nDockBarID == AFX_IDW_DOCKBAR_TOP ||
m_nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);
}
BOOL CDockBarEx::IsVertDocked() const
{
return (m_nDockBarID == AFX_IDW_DOCKBAR_LEFT ||
m_nDockBarID == AFX_IDW_DOCKBAR_RIGHT);
}
void CDockBarEx::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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -