⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dockbarex.cpp

📁 对c++中的各种ui对象进行封装
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -