📄 dockpagebar.cpp
字号:
/////////////////////////////////////////////////////////////////////////
//
// CDockPageBar Version 1.2
//
// 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 感谢hengai帮助修改了部分内存泄漏问题
// 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
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()
{
}
// 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;
m_stud.bFloat = FALSE;
}
CDockPageBar::~CDockPageBar()
{
for(POSITION pos = m_PageList.GetHeadPosition(); pos;)
{
CPageItem* pItem=(CPageItem*)m_PageList.GetNext(pos);
CWnd *pWnd = pItem->m_pWnd;
ASSERT(pWnd);
//hengai 因为在这个例子中,加入了 Edit, TREE 之类的,并且实在 MainFrm 中 CEdit m_wndEdit 声明的,会自动
//消除,所以在这里判断一下。如果使用 CEdit *m_wndEdit,然后在 CMainFrame::OnCreate 使用 m_wndEdit = new CEdit
//的,则必须在 MainFrm 析构函数中自己删除,因为加入了 IsKindOf 判断,并不会在这里析构
if(pWnd->IsKindOf(RUNTIME_CLASS(CDialog)))
{
delete pWnd; pWnd = NULL;
}
delete pItem; pItem=NULL;
}
m_PageList.RemoveAll();
for(pos = m_pDPBContext.GetHeadPosition(); pos;)
{
CDockPageBarContext* pDPBContext = (CDockPageBarContext*)m_pDPBContext.GetNext(pos);
if(pDPBContext)
{
pDPBContext->FreeAll();
}
}
m_pDPBContext.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()
ON_WM_DESTROY()
//}}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::OnDestroy()
{
}
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -