📄 categorybar.cpp
字号:
// CategoryBar.cpp : implementation file
//
#include "stdafx.h"
#include "StockRefer.h"
#include "CategoryBar.h"
#include "GroupEdit.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCategoryBar
IMPLEMENT_DYNCREATE(CCategoryBar, CWnd)
CCategoryBar::CCategoryBar()
{
crBackGroundColor = ::GetSysColor(COLOR_3DSHADOW);//RGB(0,128,128);//
crBackGroundColor1 = ::GetSysColor(COLOR_3DSHADOW);
crTextColor = ::GetSysColor(COLOR_WINDOW);
cr3dFace = ::GetSysColor(COLOR_3DFACE);
crLightBorder = ::GetSysColor(COLOR_3DLIGHT);
crHilightBorder = ::GetSysColor(COLOR_3DHILIGHT);
crShadowBorder = ::GetSysColor(COLOR_3DSHADOW);
crDkShadowBorder = ::GetSysColor(COLOR_3DDKSHADOW);
pBlackPen = new CPen(PS_SOLID, 1, RGB(0,0,0));
iFolderHeight = 22;
dwFlags = fDragItems|fEditGroups|fEditItems|fRemoveGroups|fRemoveItems|fAddGroups|fAnimation|fSelHighlight;
iSelFolder = 0;
iLastFolderHighlighted = -1;
iLastSelectedFolder = -1;
pLargeImageList = NULL;
pSmallImageList = NULL;
iFirstItem = 0;
xSmallIconLabelOffset = 4;
yLargeIconLabelOffset = 3;
ySmallIconSpacing = 10;
yLargeIconSpacing = 8;
xLeftMargin = 5;
yTopMargin = 5;
bUpArrow = bDownArrow = false;
rcUpArrow = rcDownArrow = CRect(0,0,0,0);
bUpPressed = bDownPressed = false;
bLooping = false;
iLastItemHighlighted = -1;
bPressedHighlight = false;
iLastDragItemDraw = -1;
lAnimationTickCount = 10;
iLastSel = -1;
iSelAnimCount = 0;
iSelAnimTiming = 0;
}
CCategoryBar::~CCategoryBar()
{
for (int t = 0; t < arFolder.GetSize(); t++)
{
if (arFolder.GetAt(t)) delete (CBarFolder*) arFolder.GetAt(t);
}
arFolder.RemoveAll();
delete pBlackPen;
}
BEGIN_MESSAGE_MAP(CCategoryBar, CWnd)
//{{AFX_MSG_MAP(CCategoryBar)
ON_WM_TIMER()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_SETCURSOR()
ON_WM_SIZE()
ON_WM_RBUTTONDOWN()
ON_WM_SYSCOLORCHANGE()
//}}AFX_MSG_MAP
ON_COMMAND(ID_CATEGORY_LARGEICON, OnCategoryLargeicon)
ON_UPDATE_COMMAND_UI(ID_CATEGORY_LARGEICON, OnUpdateCategoryLargeicon)
ON_COMMAND(ID_CATEGORY_SMALLICON, OnCategorySmallicon)
ON_UPDATE_COMMAND_UI(ID_CATEGORY_SMALLICON, OnUpdateCategorySmallicon)
ON_COMMAND(ID_CATEGORY_HIDE, OnCategoryHide)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCategoryBar message handlers
void CCategoryBar::SetFolderText( const int index, LPCTSTR text )
{
ASSERT(index >= 0 && index < GetFolderCount());
CBarFolder* pbf = (CBarFolder *) arFolder.GetAt(index);
if( pbf->cName )
{
delete [] pbf->cName;
pbf->cName = NULL;
}
pbf->cName = new TCHAR[ _tcslen( text ) + 1 ];
_tcscpy( pbf->cName, text );
}
void CCategoryBar::SetItemText( const int index, LPCTSTR text )
{
ASSERT(iSelFolder >= 0 && iSelFolder < GetFolderCount());
CBarFolder* pbf = (CBarFolder*) arFolder.GetAt(iSelFolder);
CBarItem* pi = (CBarItem*) pbf->arItems.GetAt(index);
if (pi->cItem)
{
delete [] pi->cItem;
pi->cItem = NULL;
}
pi->cItem = new TCHAR[ _tcslen( text ) + 1 ];
_tcscpy( pi->cItem, text );
}
BOOL CCategoryBar::Create(DWORD dwStyle, const RECT & rect, CWnd * pParentWnd, UINT nID, const DWORD dwFlag)
{
dwFlags = dwFlag;
return CWnd::CreateEx(WS_EX_STATICEDGE, NULL, NULL, dwStyle|WS_CHILD, rect, pParentWnd, nID);
//GFXOUTBARCTRL_CLASSNAME
}
bool CCategoryBar::IsSmallIconView() const
{
return dwFlags&fSmallIcon;
}
void CCategoryBar::SetSmallIconView(const bool bSet)
{
iFirstItem = 0;
if (bSet)
{
if (!IsSmallIconView())
{
dwFlags |= fSmallIcon;
CRect rc;
GetInsideRect(rc);
InvalidateRect(rc, false);
}
}
else
{
if (IsSmallIconView())
{
dwFlags &= ~fSmallIcon;
CRect rc;
GetInsideRect(rc);
InvalidateRect(rc, false);
}
}
}
DWORD CCategoryBar::GetFlag() const
{
return dwFlags;
}
void CCategoryBar::ModifyFlag(const DWORD & dwRemove, const DWORD & dwAdd, const UINT redraw)
{
if (dwRemove) dwFlags &= ~(dwRemove);
if (dwAdd) dwFlags |= dwAdd;
if (GetSafeHwnd())
{
if (redraw != 0) SetWindowPos(0,0,0,0,0,SWP_NOZORDER|SWP_NOSIZE|SWP_NOMOVE|redraw);
else Invalidate();
}
}
/*
void CCategoryBar::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if (nIDEvent == 1)
{
CPoint pt(GetMessagePos());
ScreenToClient(&pt);
CRect rc;
GetClientRect(&rc);
if (!(rc.PtInRect(pt)))
{
HighlightFolder(-1);
HighlightItem(-1);
KillTimer(1);
}
}
else if (nIDEvent == 3 && iLastSel >= 0)
{
iSelAnimCount ++;
if (iSelAnimCount > 10) iSelAnimCount = -1;
if (iSelAnimCount == 0)
DrawAnimItem(-1, 1, iLastSel);
if (iSelAnimCount == 1)
DrawAnimItem(0, 0, iLastSel);
if (iSelAnimCount == 2)
DrawAnimItem(1, 1, iLastSel);
if (iSelAnimCount == 3)
DrawAnimItem(0, 0, iLastSel);
}
CWnd::OnTimer(nIDEvent);
}
*/
void CCategoryBar::DrawAnimItem(const int xoffset, const int yoffset, const int index)
{
CImageList * ima = GetFolderImageList(iSelFolder, IsSmallIconView());
CRect rc, irc;
GetInsideRect(irc);
GetItemRect(iSelFolder, iLastSel, rc);
if (iLastSel >= iFirstItem && irc.bottom > rc.bottom && irc.top < rc.top)
{
ASSERT(iSelFolder >= 0 && iSelFolder < GetFolderCount());
CBarFolder * pbf = (CBarFolder *) arFolder.GetAt(iSelFolder);
ASSERT(index >= 0 && index < pbf->GetItemCount());
CBarItem * pi = (CBarItem *) pbf->arItems.GetAt(index);
ASSERT(pi && ima);
CClientDC dc(this);
if (IsSmallIconView())
{
if (ima)
{
IMAGEINFO ii;
ima->GetImageInfo(pi->iImageIndex, &ii);
CSize szImage = CRect(ii.rcImage).Size();
CPoint pt;
pt.x = rc.left + 2;
pt.y = rc.top + (rc.Height() - szImage.cy) / 2;
CRect rcBck(pt.x-1, pt.y-1, pt.x + szImage.cx+2, pt.y + szImage.cy+2);
dc.FillSolidRect(rcBck, crBackGroundColor);
pt.x += xoffset;
pt.y += yoffset;
ima->Draw(&dc, pi->iImageIndex, pt, ILD_NORMAL);
}
}
else
{
if (ima)
{
IMAGEINFO ii;
ima->GetImageInfo(pi->iImageIndex, &ii);
CSize szImage = CRect(ii.rcImage).Size();
CPoint pt;
pt.x = rc.left + (rc.Width() - szImage.cx) / 2;
pt.y = rc.top;
CRect rcBck(pt.x-1, pt.y-1, pt.x + szImage.cx+2, pt.y + szImage.cy+2);
dc.FillSolidRect(rcBck, crBackGroundColor);
pt.x += xoffset;
pt.y += yoffset;
ima->Draw(&dc, pi->iImageIndex, pt, ILD_NORMAL);
}
}
}
}
void CCategoryBar::OnPaint()
{
CRect clientRc;
GetClientRect(&clientRc);
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CDC memDC;
memDC.CreateCompatibleDC(&dc);
CBitmap bmp;
bmp.CreateCompatibleBitmap(&dc, clientRc.Width(), clientRc.Height());
CBitmap * obmp = memDC.SelectObject(&bmp);
CDC * pDC = &memDC;
CRect rc;
GetInsideRect(rc);
if (!GetFolderChild()) pDC->FillSolidRect(rc, crBackGroundColor);
int max = arFolder.GetSize();
CRect frc;
for (int t = 0; t < max; t++)
{
GetFolderRect(t, frc);
DrawFolder(pDC, t, frc, false);
}
if (!GetFolderChild())
{
int f,l;
GetVisibleRange(iSelFolder, f,l);
rcUpArrow.SetRect(0,0,GetSystemMetrics(SM_CXVSCROLL), GetSystemMetrics(SM_CXVSCROLL));
rcDownArrow = rcUpArrow;
rcUpArrow.OffsetRect(rc.right - 5 - GetSystemMetrics(SM_CXVSCROLL), rc.top +5);
rcDownArrow.OffsetRect(rc.right - 5 - GetSystemMetrics(SM_CXVSCROLL), rc.bottom - 5 - GetSystemMetrics(SM_CXVSCROLL));
if (f > 0)
{
if (bUpPressed) pDC->DrawFrameControl(rcUpArrow, DFC_SCROLL, DFCS_SCROLLUP|DFCS_PUSHED);
else pDC->DrawFrameControl(rcUpArrow, DFC_SCROLL, DFCS_SCROLLUP);
bUpArrow = true;
pDC->ExcludeClipRect(rcUpArrow);
}
else bUpArrow = false;
if (l < GetItemCount() - 1)
{
if (bDownPressed) pDC->DrawFrameControl(rcDownArrow, DFC_SCROLL, DFCS_SCROLLDOWN|DFCS_PUSHED);
else pDC->DrawFrameControl(rcDownArrow, DFC_SCROLL, DFCS_SCROLLDOWN);
bDownArrow = true;
pDC->ExcludeClipRect(rcDownArrow);
}
else bDownArrow = false;
PaintItems(pDC, iSelFolder, rc);
}
dc.BitBlt(clientRc.left, clientRc.top, clientRc.Width(), clientRc.Height(), &memDC, 0,0, SRCCOPY);
memDC.SelectObject(obmp);
if (iLastFolderHighlighted >= 0)
{
int i = iLastFolderHighlighted;
iLastFolderHighlighted = -1;
HighlightFolder(i);
}
if (iLastItemHighlighted >= 0)
{
int i = iLastItemHighlighted;
iLastItemHighlighted = -1;
HighlightItem(i, bPressedHighlight);
}
// fix potential resource leak - KStowell - 10-21-99
memDC.DeleteDC();
bmp.DeleteObject();
// Do not call CWnd::OnPaint() for painting messages
}
BOOL CCategoryBar::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return true;
// return CWnd::OnEraseBkgnd(pDC);
}
bool CCategoryBar::GetFolderRect(const int iIndex, CRect & rect) const
{
int max = arFolder.GetSize();
ASSERT(iIndex >= 0 && iIndex < max);
if (iIndex >= 0 && iIndex < max)
{
CRect rc;
GetClientRect(rc);
if (iIndex > iSelFolder)
rect.SetRect(rc.left, rc.bottom - ((max - iIndex)) * iFolderHeight, rc.right,
rc.bottom - (max - iIndex - 1) * iFolderHeight);
else
rect.SetRect(rc.left, rc.top + iIndex * iFolderHeight - 1, rc.right,
rc.top + (1 + iIndex) * iFolderHeight - 1);
return true;
}
return false;
}
void CCategoryBar::GetItemRect(const int iFolder, const int iIndex, CRect & rect)
{
CRect rc;
GetInsideRect(rc);
int top = rc.top;
CSize sz(0,0);
int y = 0;
for (int t = 0; t < iIndex; t++)
{
sz = GetItemSize(iFolder, t, ircAll);
top += sz.cy;
if (IsSmallIconView())
{
top += ySmallIconSpacing;
}
else
{
top += yLargeIconSpacing;
}
if (t == iFirstItem - 1) y = top - rc.top;
}
sz = GetItemSize(iFolder, iIndex, ircAll);
rect.SetRect(rc.left, top, rc.left + sz.cx, top + sz.cy);
rect.top -= y;
rect.bottom -= y;
rect.left += xLeftMargin;
rect.top += yTopMargin;
rect.bottom += yTopMargin;
if (!IsSmallIconView())
{
rect.left = rc.left;
rect.right = rc.right;
}
}
void CCategoryBar::DrawFolder(CDC * pDC, const int iIdx, CRect rect, const bool bSelected)
{
CBarFolder * pbf = (CBarFolder *) arFolder.GetAt(iIdx);
if (!bSelected)
{
CPen pn1(PS_SOLID, 1, crBackGroundColor1);
CPen * op = pDC->SelectObject(&pn1);
pDC->MoveTo(rect.left, rect.top);
pDC->LineTo(rect.right, rect.top);
pDC->SelectObject(op);
// fix potential resource leak - KStowell - 10-21-99
pn1.DeleteObject();
rect.top ++;
pDC->Draw3dRect(rect, crHilightBorder, crBackGroundColor1);
rect.InflateRect(-1,-1);
pDC->FillSolidRect(rect, cr3dFace);
int obk = pDC->SetBkMode(TRANSPARENT);
CFont * of = pDC->SelectObject(CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT)));
pDC->DrawText(CString(pbf->cName), rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
pDC->SetBkMode(obk);
pDC->SelectObject(of);
}
else
{
CPen pn1(PS_SOLID, 1, crBackGroundColor1);
CPen * op = pDC->SelectObject(&pn1);
pDC->MoveTo(rect.left+1, rect.top);
pDC->LineTo(rect.right, rect.top);
pDC->SelectObject(op);
// fix potential resource leak - KStowell - 10-21-99
pn1.DeleteObject();
rect.top ++;
pDC->Draw3dRect(rect, crDkShadowBorder, crHilightBorder);
rect.InflateRect(-1,-1);
pDC->Draw3dRect(rect, crBackGroundColor1, cr3dFace);
rect.InflateRect(-1,-1);
pDC->FillSolidRect(rect, cr3dFace);
int obk = pDC->SetBkMode(TRANSPARENT);
CFont * of = pDC->SelectObject(CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT)));
pDC->DrawText(CString(pbf->cName), rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
pDC->SetBkMode(obk);
pDC->SelectObject(of);
}
}
int CCategoryBar::AddFolder( LPCTSTR cFolderName, const DWORD exData )
{
CBarFolder* pbf = new CBarFolder(cFolderName, exData);
ASSERT(pbf);
arFolder.Add((void *)pbf);
return arFolder.GetSize() - 1;
}
CCategoryBar::CBarFolder::CBarFolder( LPCTSTR name, DWORD exData)
{
cName = NULL;
dwData = exData;
if( name )
{
cName = new TCHAR[ _tcslen( name ) + 1 ];
ASSERT(cName);
_tcscpy( cName, name );
}
pLargeImageList = NULL;
pSmallImageList = NULL;
pChild = NULL;
}
CCategoryBar::CBarFolder::~CBarFolder()
{
if (cName) delete [] cName;
for (int t = 0; t < arItems.GetSize(); t++)
if (arItems.GetAt(t)) delete (CBarFolder*) arItems.GetAt(t);
arItems.RemoveAll();
}
void CCategoryBar::GetInsideRect(CRect & rect) const
{
GetClientRect(rect);
if (arFolder.GetSize() > 0)
{
int max = arFolder.GetSize();
rect.top += iFolderHeight * (iSelFolder + 1) - 1;//+ 2;
rect.bottom -= (max - iSelFolder - 1)*iFolderHeight;
return;
}
}
void CCategoryBar::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -