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

📄 dockpagebar.cpp

📁 路由信息查看程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////
//
// CDockPageBar            Version 1.0
//
// Created: Mar 16, 2004
//
/////////////////////////////////////////////////////////////////////////
// Copyright (C) 2004 by Cuick. All rights reserved.
//
// This code is free for personal and commercial use, providing this 
// notice remains intact in the source files and all eventual changes are
// clearly marked with comments.
//
// Send bug reports, bug fixes, enhancements, requests, flames, etc. to
// Cuick@163.net
//
// Hint: These classes are intended to be used as base classes. Do not
// simply add your code to these file - instead create a new class
// derived from CDockPageBar classes and put there what you need. See 
// CTestBar classes in the demo projects for examples.
// Modify this file only to fix bugs, and don't forget to send me a copy.
/////////////////////////////////////////////////////////////////////////
// Acknowledgements:
//	o	感谢Cristi Posea的CSizingControlBar
//	o	借鉴了王骏的《轻松实现类VC界面》中的部分代码,在这里表示感谢。
//	o	开发过程中遇到的问题得到了VC知识库论坛中很多人的帮助,这里一并感谢。
//


// DockPageBar.cpp : implementation file
//
#include "stdafx.h"
#include "DockPageBar.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////
// delete the line between menu bar and tool bar

// From <afximpl.h>
struct AUX_DATA
{
	int _unused1, _unused2;
	int _unused3, _unused4;
	int cxBorder2, cyBorder2;
};

extern __declspec(dllimport) AUX_DATA afxData;

class INIT_afxData
{
public:
    INIT_afxData ()
    {
        afxData.cxBorder2 = afxData.cyBorder2 = 0;
    }
} g_afxData2;

/////////////////////////////////////////////////////////////////////////
// CMyButton
#define HTSTUD             22

CMyButton::CMyButton()
{
    bRaised = FALSE;
    bPushed = FALSE;
}

void CMyButton::Paint(CDC* pDC, BOOL isActive)
{
    CRect rc = GetRect();

    if (bPushed)
        pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNSHADOW),
            ::GetSysColor(COLOR_BTNHIGHLIGHT));
    else
        if (bRaised)
            pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNHIGHLIGHT),
                ::GetSysColor(COLOR_BTNSHADOW));
}

// draw close button
void CCloseButton::Paint(CDC* pDC, BOOL isActive)
{
	CMyButton::Paint(pDC, isActive);

	COLORREF clrOldTextColor = pDC->GetTextColor();

	if(TRUE == isActive)
		pDC->SetTextColor(RGB(255,255,255));
	else
		pDC->SetTextColor(RGB(128,128,128));

    int nPrevBkMode = pDC->SetBkMode(TRANSPARENT);
    CFont font;
    int ppi = pDC->GetDeviceCaps(LOGPIXELSX);
    int pointsize = MulDiv(75, 96, ppi); // 6 points at 96 ppi
    font.CreatePointFont(pointsize, _T("Marlett"));
    CFont* oldfont = pDC->SelectObject(&font);

    pDC->TextOut(ptOrg.x + 2, ptOrg.y + 2, CString(_T("r"))); // x-like

    pDC->SelectObject(oldfont);
    pDC->SetBkMode(nPrevBkMode);
    pDC->SetTextColor(clrOldTextColor);
}

CStudButton::CStudButton()
{
	bFloat = FALSE;
}

