// ToolBarExCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "ToolBarExCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CToolBarExCtrl
CToolBarExCtrl::CToolBarExCtrl()
{
m_buttonSpacing = CSize(20,20);
m_backGroundColor = RGB (255,255,255);
m_buttonSize = CSize(16,16);
m_ToolTip.Create(this);
m_ToolTip.Activate(TRUE);
m_hotButton = -1;
m_pushedButton = -1;
}
CToolBarExCtrl::~CToolBarExCtrl()
{
for (int i = 0; i < buttons.GetSize(); i++)
DestroyIcon(buttons[i].icon);
}
BEGIN_MESSAGE_MAP(CToolBarExCtrl, CStatic)
//{{AFX_MSG_MAP(CToolBarExCtrl)
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CToolBarExCtrl message handlers
void CToolBarExCtrl::SetButtonSpacing(CSize spacing)
{
m_buttonSpacing = spacing;
Invalidate();
}
void CToolBarExCtrl::SetButtonSize(CSize size)
{
m_buttonSize = size;
Invalidate();
}
void CToolBarExCtrl::AddButton(HICON icon, int commandId, LPCTSTR text)
{
ButtonEx button;
button.icon = icon;
button.idCommand = commandId;
button.fsState = BT_EX_ENABLED;
button.fsStyle = BT_EX_BUTTON;
button.tooltip = strdup(text);
int nIndex = buttons.Add(button);
rects.Add(CRect(0,0,0,0));
m_ToolTip.AddTool(this,text,&CRect(10,10,30,30),commandId);
Invalidate();
}
void CToolBarExCtrl::AddSeparator()
{
ButtonEx button;
button.icon = NULL;
button.idCommand = NULL;
button.fsState = BT_EX_ENABLED;
button.fsStyle = BT_EX_SEPARATOR;
button.tooltip = NULL;
buttons.Add(button);
rects.Add(CRect(0,0,0,0));
Invalidate();
}
void CToolBarExCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CDC* pDCMem = new CDC;
CBitmap bpMem;
CBitmap *bmOld;
CRect rcClient;
// Get client rectangle
GetClientRect(rcClient);
// Create DC
pDCMem->CreateCompatibleDC(&dc);
// Create bitmap
bpMem.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
// Select bitmap
bmOld = pDCMem->SelectObject(&bpMem);
// Draw control background
pDCMem->FillSolidRect(rcClient,m_backGroundColor);
CRect rect(0,0,m_buttonSpacing.cx,m_buttonSpacing.cy);
CRect btRect;
for (int i = 0; i < buttons.GetSize(); i++)
{
if (buttons[i].fsStyle == BT_EX_BUTTON)
{
btRect = rect;
CSize border = m_buttonSpacing - m_buttonSize;
btRect.DeflateRect(border.cx/2,border.cy/2);
int nFlags = DST_ICON;
if (buttons[i].fsState == BT_EX_DISABLED)
nFlags = nFlags | DSS_DISABLED;
if (m_hotButton == i)
{
CRect focusRect = btRect;
focusRect.InflateRect(2,2);
if (m_pushedButton == i)
pDCMem->FrameRect(&focusRect, &CBrush(RGB(255,0,0)));
else
pDCMem->FrameRect(&focusRect, &CBrush(RGB(0,0,255)));
}
pDCMem->DrawState(btRect.TopLeft(),m_buttonSize,buttons[i].icon,nFlags,(CBrush*)NULL);
rects[i] = btRect;
m_ToolTip.SetToolRect(this,buttons[i].idCommand,btRect);
rect.OffsetRect(m_buttonSpacing.cx,0);
}
else
{
btRect = rect;
CSize border = m_buttonSpacing - m_buttonSize;
btRect.DeflateRect(2,border.cy/2);
btRect.right = btRect.left + 3;
pDCMem->DrawEdge(&btRect,EDGE_BUMP,BF_RECT);
rect.OffsetRect(7,0);
}
if (rect.right > rcClient.right)
{
rect.left = 0;
rect.top += m_buttonSpacing.cy;
rect.right = m_buttonSpacing.cx;
rect.bottom += m_buttonSpacing.cy;
}
}
// Copy back buffer to the display
dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), pDCMem, 0, 0, SRCCOPY);
// Select old objects
pDCMem->SelectObject(bmOld);
// Delete objects
if (pDCMem->GetSafeHdc() != NULL)
{
pDCMem->DeleteDC();
}
delete pDCMem;
if (bpMem.GetSafeHandle() != NULL)
{
bpMem.DeleteObject();
}
}
void CToolBarExCtrl::RemoveButton(int nIndex, int commandId)
{
if (nIndex > -1 && nIndex < buttons.GetSize())
{
buttons.RemoveAt(nIndex);
rects.RemoveAt(nIndex);
m_ToolTip.DelTool(this,nIndex);
}
else
{
for (int i = 0; i < buttons.GetSize(); i++)
{
if (buttons[i].idCommand == commandId)
{
buttons.RemoveAt(i);
rects.RemoveAt(i);
m_ToolTip.DelTool(this,i);
}
}
}
Invalidate();
}
void CToolBarExCtrl::SetBackGroundColor(COLORREF color)
{
m_backGroundColor = color;
Invalidate();
}
BOOL CToolBarExCtrl::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
BOOL res = CStatic::PreTranslateMessage(pMsg);
m_ToolTip.RelayEvent(pMsg);
return res;
}
void CToolBarExCtrl::EnableButton(int nId, bool bEnable)
{
if (nId < 0 || nId > buttons.GetSize())
return;
if (bEnable)
buttons[nId].fsState = BT_EX_ENABLED;
else
buttons[nId].fsState = BT_EX_DISABLED;
Invalidate();
}
ButtonEx* CToolBarExCtrl::GetButton(int nIndex, int commandId)
{
if (nIndex > -1 && nIndex < buttons.GetSize())
return &buttons[nIndex];
else
{
for (int i = 0; i < buttons.GetSize(); i++)
{
if (buttons[i].idCommand == commandId)
{
return &buttons[i];
}
}
}
return NULL;
}
void CToolBarExCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
TOOLINFO ti;
BOOL bHit = m_ToolTip.HitTest(this,point,&ti);
if (bHit)
{
for (int i = 0; i < buttons.GetSize(); i++)
{
if (buttons[i].idCommand == ti.uId && buttons[i].fsState)
{
m_hotButton = i;
::SetCursor(LoadCursor(NULL,MAKEINTRESOURCE(32649)));
}
}
}
else
{
m_hotButton = -1;
::SetCursor(LoadCursor(NULL,IDC_ARROW));
}
Invalidate();
CStatic::OnMouseMove(nFlags, point);
}
void CToolBarExCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
TOOLINFO ti;
BOOL bHit = m_ToolTip.HitTest(this,point,&ti);
if (bHit)
{
for (int i = 0; i < buttons.GetSize(); i++)
{
if (buttons[i].idCommand == ti.uId && buttons[i].fsState)
{
m_pushedButton = i;
::SetCursor(LoadCursor(NULL,MAKEINTRESOURCE(32649)));
}
}
}
else
{
m_pushedButton = -1;
::SetCursor(LoadCursor(NULL,IDC_ARROW));
}
Invalidate();
CStatic::OnLButtonDown(nFlags, point);
}
void CToolBarExCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
TOOLINFO ti;
BOOL bHit = m_ToolTip.HitTest(this,point,&ti);
if (bHit)
{
for (int i = 0; i < buttons.GetSize(); i++)
{
if (buttons[i].idCommand == ti.uId && buttons[i].fsState)
{
GetParent()->SendMessage(WM_COMMAND,(WPARAM)buttons[i].idCommand,(LPARAM)m_hWnd);
::SetCursor(LoadCursor(NULL,MAKEINTRESOURCE(32649)));
}
}
}
else
::SetCursor(LoadCursor(NULL,IDC_ARROW));
m_pushedButton = -1;
Invalidate();
CStatic::OnLButtonUp(nFlags, point);
}