www.pudn.com > editpad_src > bcgtoolbarbutton.cpp, change:1999-12-16,size:17680b
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// This source code is a part of BCGControlBar library.
// You may use, compile or redistribute it as part of your application
// for free. You cannot redistribute it as a part of a software development
// library without the agreement of the author. If the sources are
// distributed along with the application, you should leave the original
// copyright notes in the source code without any changes.
// This code can be used WITHOUT ANY WARRANTIES on your own risk.
//
// Stas Levin <stas@iet.co.il>
//*******************************************************************************
// BCGToolbarButton.cpp: implementation of the CBCGToolbarButton class.
//
//////////////////////////////////////////////////////////////////////
#include "Stdafx.h"
#include "BCGToolbar.h"
#include "BCGToolbarButton.h"
#include "BCGToolBarImages.h"
#include "BCGCommandManager.h"
#include "globals.h"
#include "BCGFrameWnd.h"
#include "BCGMDIFrameWnd.h"
#include "BCGOleIPFrameWnd.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
IMPLEMENT_SERIAL(CBCGToolbarButton, CObject, VERSIONABLE_SCHEMA | 1)
CLIPFORMAT CBCGToolbarButton::m_cFormat = (CLIPFORMAT)::RegisterClipboardFormat (_T("BCGToolbarButton"));
static const int TEXT_MARGIN = 3;
static const int SEPARATOR_WIDTH = 8;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBCGToolbarButton::CBCGToolbarButton()
{
Initialize ();
}
//*********************************************************************************
CBCGToolbarButton::CBCGToolbarButton(UINT uiID, int iImage, LPCTSTR lpszText, BOOL bUserButton,
BOOL bLocked)
{
Initialize ();
m_bLocked = bLocked;
m_nID = uiID;
m_bUserButton = bUserButton;
SetImage (iImage);
m_strText = (lpszText == NULL) ? _T("") : lpszText;
if (m_nID != 0 && !m_bLocked)
{
if (m_bUserButton)
{
if (m_iUserImage != -1)
{
CMD_MGR.SetCmdImage (m_nID, m_iUserImage, TRUE);
}
else
{
m_iUserImage = CMD_MGR.GetCmdImage (m_nID, TRUE);
}
}
else
{
if (m_iImage != -1)
{
CMD_MGR.SetCmdImage (m_nID, m_iImage, FALSE);
}
else
{
m_iImage = CMD_MGR.GetCmdImage (m_nID, FALSE);
}
}
}
}
//*********************************************************************************
void CBCGToolbarButton::Initialize ()
{
m_nID = 0;
m_nStyle = TBBS_BUTTON;
m_iImage = -1;
m_iUserImage = -1;
m_bUserButton = FALSE;
m_bDragFromCollection = FALSE;
m_bText = FALSE;
m_bImage = TRUE;
m_bWrap = FALSE;
m_bWholeText = TRUE;
m_bLocked = FALSE;
m_bIsHidden = FALSE;
m_bTextBelow = FALSE;
m_rect.SetRectEmpty ();
m_sizeText = CSize (0, 0);
}
//*********************************************************************************
CBCGToolbarButton::~CBCGToolbarButton()
{
}
//*********************************************************************************
void CBCGToolbarButton::CopyFrom (const CBCGToolbarButton& src)
{
m_nID = src.m_nID;
m_bLocked = src.m_bLocked;
m_bUserButton = src.m_bUserButton;
m_nStyle = src.m_nStyle;
SetImage (src.m_bUserButton ? src.m_iUserImage : src.m_iImage);
m_strText = src.m_strText;
m_bText = src.m_bText;
m_bImage = src.m_bImage;
m_bWrap = src.m_bWrap;
m_bDragFromCollection = FALSE;
}
//***************************************************************************************
void CBCGToolbarButton::Serialize (CArchive& ar)
{
CObject::Serialize (ar);
if (ar.IsLoading ())
{
int iImage;
ar >> m_nID;
ar >> m_nStyle;
ar >> iImage;
ar >> m_strText;
ar >> m_bUserButton;
ar >> m_bDragFromCollection;
ar >> m_bText;
ar >> m_bImage;
SetImage (iImage);
}
else
{
ar < m_nID;
ar < m_nStyle;
ar < GetImage ();
ar < m_strText;
ar < m_bUserButton;
ar < m_bDragFromCollection;
ar < m_bText;
ar < m_bImage;
}
}
//***************************************************************************************
CLIPFORMAT CBCGToolbarButton::GetClipboardFormat ()
{
return m_cFormat;
}
//***************************************************************************************
CBCGToolbarButton* CBCGToolbarButton::CreateFromOleData (COleDataObject* pDataObject)
{
ASSERT (pDataObject != NULL);
ASSERT (pDataObject->IsDataAvailable (CBCGToolbarButton::m_cFormat));
CBCGToolbarButton* pButton = NULL;
try
{
//-------------------------------------
// Get file refering to clipboard data:
//-------------------------------------
CFile* pFile = pDataObject->GetFileData (GetClipboardFormat ());
if (pFile == NULL)
{
return FALSE;
}
//-------------------------------------------------------
// Connect the file to the archive and read the contents:
//-------------------------------------------------------
CArchive ar (pFile, CArchive::load);
//----------------------------------------
// First, read run-time class information:
//----------------------------------------
CRuntimeClass* pClass = ar.ReadClass ();
ASSERT (pClass != NULL);
pButton = (CBCGToolbarButton*) pClass->CreateObject ();
ASSERT (pButton != NULL);
pButton->Serialize (ar);
ar.Close ();
delete pFile;
return pButton;
}
catch (COleException* pEx)
{
TRACE(_T("CBCGToolbarButton::CreateFromOleData. OLE exception: %x\r\n"),
pEx->m_sc);
pEx->Delete ();
return NULL;
}
catch (CArchiveException* pEx)
{
TRACE(_T("CBCGToolbarButton::CreateFromOleData. Archive exception\r\n"));
pEx->Delete ();
return FALSE;
}
catch (CNotSupportedException *pEx)
{
TRACE(_T("CBCGToolbarButton::CreateFromOleData. \"Not Supported\" exception\r\n"));
pEx->Delete ();
return FALSE;
}
if (pButton != NULL)
{
delete pButton;
}
return NULL;
}
//***************************************************************************************
void CBCGToolbarButton::OnDraw (CDC* pDC, const CRect& rect, CBCGToolBarImages* pImages,
BOOL bHorz, BOOL bCustomizeMode, BOOL bHighlight,
BOOL bDrawBorder, BOOL bGrayDisabledButtons)
{
ASSERT_VALID (pDC);
ASSERT_VALID (this);
BOOL bHot = bHighlight;
CSize sizeImage = (pImages == NULL) ? CSize (0, 0) : pImages->GetImageSize (TRUE);
//---------------
// Interior grey:
//---------------
// pDC->FillRect (rect, &globalData.brBtnFace);
if (!bCustomizeMode && !bHighlight &&
(m_nStyle & (TBBS_CHECKED | TBBS_INDETERMINATE)))
{
CRect rectDither = rect;
rectDither.InflateRect (-afxData.cxBorder2, -afxData.cyBorder2);
CBCGToolBarImages::FillDitheredRect (pDC, rectDither);
}
int x = rect.left;
int y = rect.top;
int iTextLen = 0;
if (IsDrawText () && !(m_bTextBelow && bHorz))
{
CString strWithoutAmp = m_strText;
strWithoutAmp.Remove (_T('&'));
iTextLen = pDC->GetTextExtent (strWithoutAmp).cx + 2 * TEXT_MARGIN;
}
int dx = 0;
int dy = 0;
if (m_bTextBelow && bHorz)
{
ASSERT (bHorz);
dx = rect.Width ();
dy = sizeImage.cy + 2 * TEXT_MARGIN;
}
else
{
dx = bHorz ? rect.Width () - iTextLen : rect.Width ();
dy = bHorz ? rect.Height () : rect.Height () - iTextLen;
}
// determine offset of bitmap (centered within button)
CPoint ptImageOffset;
ptImageOffset.x = (dx - sizeImage.cx - 1) / 2;
ptImageOffset.y = (dy - sizeImage.cy + 1) / 2;
CPoint ptTextOffset (TEXT_MARGIN, TEXT_MARGIN);
if (IsDrawText () && !(m_bTextBelow && bHorz))
{
TEXTMETRIC tm;
pDC->GetTextMetrics (&tm);
if (bHorz)
{
ptTextOffset.y = (dy - tm.tmHeight - 1) / 2;
}
else
{
ptTextOffset.x = (dx - tm.tmHeight + 1) / 2;
}
}
CPoint ptImageOffsetInButton (0, 0);
BOOL bPressed = FALSE;
if ((m_nStyle & (TBBS_PRESSED | TBBS_CHECKED)) && !bCustomizeMode)
{
// pressed in or checked
ptImageOffset.Offset (1, 1);
bPressed = TRUE;
ptTextOffset.x ++;
if (bHorz)
{
ptTextOffset.y ++;
}
else
{
ptTextOffset.y --;
}
}
BOOL bImageIsReady = FALSE;
if ((m_nStyle & TBBS_PRESSED) || !(m_nStyle & TBBS_DISABLED) ||
bCustomizeMode)
{
if (IsDrawImage () && pImages != NULL)
{
pImages->Draw (pDC, x + ptImageOffset.x, y + ptImageOffset.y, GetImage ());
}
if (bCustomizeMode || m_nStyle & TBBS_PRESSED)
{
bImageIsReady = TRUE;
}
}
BOOL bDisabled = (bCustomizeMode && !IsEditable ()) ||
(!bCustomizeMode && (m_nStyle & TBBS_DISABLED));
if (!bImageIsReady)
{
if (!bHighlight)
{
bHighlight = !(m_nStyle & (TBBS_CHECKED | TBBS_INDETERMINATE));
}
if (IsDrawImage () && pImages != NULL)
{
pImages->Draw (pDC, x + ptImageOffset.x, y + ptImageOffset.y, GetImage (),
!bHighlight, bDisabled && bGrayDisabledButtons);
}
}
if ((m_bTextBelow && bHorz) || IsDrawText ())
{
//--------------------
// Draw button's text:
//--------------------
pDC->SetTextColor (bDisabled ?
globalData.clrGrayedText :
(bHot) ? CBCGToolBar::GetHotTextColor () :
globalData.clrBtnText);
CString strText = m_strText;
CRect rectText = rect;
UINT uiTextFormat = 0;
if (m_bTextBelow && bHorz)
{
ASSERT (bHorz);
ptTextOffset.y += sizeImage.cy + TEXT_MARGIN;
uiTextFormat = DT_CENTER | DT_WORDBREAK;
rectText.left = (rect.left + rect.right - m_sizeText.cx) / 2 + ptTextOffset.x;
rectText.right = (rect.left + rect.right + m_sizeText.cx) / 2;
}
else
{
if (IsDrawImage ())
{
if (bHorz)
{
ptTextOffset.x += ptImageOffset.x + sizeImage.cx;
}
else
{
ptTextOffset.y += TEXT_MARGIN;
}
}
rectText.left = x + ptTextOffset.x + TEXT_MARGIN;
uiTextFormat = DT_SINGLELINE;
}
if (bHorz)
{
rectText.top += ptTextOffset.y;
}
else
{
rectText.top = rect.bottom - ptTextOffset.y - TEXT_MARGIN;
rectText.bottom = rect.top;
rectText.right = rectText.left;
rectText.left = x + ptTextOffset.x;
strText.Remove (_T('&'));
uiTextFormat |= DT_NOCLIP;
}
pDC->DrawText (strText, &rectText, uiTextFormat);
}
//--------------------
// Draw button border:
//--------------------
if (!bCustomizeMode && HaveHotBorder () && bDrawBorder)
{
if (m_nStyle & (TBBS_PRESSED | TBBS_CHECKED))
{
//-----------------------
// Pressed in or checked:
//-----------------------
pDC->Draw3dRect (&rect,
afxData.clrBtnShadow,
afxData.clrBtnHilite);
}
else if (bHot && !(m_nStyle & TBBS_DISABLED) &&
!(m_nStyle & (TBBS_CHECKED | TBBS_INDETERMINATE)))
{
pDC->Draw3dRect (&rect, afxData.clrBtnHilite,
afxData.clrBtnShadow);
}
}
}
//***********************************************************************************
SIZE CBCGToolbarButton::OnCalculateSize (
CDC* pDC,
const CSize& sizeDefault,
BOOL bHorz)
{
ASSERT_VALID (pDC);
CSize size = sizeDefault;
if (m_nStyle & TBBS_SEPARATOR)
{
if (bHorz)
{
size.cx = m_iImage > 0 ? m_iImage : SEPARATOR_WIDTH;
}
else
{
size.cy = SEPARATOR_WIDTH;
}
}
else
{
if (!IsDrawImage () || GetImage () 0)
{
if (bHorz)
{
size.cx = 0;
}
else
{
size.cy = 0;
}
}
m_sizeText = CSize (0, 0);
if (!m_strText.IsEmpty ())
{
if (m_bTextBelow && bHorz)
{
//----------------------------------------------------------
// Try format text that it ocuppies no more tow lines an its
// width less than 3 images:
//----------------------------------------------------------
CRect rectText (0, 0,
sizeDefault.cx * 3, sizeDefault.cy);
pDC->DrawText ( m_strText, rectText,
DT_CENTER | DT_CALCRECT | DT_WORDBREAK);
m_sizeText = rectText.Size ();
m_sizeText.cx += 2 * TEXT_MARGIN;
size.cx = max (size.cx, m_sizeText.cx) + 4 * TEXT_MARGIN;
size.cy += m_sizeText.cy + 2 * TEXT_MARGIN;
}
else if (IsDrawText ())
{
CString strWithoutAmp = m_strText;
strWithoutAmp.Remove (_T('&'));
int iTextLen = pDC->GetTextExtent (strWithoutAmp).cx + 2 * TEXT_MARGIN + 6;
if (bHorz)
{
size.cx += iTextLen;
}
else
{
size.cy += iTextLen;
}
}
}
}
return size;
}
//************************************************************************************
BOOL CBCGToolbarButton::PrepareDrag (COleDataSource& srcItem)
{
if (!CanBeStored ())
{
return TRUE;
}
try
{
CSharedFile globFile;
CArchive ar (&globFile,CArchive::store);
//---------------------------------
// Save run-time class information:
//---------------------------------
CRuntimeClass* pClass = GetRuntimeClass ();
ASSERT (pClass != NULL);
ar.WriteClass (pClass);
//---------------------
// Save button context:
//---------------------
Serialize (ar);
ar.Close();
srcItem.CacheGlobalData (GetClipboardFormat (), globFile.Detach());
}
catch (COleException* pEx)
{
TRACE(_T("CBCGToolbarButton::PrepareDrag. OLE exception: %x\r\n"),
pEx->m_sc);
pEx->Delete ();
return FALSE;
}
catch (CArchiveException* pEx)
{
TRACE(_T("CBCGToolbarButton::PrepareDrag. Archive exception\r\n"));
pEx->Delete ();
return FALSE;
}
return TRUE;
}
//****************************************************************************************
void CBCGToolbarButton::SetImage (int iImage)
{
if (m_nStyle & TBBS_SEPARATOR)
{
m_iImage = iImage; // Actualy, separator width!
return;
}
if (m_bUserButton)
{
m_iUserImage = iImage;
}
else
{
m_iImage = iImage;
}
if (!m_bLocked)
{
if (m_nID != 0 && iImage != -1)
{
CMD_MGR.SetCmdImage (m_nID, iImage, m_bUserButton);
}
else if (m_nID != 0)
{
m_iImage = CMD_MGR.GetCmdImage (m_nID, FALSE);
m_iUserImage = CMD_MGR.GetCmdImage (m_nID, TRUE);
if (m_iImage == -1 && !m_bUserButton)
{
m_bUserButton = TRUE;
}
else if (m_iImage == -1 && m_bUserButton)
{
m_bUserButton = FALSE;
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CBCGToolbarButton diagnostics
#ifdef _DEBUG
void CBCGToolbarButton::AssertValid() const
{
CObject::AssertValid();
}
//******************************************************************************************
void CBCGToolbarButton::Dump(CDumpContext& dc) const
{
CObject::Dump (dc);
CString strId;
strId.Format (_T("%x"), m_nID);
dc < "[" < strId < " " < m_strText < "]";
dc < "\n";
}
#endif
int CBCGToolbarButton::OnDrawOnCustomizeList (
CDC* pDC, const CRect& rect, BOOL bSelected)
{
int iWidth = 0;
ASSERT_VALID (pDC);
CBCGToolBarImages* pImages = m_bUserButton ?
CBCGToolBar::GetUserImages () :
CBCGToolBar::GetImages ();
CBCGToolBarImages* pCommonImages = CBCGToolBar::GetImages ();
CSize sizeButton (0, 0);
if (pCommonImages != NULL)
{
sizeButton = CSize (pCommonImages->GetImageSize ().cx + 6,
pCommonImages->GetImageSize ().cy + 6);
}
CRect rectRow = rect;
CRect rectText = rect;
rectText.left += sizeButton.cx;
iWidth = sizeButton.cx;
//-------------------
// Draw button image:
//-------------------
if (GetImage () >= 0 && pImages != NULL)
{
CRect rectImage = rect;
rectImage.right = rectImage.left + sizeButton.cx;
CBCGDrawState ds;
pImages->PrepareDrawImage (ds);
OnDraw (pDC, rectImage, pImages, TRUE, TRUE, bSelected);
pImages->EndDrawImage (ds);
rectRow.left = rectImage.right;
}
//-------------------
// Draw button text:
//-------------------
if (!m_strText.IsEmpty ())
{
COLORREF clrTextOld;
if (bSelected)
{
pDC->FillSolidRect (rectRow, ::GetSysColor (COLOR_HIGHLIGHT));
clrTextOld = pDC->SetTextColor (::GetSysColor (COLOR_HIGHLIGHTTEXT));
}
else
{
pDC->FillRect (rectRow, &globalData.brBtnFace);
clrTextOld = pDC->SetTextColor (::GetSysColor (COLOR_BTNTEXT));
}
pDC->SetBkMode (TRANSPARENT);
pDC->DrawText (m_strText, rectText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
pDC->SetTextColor (clrTextOld);
int iTextWidth = min (rectText.Width (), pDC->GetTextExtent (m_strText).cx);
iWidth += iTextWidth;
}
if (bSelected)
{
pDC->DrawFocusRect (rectRow);
}
return iWidth;
}
//*************************************************************************************
BOOL CBCGToolbarButton::OnToolHitTest(const CWnd* pWnd, TOOLINFO* pTI)
{
CFrameWnd* pTopFrame = (pWnd == NULL) ?
(CFrameWnd*) AfxGetMainWnd () :
pWnd->GetTopLevelFrame ();
CBCGMDIFrameWnd* pMainFrame = DYNAMIC_DOWNCAST (CBCGMDIFrameWnd, pTopFrame);
if (pMainFrame != NULL)
{
return pMainFrame->OnMenuButtonToolHitTest (this, pTI);
}
else // Maybe, SDI frame...
{
CBCGFrameWnd* pFrame = DYNAMIC_DOWNCAST (CBCGFrameWnd, pTopFrame);
if (pFrame != NULL)
{
return pFrame->OnMenuButtonToolHitTest (this, pTI);
}
else // Maybe, OLE frame...
{
CBCGOleIPFrameWnd* pOleFrame =
DYNAMIC_DOWNCAST (CBCGOleIPFrameWnd, pFrame);
if (pOleFrame != NULL)
{
return pOleFrame->OnMenuButtonToolHitTest (this, pTI);
}
}
}
return FALSE;
}