// draw stud
void CStudButton::Paint(CDC* pDC, BOOL isActive)
{
	CMyButton::Paint(pDC, isActive);

	HPEN oldPen;
	CPen pen;
	if(TRUE == isActive)
		pen.CreatePen (PS_SOLID, 1, RGB(255,255,255));
	else
		pen.CreatePen (PS_SOLID, 1, RGB(0,0,0));

	oldPen = (HPEN)pDC->SelectObject (pen);

	if(FALSE == bFloat)
	{
		pDC->MoveTo (ptOrg.x + 4, ptOrg.y + 8);
		pDC->LineTo (ptOrg.x + 4, ptOrg.y + 3);
		pDC->LineTo (ptOrg.x + 8, ptOrg.y + 3);
		pDC->LineTo (ptOrg.x + 8, ptOrg.y + 8);
		
		pDC->MoveTo (ptOrg.x + 7, ptOrg.y + 3);
		pDC->LineTo (ptOrg.x + 7, ptOrg.y + 8);
		
		pDC->MoveTo (ptOrg.x + 2, ptOrg.y + 8);
		pDC->LineTo (ptOrg.x + 11, ptOrg.y + 8);
		
		pDC->MoveTo (ptOrg.x + 6, ptOrg.y + 8);
		pDC->LineTo (ptOrg.x + 6, ptOrg.y + 12);
	}
	else
	{
		pDC->MoveTo (ptOrg.x + 5, ptOrg.y + 4);
		pDC->LineTo (ptOrg.x + 10, ptOrg.y + 4);
		pDC->LineTo (ptOrg.x + 10, ptOrg.y + 8);
		pDC->LineTo (ptOrg.x + 5, ptOrg.y + 8);
		
		pDC->MoveTo (ptOrg.x + 5, ptOrg.y + 7);
		pDC->LineTo (ptOrg.x + 10, ptOrg.y + 7);
		
		pDC->MoveTo (ptOrg.x + 5, ptOrg.y + 2);
		pDC->LineTo (ptOrg.x + 5, ptOrg.y + 11);
		
		pDC->MoveTo (ptOrg.x + 1, ptOrg.y + 6);
		pDC->LineTo (ptOrg.x + 5, ptOrg.y + 6);
	}

	pDC->SelectObject(oldPen);
}

/////////////////////////////////////////////////////////////////////////////
// CPageItem 
#define	ITEMBUTTON_HEIGHT		27

void CPageItem::Draw(CDC *pDC, BOOL bActive)
{
	CRect rect = m_rect;
	COLORREF crOldText;

	rect.top += 2;
	if(bActive)
	{
		rect.bottom -= 2;
		
		CBrush brush(GetSysColor(COLOR_3DFACE));
		pDC->FillRect(rect,&brush);

		CPen pen(PS_SOLID,1,GetSysColor(COLOR_3DDKSHADOW));
		HPEN oldPen = (HPEN)pDC->SelectObject (&pen);
		pDC->MoveTo (rect.left , rect.bottom );
		pDC->LineTo (rect.right+1 ,rect.bottom );

		pDC->MoveTo (rect.right, rect.top);
		pDC->LineTo (rect.right ,rect.bottom+1 );

		pDC->SelectObject (oldPen);

		crOldText = pDC->SetTextColor(RGB(0,0,0));
		m_pWnd->ShowWindow(SW_SHOW);
	}
	else
	{
		CPen pen(PS_SOLID, 1, RGB(128,128,128));
		HPEN oldPen = (HPEN)pDC->SelectObject (&pen);

		pDC->MoveTo (rect.right+1, rect.top + 3);
		pDC->LineTo (rect.right+1, rect.bottom -4);

		pDC->SelectObject (oldPen);

		crOldText = pDC->SetTextColor(RGB(128,128,128));
		m_pWnd->ShowWindow(SW_HIDE);
	}

	rect.left += 5;
	rect.right -= 2;
	rect.top +=1;
	
	// draw Icon
	if(rect.Width() > 16 && m_hIcon != NULL)
	{
		::DrawIconEx(pDC->m_hDC,rect.left,rect.top + 3,m_hIcon,16,16,0,NULL,DI_NORMAL);
		rect.left += 22;
	}
	if (!m_sText.IsEmpty())
	{
		// draw text
		rect.top += 2;
		CString sText = m_sText;
		int l = sText.GetLength();
		int i;

		for(i=0;i<10 && pDC->GetTextExtent(sText).cx > rect.Width();i++,l-=2)
			sText = sText.Left(l-2);
		if(i > 0)
		{
			sText = sText.Left(l-2);
			sText += "...";
		}
		int nPrevBkMode = pDC->SetBkMode(TRANSPARENT);
		
		pDC->DrawText(sText, &rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
		pDC->SetBkMode(nPrevBkMode);
	}

	pDC->SetTextColor (crOldText);
}

/////////////////////////////////////////////////////////////////////////////
// CDockPageBar

IMPLEMENT_DYNAMIC(CDockPageBar, baseCDockPageBar);

CDockPageBar::CDockPageBar()
{
	m_szMinHorz = CSize(50, 50);
    m_szMinVert = CSize(60, 60);
    m_szMinFloat = CSize(150, 150);

	m_cyGripper = 20;
	m_isActive = FALSE;
	m_Title = "";
	m_nActivePage = -1;
}

CDockPageBar::~CDockPageBar()
{
	POSITION pos;
	CPageItem* pItem;
	for(pos=m_PageList.GetHeadPosition();pos!=NULL;)
	{
		pItem=(CPageItem*)m_PageList.GetNext(pos);
		if(pItem)
		{
			delete pItem;
			pItem=NULL;
		}
	}
	m_PageList.RemoveAll();
}


BEGIN_MESSAGE_MAP(CDockPageBar, baseCDockPageBar)
	//{{AFX_MSG_MAP(CDockPageBar)
	ON_WM_CREATE()
	ON_WM_NCHITTEST()
	ON_WM_NCLBUTTONUP()
	ON_WM_SIZE()
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CDockPageBar message handlers

int CDockPageBar::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (baseCDockPageBar::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	if (m_font.CreatePointFont(85, "Tahoma"))
			SetFont(&m_font);

	m_isActive = FALSE;

	return 0;
}

void CDockPageBar::OnUpdateCmdUI(CFrameWnd *pTarget, BOOL bDisableIfNoHndler)
{
	if (!HasGripper())
        return;

    BOOL bNeedPaint = FALSE;

    CWnd* pFocus = GetFocus();
    BOOL bActiveOld = m_isActive;

    m_isActive = (pFocus->GetSafeHwnd() && IsChild(pFocus));
	m_isActive = m_isActive || (pFocus == this);
    if (m_isActive != bActiveOld)
        bNeedPaint = TRUE;


    CPoint pt;
    ::GetCursorPos(&pt);

	///////////////////////////////////////////////////////////
	// hit close
    BOOL bHit = (OnNcHitTest(pt) == HTCLOSE);
    BOOL bLButtonDown = (::GetKeyState(VK_LBUTTON) < 0);

    BOOL bWasPushed = m_biHide.bPushed;
    m_biHide.bPushed = bHit && bLButtonDown;

    BOOL bWasRaised = m_biHide.bRaised;
    m_biHide.bRaised = bHit && !bLButtonDown;

    bNeedPaint |= (m_biHide.bPushed ^ bWasPushed) ||
                  (m_biHide.bRaised ^ bWasRaised);

	////////////////////////////////////////////////////////////
	// hit stud
	bHit = (OnNcHitTest(pt) == HTSTUD);
	bWasPushed = m_stud.bPushed;
    m_stud.bPushed = bHit && bLButtonDown;

    bWasRaised = m_stud.bRaised;
    m_stud.bRaised = bHit && !bLButtonDown;

	bNeedPaint |= (m_stud.bPushed ^ bWasPushed) ||
                  (m_stud.bRaised ^ bWasRaised);

    if (bNeedPaint)
        SendMessage(WM_NCPAINT);

}

// draw title bar
void CDockPageBar::NcPaintGripper(CDC *pDC, CRect rcClient)
{
    if (!HasGripper())
        return;

    CRect gripper = rcClient;
    CRect rcbtn = m_biHide.GetRect();


    gripper.DeflateRect(1, 1);
	gripper.top -= m_cyGripper;
	gripper.bottom = gripper.top + 16;

	HFONT oldFont = (HFONT)pDC->SelectObject (m_font);

	int nPrevBkMode = pDC->SetBkMode(TRANSPARENT);
	COLORREF crOldText;

	if(TRUE == m_isActive)			// active state
	{
		CBrush brush(RGB(10,36,106));
		pDC->FillRect(&gripper, &brush);

		crOldText = pDC->SetTextColor(RGB(255,255,255));
	}
	else
	{
		CPen pen(PS_SOLID, 1, RGB(128,128,128));
		
		HPEN poldPen = (HPEN)pDC->SelectObject (&pen);
		
		pDC->MoveTo (gripper.TopLeft());
		pDC->LineTo (gripper.right ,gripper.top );
		pDC->LineTo (gripper.BottomRight() );
		pDC->LineTo (gripper.left ,gripper.bottom );
		pDC->LineTo (gripper.TopLeft ());
		pDC->SelectObject (poldPen);

		crOldText = pDC->SetTextColor(RGB(0,0,0));
	}
	
	gripper.left += 4;
	gripper.top += 2;

	// draw caption
	if (!m_Title.IsEmpty())
	{
		CString sText = m_Title;
		int l = sText.GetLength();
		int i;

		for(i=0;i<10 && pDC->GetTextExtent(sText).cx > (gripper.Width() - 30);i++,l-=2)
			sText = sText.Left(l-2);
		if(i > 0)
		{
			sText = sText.Left(l-2);
			sText += "...";
		}
		pDC->TextOut (gripper.left, gripper.top, sText);
	}

	pDC->SetTextColor (crOldText);
	pDC->SetBkMode(nPrevBkMode);
	pDC->SelectObject(oldFont);

	CPoint ptOrgBtn;
    ptOrgBtn = CPoint(gripper.right - 15, gripper.top);
	m_biHide.Move(ptOrgBtn);
    m_biHide.Paint(pDC, m_isActive);

	ptOrgBtn.x -= 17;
	m_stud.Move (ptOrgBtn);
	m_stud.Paint(pDC, m_isActive);
}

void CDockPageBar::NcCalcClient(LPRECT pRc, UINT nDockBarID)
{
	CRect rcBar(pRc); // save the bar rect

    // subtract edges
    baseCDockPageBar::NcCalcClient(pRc, nDockBarID);

    if (!HasGripper())
        return;

    CRect rc(pRc); // the client rect as calculated by the base class

    BOOL bHorz = (nDockBarID == AFX_IDW_DOCKBAR_TOP) ||
                 (nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);

    if (bHorz)
        rc.DeflateRect(0, m_cyGripper, 1, 0);
    else
        rc.DeflateRect(0, m_cyGripper, 0, 0);

    *pRc = rc;
}

void CDockPageBar::OnNcLButtonUp(UINT nHitTest, CPoint point) 
{
	if (nHitTest == HTCLOSE)
        m_pDockSite->ShowControlBar(this, FALSE, FALSE); // hide
	if (nHitTest == HTSTUD)
		m_stud.bFloat = ~m_stud.bFloat;

	baseCDockPageBar::OnNcLButtonUp(nHitTest, point);
}

BOOL CDockPageBar::HasGripper() const
{
	if (IsFloating())
        return FALSE;
    return TRUE;
}

UINT CDockPageBar::OnNcHitTest(CPoint point) 
{
    CRect rcBar;
    GetWindowRect(rcBar);

    UINT nRet = baseCDockPageBar::OnNcHitTest(point);
    if (nRet != HTCLIENT)
        return nRet;

    CRect rc = m_biHide.GetRect();
    rc.OffsetRect(rcBar.TopLeft());
    if (rc.PtInRect(point))
        return HTCLOSE;

	rc = m_stud.GetRect();
    rc.OffsetRect(rcBar.TopLeft());
    if (rc.PtInRect(point))
        return HTSTUD;

    return HTCLIENT;
}


/////////////////////////////////////////////////////////////////////////////
// about PageItem

void CDockPageBar::GetClientRect(LPRECT lpRect, BOOL isMulti)
{
	CWnd::GetClientRect(lpRect);
	
	if(TRUE == isMulti)
		lpRect->bottom -= ITEMBUTTON_HEIGHT;
}

CPageItem* CDockPageBar::GetPageItem(int nIndex)
{
	CPageItem *pItem = NULL;
	POSITION pos = m_PageList.FindIndex(nIndex);
	if(pos)
		pItem = (CPageItem*)m_PageList.GetAt(pos);

	return pItem;
}

void CDockPageBar::SetActivePage(int nIndex)
{
	if(nIndex == m_nActivePage)
		return;
	CPageItem *pItem;

	pItem = (CPageItem*)GetPageItem(nIndex);

	if(!pItem) return;
	m_nActivePage = nIndex;

	m_Title = pItem->m_sText;

	SetWindowText(m_Title);
	SendMessage(WM_NCPAINT);
	Invalidate();
}

void CDockPageBar::OnSize(UINT nType, int cx, int cy) 
{
	UpdateSize();
	Invalidate(FALSE);
}

void CDockPageBar::UpdateSize()
{
	UINT PageCount = m_PageList.GetCount();
	if(PageCount < 1) return;

	CPageItem	*pItem;
	CRect		rect,ClientRect,ItemRect;
	
	if(PageCount == 1) 
	{
		GetClientRect(ClientRect, FALSE);

		pItem = (CPageItem*)GetPageItem(0);;
		if(pItem->m_pWnd)
		{
				pItem->m_pWnd->MoveWindow(ClientRect);
				pItem->m_pWnd->ShowWindow(SW_SHOW);
		}
		return;
	}

	POSITION	pos;

	GetClientRect(rect, FALSE);
	rect.left += 6;
	rect.right -= 6;
	rect.bottom -= 1;
	rect.top = rect.bottom - ITEMBUTTON_HEIGHT + 2;


	GetClientRect(ClientRect, TRUE);

	ItemRect = rect;
	int AreaWidth = 0,ItemWidth,ItemIndex=0;

	for(pos=m_PageList.GetHeadPosition();pos!=NULL;ItemIndex++)
	{
		pItem=(CPageItem*)m_PageList.GetNext(pos);
		if(pItem)
		{
			ItemWidth = pItem->m_TabWidth;
			AreaWidth += ItemWidth;
			ItemRect.right = ItemRect.left+ItemWidth-1;
			pItem->m_rect = ItemRect;
			ItemRect.left = ItemRect.right + 1;
			if(pItem->m_pWnd)
				pItem->m_pWnd->MoveWindow(ClientRect);
		}
	}

	if(AreaWidth > rect.Width())
	{
		ItemRect = rect;
		int AreaWidth,MaxWidth = rect.Width()/PageCount;
		for(pos=m_PageList.GetHeadPosition();pos!=NULL;)
		{
			pItem=(CPageItem*)m_PageList.GetNext(pos);
			if(pItem)
			{
				AreaWidth = pItem->m_TabWidth;
				ItemWidth = (MaxWidth < AreaWidth)?MaxWidth:AreaWidth;
				ItemRect.right = ItemRect.left+ItemWidth;
				pItem->m_rect = ItemRect;
				ItemRect.left = ItemRect.right + 1;
			}
		}
	}
}

BOOL CDockPageBar::AddPage(CWnd *pWnd, LPCTSTR sText, UINT IconID)
{
	ASSERT(IsWindow(pWnd->m_hWnd));
	CPageItem *pItem;
	pItem = new CPageItem();
	pItem->m_pWnd = pWnd;
	pItem->m_pWnd->SetParent (this);
	pItem->m_sText = sText;
	CClientDC dc(this);
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -