// OXCoolToolBar.cpp : implementation file
//
// Version: 9.3
#include "stdafx.h"
#include <stdlib.h>
#include "OXCoolToolBar.h"
#include "UTBStrOp.h"
#ifdef OX_CUSTOMIZE_COMMANDS
#include "OXDragDropCommands.h"
#endif // OX_CUSTOMIZE_COMMANDS
#if _MFC_VER>0x0421
#include <afxdtctl.h>
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int ID_OXGRIPPER_WIDTH = 0;
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// COXCoolToolBar idle update through COXCoolToolBarCmdUI class.
void COXCoolToolBarCmdUI::Enable(BOOL bOn)
{
m_bEnableChanged = TRUE;
COXCoolToolBar* pCoolToolBar = (COXCoolToolBar*)m_pOther;
CToolBarCtrl* pToolBarCtrl = &pCoolToolBar->GetToolBarCtrl();
ASSERT(pToolBarCtrl != NULL);
ASSERT(m_nIndex < m_nIndexMax);
// Get toolbar button state
TBBUTTON TB;
pToolBarCtrl->GetButton(m_nIndex, &TB);
BYTE nNewState = (BYTE) (TB.fsState & ~TBSTATE_ENABLED);
if (bOn)
nNewState |= TBSTATE_ENABLED;
if (nNewState != TB.fsState)
{
#ifdef TBIF_BYINDEX
TBBUTTONINFO bi;
ZeroMemory(&bi, sizeof(bi));
bi.cbSize=sizeof(bi);
bi.dwMask = TBIF_BYINDEX | TBIF_STATE;
bi.fsState = nNewState;
pToolBarCtrl->SetButtonInfo(m_nIndex, &bi);
#else
pToolBarCtrl->SetState(m_nID, nNewState);
#endif
}
}
void COXCoolToolBarCmdUI::SetCheck(int nCheck)
{
ASSERT(nCheck >= 0 && nCheck <= 2); // 0=>off, 1=>on, 2=>indeterminate
COXCoolToolBar* pCoolToolBar = (COXCoolToolBar*)m_pOther;
CToolBarCtrl* pToolBarCtrl = &pCoolToolBar->GetToolBarCtrl();
ASSERT(pToolBarCtrl != NULL);
ASSERT(m_nIndex < m_nIndexMax);
// Get toolbar button state
TBBUTTON TB;
pToolBarCtrl->GetButton(m_nIndex, &TB);
BYTE nNewState = (BYTE) (TB.fsState & ~ (TBSTATE_CHECKED | TBSTATE_INDETERMINATE));
if (nCheck == 1)
nNewState |= TBSTATE_CHECKED;
else
if (nCheck == 2)
nNewState |= TBSTATE_INDETERMINATE;
if (nNewState != TB.fsState)
{
#ifdef TBIF_BYINDEX
TBBUTTONINFO bi;
ZeroMemory(&bi, sizeof(bi));
bi.cbSize=sizeof(bi);
bi.dwMask = TBIF_BYINDEX | TBIF_STATE;
bi.fsState = nNewState;
pToolBarCtrl->SetButtonInfo(m_nIndex, &bi);
#else
pToolBarCtrl->SetState(m_nID, nNewState);
#endif
}
// should we set the button style too ?
// pToolBarCtrl->_SetButtonStyle(m_nIndex, nNewStyle | TBBS_CHECKBOX);
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// COXCoolToolBar
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
#include "OXSkins.h"
DWORD COXCoolToolBar::m_dwComCtlVersion=0;
CMap<int,int,OXCUSTOMBUTTONDESCRIPTOR,OXCUSTOMBUTTONDESCRIPTOR&>
COXCoolToolBar::m_mapAllCustomButtons;
CArray<int,int> COXCoolToolBar::m_arrAllCustomButtonIDs;
BOOL COXCoolToolBar::m_bCustomButtonsStateSaved=FALSE;
BOOL COXCoolToolBar::m_bCustomButtonsStateLoaded=FALSE;
IMPLEMENT_DYNAMIC(COXCoolToolBar,CToolBar)
COXCoolToolBar::COXCoolToolBar() :
#if _MFC_VER>=0x0420
m_bCool(FALSE),
// by default - flat mode
m_bSeparator(TRUE),
m_nIndent(0),
// means not set
m_sizeMinMaxWidth(-1,-1),
m_crDefaultTextColor(CLR_DEFAULT),
m_crHotTextColor(CLR_DEFAULT),
m_crSelectedTextColor(CLR_DEFAULT),
m_crCheckedTextColor(CLR_DEFAULT),
m_crDefaultBkColor(CLR_DEFAULT),
m_crHotBkColor(CLR_DEFAULT),
m_crSelectedBkColor(CLR_DEFAULT),
m_crCheckedBkColor(CLR_DEFAULT),
m_crDefaultBorderColor(CLR_DEFAULT),
m_crHotBorderColor(CLR_DEFAULT),
m_crSelectedBorderColor(CLR_DEFAULT),
m_crCheckedBorderColor(CLR_DEFAULT),
m_bDropDownArrow(FALSE),
#endif
m_ttID(TTID_NOTSET),
m_pBitmapIds(NULL),
m_nBitmapButtons(0),
m_hIcon(NULL),
m_bPrevFloating(3), // neither TRUE not FALSE;
m_dwPrevDockSide((DWORD)-1), // none of side
m_nCustomizedButtonIndex(-1),
m_bAdvancedCutomizable(FALSE),
m_bInAdvancedCustomizationMode(FALSE),
m_bDragDropOwner(FALSE),
m_bDragDropOperation(FALSE),
m_hWndCustomizeOrganizer(NULL),
m_nDraggedButtonIndex(-1),
m_bNoInternalRedraw(FALSE),
m_bNoBkgndRedraw(FALSE),
m_nIdleFlags(0),
m_pToolbarSkin(NULL),
m_iDropDownIndex(-1),
m_iLastDropDownIndex(-1),
m_bFloatingEnabled(TRUE),
m_bSnapWhileDragging(FALSE),
m_bDragging(FALSE),
m_ptLButtonDown(0, 0)
{
m_bWindowsNTRunning=IsWindowsNTRunning();
if(m_dwComCtlVersion==0)
{
DWORD dwMajor, dwMinor;
if(SUCCEEDED(GetComCtlVersion(&dwMajor, &dwMinor)))
{
m_dwComCtlVersion=MAKELONG((WORD)dwMinor, (WORD)dwMajor);
}
else
{
// assume that neither IE 3.0 nor IE 4.0 installed
m_dwComCtlVersion=0x00040000;
}
}
m_nDropDownArrowWidth=GetDropDownArrowWidth();
m_iconRect.SetRectEmpty();
}
COXCoolToolBar::~COXCoolToolBar()
{
LPTSTR lpszResourceName;
// delete all bitmaps that we associated with CoolToolBar
HBITMAP hBitmap;
POSITION pos=m_allBitmaps.GetStartPosition();
while(pos!=NULL)
{
m_allBitmaps.GetNextAssoc(pos,lpszResourceName,hBitmap);
::DeleteObject(hBitmap);
}
m_allBitmaps.RemoveAll();
// delete all image lists that we associated with CoolToolBar
HANDLE hImageList;
pos=m_allImageLists.GetStartPosition();
while(pos!=NULL)
{
m_allImageLists.GetNextAssoc(pos,lpszResourceName,hImageList);
ImageList_Destroy((HIMAGELIST)hImageList);
}
m_allImageLists.RemoveAll();
// delete the classic skin
if (m_pToolbarSkin != NULL)
delete m_pToolbarSkin;
}
BEGIN_MESSAGE_MAP(COXCoolToolBar, CToolBar)
//{{AFX_MSG_MAP(COXCoolToolBar)
ON_WM_NCCREATE()
ON_WM_NCPAINT()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_NCCALCSIZE()
ON_WM_WINDOWPOSCHANGING()
ON_WM_WINDOWPOSCHANGED()
ON_WM_SETTINGCHANGE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDBLCLK()
//}}AFX_MSG_MAP
ON_MESSAGE(TB_INSERTBUTTON, OnInsertButton)
ON_MESSAGE(TB_DELETEBUTTON, OnDeleteButton)
#if _MFC_VER>=0x0420
ON_MESSAGE(TB_MOVEBUTTON, OnMoveButton)
#endif
ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
// reflect messages to make customization work
ON_NOTIFY_REFLECT_EX(TBN_BEGINDRAG, OnTBNBeginDrag)
ON_NOTIFY_REFLECT_EX(TBN_ENDDRAG, OnTBNEndDrag)
ON_NOTIFY_REFLECT_EX(TBN_QUERYINSERT, OnTBNQueryInsert)
ON_NOTIFY_REFLECT_EX(TBN_QUERYDELETE, OnTBNQueryDelete)
ON_NOTIFY_REFLECT_EX(TBN_TOOLBARCHANGE, OnTBNToolBarChange)
ON_NOTIFY_REFLECT_EX(TBN_GETBUTTONINFO, OnTBNGetButtonInfo)
// handle drag'n'drop messages
ON_MESSAGE(SHBDTM_DRAGENTER, OnDragEnter)
ON_MESSAGE(SHBDTM_DRAGLEAVE, OnDragLeave)
ON_MESSAGE(SHBDTM_DRAGOVER, OnDragOver)
ON_MESSAGE(SHBDTM_DROP, OnDrop)
// handle advanced customization commands
ON_COMMAND(ID_OXCUSTTB_DELETE,OnCustTBDelete)
ON_COMMAND(ID_OXCUSTTB_APPEARANCE,OnCustTBAppearance)
ON_COMMAND(ID_OXCUSTTB_IMAGEONLY,OnCustTBImageOnly)
ON_COMMAND(ID_OXCUSTTB_IMAGETEXT,OnCustTBImageText)
ON_COMMAND(ID_OXCUSTTB_SEPARATOR_BEFORE,OnCustTBSeparatorBefore)
ON_COMMAND(ID_OXCUSTTB_SEPARATOR_AFTER,OnCustTBSeparatorAfter)
#if _MFC_VER>=0x0420
// reflect message to provide custom draw functionality
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW,OnCustomDraw)
#endif
ON_NOTIFY_REFLECT_EX(TBN_DROPDOWN, OnDropDownButton)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COXCoolToolBar message handlers
BOOL COXCoolToolBar::Create(CWnd* pParentWnd, DWORD dwStyle, UINT nID)
{
//#if _WIN32_IE>=0x0400
if(m_dwComCtlVersion>=_IE40_COMCTL_VERSION)
{
ASSERT_VALID(pParentWnd); // must have a parent
ASSERT (!((dwStyle & CBRS_SIZE_FIXED) && (dwStyle & CBRS_SIZE_DYNAMIC)));
dwStyle|=WS_CLIPCHILDREN;
#if _MFC_VER<=0x0421
// save the style
m_dwStyle = dwStyle;
if (nID == AFX_IDW_TOOLBAR)
m_dwStyle |= CBRS_HIDE_INPLACE;
dwStyle &= ~CBRS_ALL;
dwStyle |= CCS_NOPARENTALIGN|CCS_NODIVIDER|CCS_NORESIZE;
// by default set flat style
dwStyle|=TBSTYLE_FLAT;
// Initialize bar common controls
static BOOL bInitCoolToolBar = FALSE;
if (!bInitCoolToolBar)
{
INITCOMMONCONTROLSEX sex;
sex.dwSize = sizeof(INITCOMMONCONTROLSEX);
sex.dwICC = ICC_BAR_CLASSES;
InitCommonControlsEx(&sex);
bInitCoolToolBar = TRUE;
}
// Create the CoolToolBar using style and parent.
CRect rc;
rc.SetRectEmpty();
if(CWnd::CreateEx(WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, NULL,
dwStyle, rc.left, rc.top, rc.Width(), rc.Height(),
pParentWnd->m_hWnd, (HMENU)nID))
#else
if(CToolBar::Create(pParentWnd, dwStyle, nID))
#endif
{
#if _MFC_VER>0x0421
// by default set flat style
ModifyStyle(0,TBSTYLE_FLAT|TBSTYLE_TRANSPARENT);
SetBorders(0,0,0,0);
SetDropDownArrow(TRUE);
#else
SendMessage(TB_BUTTONSTRUCTSIZE,sizeof(TBBUTTON));
#endif
if(pParentWnd->IsKindOf(RUNTIME_CLASS(CMDIChildWnd)))
VERIFY(ModifyStyle(TBSTYLE_TRANSPARENT,0));
}
else
return FALSE;
}
//#else
else
{
if(!CToolBar::Create(pParentWnd,dwStyle,nID))
return FALSE;
#if _MFC_VER>=0x0420
// by default set flat style
SetFlat();
#endif //_MFC_VER>=0x0420
}
//#endif //_WIN32_IE>=0x0400
// register OLE Drag'n'Drop
COleDropTarget* pOleDropTarget=GetDropTarget();
ASSERT(pOleDropTarget!=NULL);
if(!pOleDropTarget->Register(this))
{
TRACE(_T("COXCoolToolBar::Create: failed to register the control with COleDropTarget. You've probably forgotten to initialize OLE libraries using AfxOleInit function\n"));
}
// Add empty string
VERIFY(GetToolBarCtrl().AddStrings(_T("\0"))==0);
return TRUE;
}
BOOL COXCoolToolBar::OnNcCreate(LPCREATESTRUCT lpCreateStruct)
{
#if _MFC_VER>=0x0420
if(IsCool())
{
// bypass CToolBar/CControlBar
return (BOOL)Default();
}
else
{
return CToolBar::OnNcCreate(lpCreateStruct);
}
#else
return CToolBar::OnNcCreate(lpCreateStruct);
#endif
}
void COXCoolToolBar::OnNcPaint()
{
CWindowDC dc(this);
// Exclude the client rectangle, but not the gripper
CRect rectWindow, rectClient;
GetWindowRect(rectWindow);
GetClientRect(rectClient);
ClientToScreen(rectClient);
rectClient.OffsetRect(-rectWindow.left, -rectWindow.top);
dc.ExcludeClipRect(rectClient);
CRect rect(0, 0, 0, 0);
GetWindowRect(rect);
rect.OffsetRect(-rect.left, -rect.top);
GetToolbarSkin()->DrawNonClientArea(&dc, rect, this);
#if _MFC_VER>=0x0420
if(IsCool())
{
// bypass CToolBar/CControlBar
Default();
}
else
{
if(IsFlat() && IsGripper())
DrawGripper(dc,rect);
}
#endif
if(m_hIcon!=NULL)
DrawIcon(dc,rect);
DrawInBookedSpace(dc,rect);
}
void COXCoolToolBar::OnPaint()
{
if(m_dwComCtlVersion>=_IE40_COMCTL_VERSION)
{
CToolBar::OnPaint();
}
else
{
// CToolBar has some problems with painting when CToolBar is dockable
// (due to a bug in comctl32.dll version 4.70 which is supplied with IE 3.0)
CRect rectUpdate(0,0,0,0);
GetUpdateRect(&rectUpdate,TRUE);
#if _MFC_VER>=0x0420
if(IsCool())
{
// bypass CToolBar/CControlBar
Default();
}
else
{
if(IsFloating())
{
CToolBar::OnPaint();
}
else
{
Default();
if(!IsFlat())
{
InvalidateRect(&rectUpdate);
CToolBar::OnPaint();
}
}
}
#else
if(IsFloating())
{
CToolBar::OnPaint();
}
else
{
Default();
InvalidateRect(&rectUpdate);
CToolBar::OnPaint();
}
#endif
}
}
BOOL COXCoolToolBar::OnEraseBkgnd(CDC* pDC)
{
if (GetToolbarSkin()->CallOnEraseBkgnd() == TRUE)
return CToolBar::OnEraseBkgnd(pDC);
else
return FALSE;
}
void COXCoolToolBar::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
#if _MFC_VER>=0x0420
if(IsCool())
{
// bypass CToolBar/CControlBar
Default();
// Change the non-client area of CoolToolBar
// to make it look pretty in CoolBar
int nAddIntension=IsFlat() ? 2 : 0;
if(m_dwStyle&CBRS_ORIENT_HORZ)
{
lpncsp->rgrc[0].top+=nAddIntension;
lpncsp->rgrc[0].bottom+=nAddIntension;
}
else
{
lpncsp->rgrc[0].left+=nAddIntension;
lpncsp->rgrc[0].right+=nAddIntension;
}
}
else
{
CToolBar::OnNcCalcSize(bCalcValidRects, lpncsp);
if(IsFlat())
{
// adjust non-client area
#if _MFC_VER<=0x0421
lpncsp->rgrc[0].top+=2;
lpncsp->rgrc[0].bottom+=2;
#endif
// adjust non-client area for gripper at left or top
if(m_dwStyle&CBRS_ORIENT_HORZ)
{
if(IsGripper() && !(m_dwStyle & CBRS_FLOATING))
{
lpncsp->rgrc[0].left+=ID_OXGRIPPER_WIDTH;
}
}
else
{
if(IsGripper() && !(m_dwStyle & CBRS_FLOATING))
{
lpncsp->rgrc[0].top+=ID_OXGRIPPER_WIDTH;
}
}
}
}
#else
CToolBar::OnNcCalcSize(bCalcValidRects, lpncsp);
#endif
if(m_hIcon!=NULL)
{
// adjust non-client area for icon at left or top
if(m_dwStyle&CBRS_ORIENT_HORZ)
{
int nIconWidth=::GetSystemMetrics(SM_CXSMICON);
lpncsp->rgrc[0].left+=nIconWidth+2;
}
else
{
int nIconHeight=::GetSystemMetrics(SM_CYSMICON);
lpncsp->rgrc[0].top+=nIconHeight+2;
}
}
CRect rectBookedSpace(0,0,0,0);
BookSpace(rectBookedSpace,(m_dwStyle&CBRS_ORIENT_HORZ) ? LM_HORZ : 0);
lpncsp->rgrc[0].left+=rectBookedSpace.left;
lpncsp->rgrc[0].right-=rectBookedSpace.right;
lpncsp->rgrc[0].top+=rectBookedSpace.top;
lpncsp->rgrc[0].bottom-=rectBookedSpace.bottom;
}
void COXCoolToolBar::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
#if _MFC_VER>=0x0420
if(IsCool())
{
// bypass CToolBar/CControlBar
Default();
}
else
{
CToolBar::OnWindowPosChanging(lpwndpos);
}
#if _MFC_VER<=0x0421
// TODO: Add your message handler code here
if (IsFlat() && !(lpwndpos->flags & SWP_NOMOVE))
{ // if moved:
CRect rc; // Fill rectangle with..
GetWindowRect(&rc); // ..my (toolbar) rectangle.
CWnd* pParent = GetParent(); // get parent (dock bar/frame) win..
pParent->ScreenToClient(&rc); // .. and convert to parent coords
// Ask parent window to paint the area beneath my old location.
// Typically, this is just solid grey.
//
pParent->InvalidateRect(&rc); // paint old rectangle
// Now paint my non-client area at the new location.
// This is the extra bit of border space surrounding the buttons.
// Without this, you will still have a partial display bug
//
if(m_bWindowsNTRunning)
{
// we need this code on NT systems
// because we've got problem with redrawing
CRect rect;
GetWindowRect(&rect);
// redraw
SetWindowPos(NULL,0,0,rect.Width(),rect.Height(),
SWP_NOMOVE|SWP_NOZORDER|SWP_DRAWFRAME|
SWP_FRAMECHANGED|SWP_NOREDRAW);
}
else
{
PostMessage(WM_NCPAINT);
}
}
#endif // _MFC_VER<=0x0421
#else
CToolBar::OnWindowPosChanging(lpwndpos);
#endif // _MFC_VER>=0x0420
}
void COXCoolToolBar::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos)
{
// TODO: Add your message handler code here
if(m_pDockContext!=NULL)
{
m_pDockContext->m_bDragging=FALSE;
}
CToolBar::OnWindowPosChanged(lpwndpos);
BOOL bFloating=IsFloating();
if(bFloating!=m_bPrevFloating)
{
m_bPrevFloating=bFloating;
OnFloatingDocking(bFloating);
}
else
{
DWORD dwDockSide=GetBarStyle()&CBRS_ALIGN_ANY;
if(m_dwPrevDockSide!=dwDockSide)
{
m_dwPrevDockSide=dwDockSide;
OnChangeDockSide(m_dwPrevDockSide);
}
}
DelayUpdateCustomButtons();
SendMessage(WM_NCPAINT, 0, 0);
}
LRESULT COXCoolToolBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM lParam)
{
if(IsWindowVisible())
{
// redraw the toolbar if necessary
if(m_nIdleFlags & oxidleRedrawToolbar)
{
RedrawToolBar(TRUE,TRUE);
}
if(m_nIdleFlags & oxidleUpdateCustomButtons)
{
UpdateCustomButtons();
}
m_nIdleFlags=0;
}
return CToolBar::OnIdleUpdateCmdUI(wParam,lParam);
}
void COXCoolToolBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
COXCoolToolBarCmdUI state;
state.m_pOther = this;
state.m_nIndexMax = GetToolBarCtrl().GetButtonCount();
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; state.m_nIndex++)
{
// get buttons state
TBBUTTON TB;
GetToolBarCtrl().GetButton(state.m_nIndex, &TB);
state.m_nID = TB.idCommand;
// ignore separators
if (!(TB.fsStyle & TBSTYLE_SEP) || IsCustomButton(state.m_nIndex))
{
// allow the toolbar itself to have update handlers
if (CWnd::OnCmdMsg(state.m_nID, CN_UPDATE_COMMAND_UI, &state, NULL))
continue;
// allow the owner to process the update
state.DoUpdate(pTarget, bDisableIfNoHndler);
}
}
// update any dialog controls added to the toolbar
UpdateDialogControls(pTarget, bDisableIfNoHndler);
}
void COXCoolToolBar::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
UNREFERENCED_PARAMETER(uFlags);
UNREFERENCED_PARAMETER(lpszSection);
m_nDropDownArrowWidth=GetDropDownArrowWidth();
RedrawToolBar();
CToolBar::OnSettingChange(uFlags, lpszSection);
}
// v9.3 - update 03 - 64-bit - return value was declared as LONG - changed to LRESULT
LRESULT COXCoolToolBar::OnDragEnter(WPARAM wParam, LPARAM lParam)
{
// toolbar must be in advanced customizable state
if(!IsCustomizable(TRUE))
return (LONG)FALSE;
// set flag that specifies that drag'n'drop operation is active
m_bDragDropOperation=TRUE;
// lParam is the pointer to SHBDROPTARGETACTION structure
LPSHBDROPTARGETACTION pSHBDTAction=(LPSHBDROPTARGETACTION)lParam;
ASSERT(pSHBDTAction!=NULL);
ASSERT(pSHBDTAction->pWnd);
ASSERT(pSHBDTAction->pWnd->GetSafeHwnd()==GetSafeHwnd());
return OnDragOver(wParam,lParam);
}
// v9.3 - update 03 - 64-bit - return value was declared as LONG - changed to LRESULT
LRESULT COXCoolToolBar::OnDragOver(WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(wParam);
// toolbar must be in advanced customizable state
if(!IsCustomizable(TRUE))
return (LONG)FALSE;
// lParam is the pointer to SHBDROPTARGETACTION structure
LPSHBDROPTARGETACTION pSHBDTAction=(LPSHBDROPTARGETACTION)lParam;
ASSERT(pSHBDTAction!=NULL);
ASSERT(pSHBDTAction->pWnd);
ASSERT(pSHBDTAction->pWnd->GetSafeHwnd()==GetSafeHwnd());
pSHBDTAction->result=(LRESULT)DROPEFFECT_NONE;
#ifdef OX_CUSTOMIZE_COMMANDS
// Can we use this object?
if(pSHBDTAction->pDataObject->
IsDataAvailable(COXDragDropCommands::m_cfCommandButton))
{
BOOL bQualified=!(m_bDragDropOwner &&
(pSHBDTAction->dwKeyState & MK_CONTROL)==MK_CONTROL);
if(bQualified)
{
if(!(m_bDragDropOwner &&
(pSHBDTAction->dwKeyState & MK_CONTROL)!=MK_CONTROL))
{
// Get the drag item info
//
HGLOBAL hgData=pSHBDTAction->pDataObject->
GetGlobalData(COXDragDropCommands::m_cfCommandButton);
ASSERT(hgData!=NULL);
// lock it
BYTE* lpItemData=(BYTE*)::GlobalLock(hgData);
// get button command ID
int nCommandID=*(int*)lpItemData;
lpItemData+=sizeof(int);
// unlock it
::GlobalUnlock(hgData);
// free it
::GlobalFree(hgData);
if(nCommandID<0 || (nCommandID>0 && CommandToIndex(nCommandID)!=-1))
bQualified=FALSE;
}
if(bQualified)
{
// analize the current cursor position
//
CPoint point=pSHBDTAction->point;
int nButtonIndex=HitTest(&point);
BOOL bIsOut=(nButtonIndex<0);
nButtonIndex=(bIsOut ? -nButtonIndex : nButtonIndex);
if(nButtonIndex>GetToolBarCtrl().GetButtonCount() &&
GetToolBarCtrl().GetButtonCount()>0)
{
nButtonIndex=-1;
bQualified=FALSE;
}
else
{
// check if we are really over custom button,
// which is interpreted as separator and never being
// reterned as legitimate value from HitTest() function
CRect rectItem;
GetItemRect(nButtonIndex,rectItem);
if(!rectItem.PtInRect(point))
{
// check if previous button is custom one
if(nButtonIndex>0 && IsCustomButton(nButtonIndex-1))
{
nButtonIndex--;
}
}
CWnd* pParentWnd=GetParent();
ASSERT(pParentWnd!=NULL);
NMTOOLBAR nmtb;
nmtb.hdr.hwndFrom=GetSafeHwnd();
nmtb.hdr.idFrom=GetDlgCtrlID();
nmtb.hdr.code=TBN_QUERYINSERT;
nmtb.iItem=nButtonIndex;
if(!pParentWnd->
SendMessage(WM_NOTIFY,nmtb.hdr.idFrom,(LPARAM)&nmtb))
{
bQualified=FALSE;
}
else
{
TBINSERTMARK tbim;
if(nButtonIndex==GetToolBarCtrl().GetButtonCount() &&
nButtonIndex>0)
{
tbim.iButton=nButtonIndex-1;
tbim.dwFlags=TBIMHT_AFTER;
}
else
{
tbim.iButton=nButtonIndex;
tbim.dwFlags=0;
CRect rectItem;
GetItemRect(tbim.iButton,rectItem);
if(point.x>=rectItem.left+rectItem.Width()/2 || point.x<0)
{
tbim.dwFlags=TBIMHT_AFTER;
}
}
SetInsertMark(&tbim);
// Check if the control key was pressed
if((pSHBDTAction->dwKeyState & MK_CONTROL)==MK_CONTROL)
pSHBDTAction->result=(LRESULT)DROPEFFECT_COPY;
else
pSHBDTAction->result=(LRESULT)DROPEFFECT_MOVE;
}
}
}
}
if(!bQualified)
SetInsertMark(-1);
}
#endif // OX_CUSTOMIZE_COMMANDS
return (LONG)TRUE;
}
// v9.3 - update 03 - 64-bit - return value was declared as LONG - changed to LRESULT
LRESULT COXCoolToolBar::OnDragLeave(WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(wParam);
if(!IsCustomizable(TRUE))
return (LONG)FALSE;
// lParam is the pointer to SHBDROPTARGETACTION structure
LPSHBDROPTARGETACTION pSHBDTAction=(LPSHBDROPTARGETACTION)lParam;
ASSERT(pSHBDTAction!=NULL);
ASSERT(pSHBDTAction->pWnd);
ASSERT(pSHBDTAction->pWnd->GetSafeHwnd()==GetSafeHwnd());
SetInsertMark(-1);
if(!m_bDragDropOwner)
{
// reset flag that specifies that drag'n'drop operation is active
m_bDragDropOperation=FALSE;
}
return (LONG)TRUE;
}
// v9.3 - update 03 - 64-bit - return value was declared as LONG - changed to LRESULT
LRESULT COXCoolToolBar::OnDrop(WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(wParam);
if(!IsCustomizable(TRUE))
return (LONG)FALSE;
// lParam is the pointer to SHBDROPTARGETACTION structure
LPSHBDROPTARGETACTION pSHBDTAction=(LPSHBDROPTARGETACTION)lParam;
ASSERT(pSHBDTAction!=NULL);
ASSERT(pSHBDTAction->pWnd);
ASSERT(pSHBDTAction->pWnd->GetSafeHwnd()==GetSafeHwnd());
pSHBDTAction->result=(LRESULT)FALSE;
#ifdef OX_CUSTOMIZE_COMMANDS
// if dragged item is to be copied or moved
if((pSHBDTAction->dropEffect&DROPEFFECT_COPY)!=0 ||
(pSHBDTAction->dropEffect&DROPEFFECT_MOVE)!=0)
{
// data must be in the specific format
ASSERT(pSHBDTAction->pDataObject->
IsDataAvailable(COXDragDropCommands::m_cfCommandButton));
TBINSERTMARK tbim;
GetInsertMark(&tbim);
int nButtonIndex=tbim.iButton;
if(nButtonIndex!=-1 || GetToolBarCtrl().GetButtonCount()==0)
{
BOOL bButtonRemainsTheSame=FALSE;
if(m_bDragDropOwner && (pSHBDTAction->dropEffect&DROPEFFECT_COPY)==0)
{
ASSERT(GetToolBarCtrl().GetButtonCount()>0);
int nDraggedButtonIndex=GetDraggedButton();
ASSERT(nDraggedButtonIndex!=-1);
if(nDraggedButtonIndex<GetToolBarCtrl().GetButtonCount()-1 &&
((tbim.dwFlags==0 && nButtonIndex==nDraggedButtonIndex) ||
(tbim.dwFlags==TBIMHT_AFTER &&
(nButtonIndex+1)==nDraggedButtonIndex)))
{
if((GetButtonStyle(nDraggedButtonIndex+1)&TBSTYLE_SEP)==0 ||
IsCustomButton(nDraggedButtonIndex+1))
{
TBBUTTON button={ 0 };
button.fsStyle=TBSTYLE_SEP;
button.iString=-1;
button.iBitmap=-1;
VERIFY(GetToolBarCtrl().
InsertButton(nDraggedButtonIndex+1,&button));
}
bButtonRemainsTheSame=TRUE;
}
else if(nDraggedButtonIndex>0 && ((tbim.dwFlags==TBIMHT_AFTER &&
nButtonIndex==nDraggedButtonIndex) ||
(tbim.dwFlags==0 && (nButtonIndex-1)==nDraggedButtonIndex)))
{
if((GetButtonStyle(nDraggedButtonIndex-1)&TBSTYLE_SEP)==0 ||
IsCustomButton(nDraggedButtonIndex-1))
{
TBBUTTON button={ 0 };
button.fsStyle=TBSTYLE_SEP;
button.iString=-1;
button.iBitmap=-1;
VERIFY(GetToolBarCtrl().
InsertButton(nDraggedButtonIndex,&button));
}
bButtonRemainsTheSame=TRUE;
}
else if((nButtonIndex==nDraggedButtonIndex+2 && tbim.dwFlags==0) ||
(nButtonIndex==nDraggedButtonIndex+1 &&
tbim.dwFlags==TBIMHT_AFTER))
{
if((GetButtonStyle(nDraggedButtonIndex+1)&TBSTYLE_SEP)!=0 &&
!IsCustomButton(nDraggedButtonIndex+1))
{
VERIFY(GetToolBarCtrl().DeleteButton(nDraggedButtonIndex+1));
nButtonIndex--;
bButtonRemainsTheSame=TRUE;
}
}
else if((nButtonIndex==nDraggedButtonIndex-2 &&
tbim.dwFlags==TBIMHT_AFTER) ||
(nButtonIndex==nDraggedButtonIndex-1 && tbim.dwFlags==0))
{
if((GetButtonStyle(nDraggedButtonIndex-1)&TBSTYLE_SEP)!=0 &&
!IsCustomButton(nDraggedButtonIndex-1))
{
VERIFY(GetToolBarCtrl().DeleteButton(nDraggedButtonIndex-1));
bButtonRemainsTheSame=TRUE;
}
}
}
// remove insert mark
SetInsertMark(-1);
if(bButtonRemainsTheSame)
{
m_bDragDropOperation=FALSE;
pSHBDTAction->result=(LRESULT)TRUE;
return (LONG)TRUE;
}
nButtonIndex=(tbim.dwFlags==0 ? nButtonIndex : nButtonIndex+1);
int nButtonCount=GetToolBarCtrl().GetButtonCount();
if(nButtonIndex==-1)
{
ASSERT(nButtonCount==0 && !m_bDragDropOwner);
nButtonIndex=0;
}
else if(nButtonIndex>nButtonCount)
{
nButtonIndex=nButtonCount;
}
if(m_bDragDropOwner)
{
#if _MFC_VER<0x0420
if(!IsCustomButton(GetDraggedButton()))
#endif
{
int nOldButtonPos=GetDraggedButton();
int nNewButtonPos=(nButtonIndex>GetDraggedButton() ?
nButtonIndex-1 : nButtonIndex);
if(nOldButtonPos!=nNewButtonPos)
{
// just move button
VERIFY(MoveButton(nOldButtonPos,nNewButtonPos));
SetCustomizedButton(nNewButtonPos);
}
m_bDragDropOperation=FALSE;
pSHBDTAction->result=(LRESULT)TRUE;
return (LONG)TRUE;
}
}
// Get the drag item info
//
HGLOBAL hgData=pSHBDTAction->pDataObject->
GetGlobalData(COXDragDropCommands::m_cfCommandButton);
ASSERT(hgData!=NULL);
// lock it
BYTE* lpItemData=(BYTE*)::GlobalLock(hgData);
// get button command ID
int nCommandID=*(int*)lpItemData;
lpItemData+=sizeof(int);
// get button text
CString sText((LPTSTR)lpItemData);
lpItemData+=sText.GetLength()*sizeof(TCHAR)+sizeof(TCHAR);
int nPosition=sText.Find(_T('\t'));
if(nPosition!=-1)
sText=sText.Left(nPosition);
// get button image index
int nImageIndex=*(int*)lpItemData;
lpItemData+=sizeof(int);
// get button style
BYTE fsStyle=*(BYTE*)lpItemData;
lpItemData+=sizeof(BYTE);
if(nCommandID>0 || (nCommandID==0 && nButtonCount>0))
{
// determine if dragged button is a custom one
BOOL bCustomButton=(GetCustomButtonIndex(nCommandID)!=-1);
if(!bCustomButton)
{
// insert new button
//
TBBUTTON button={ 0 };
button.iBitmap=nImageIndex;
button.idCommand=nCommandID;
if((fsStyle&TBSTYLE_SEP)==TBSTYLE_SEP)
fsStyle&=~TBSTYLE_AUTOSIZE;
else
fsStyle|=TBSTYLE_AUTOSIZE;
button.fsStyle=fsStyle;
button.iString=-1;
// don't redraw the toolbar contents, we will do it later
m_bNoInternalRedraw=TRUE;
VERIFY(GetToolBarCtrl().InsertButton(nButtonIndex,&button));
m_bNoInternalRedraw=FALSE;
if(!sText.IsEmpty())
{
VERIFY(SetButtonText(nButtonIndex,sText));
}
RedrawToolBar(TRUE,TRUE);
//////////////////////////////
}
else
{
int nCustomButtonIndex=GetCustomButtonIndex(nCommandID);
ASSERT(nCustomButtonIndex!=-1);
// insert new custom button
VERIFY(InsertCustomButton(nButtonIndex,nCustomButtonIndex));
if(IsInAdvancedCustomizationMode())
{
// set it into customization mode
OXCUSTOMBUTTONDESCRIPTOR descriptor;
VERIFY(GetCustomButton(nButtonIndex,descriptor));
descriptor.m_pCBTemplate->CBSetCustomizationMode(TRUE);
}
}
}
// unlock it
::GlobalUnlock(hgData);
// free it
::GlobalFree(hgData);
// drag'n'drop operation completed successfully
pSHBDTAction->result=(LRESULT)TRUE;
}
else
{
pSHBDTAction->result=(LRESULT)FALSE;
}
}
#endif // OX_CUSTOMIZE_COMMANDS
m_bDragDropOperation=FALSE;
// we handled the message
return (LONG)TRUE;
}
LRESULT COXCoolToolBar::OnInsertButton(WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
LRESULT lResult=Default();
if((BOOL)lResult)
{
CRect rect;
GetClientRect(rect);
ValidateRect(rect);
if((int)wParam<=m_nCustomizedButtonIndex)
{
SetCustomizedButton(m_nCustomizedButtonIndex+1);
}
if((int)wParam<=m_nDraggedButtonIndex)
{
SetDraggedButton(m_nDraggedButtonIndex+1);
}
// update custom buttons positions
for(int nButtonIndex=GetToolBarCtrl().GetButtonCount()-2;
nButtonIndex>=(int)wParam; nButtonIndex--)
{
OXCUSTOMBUTTONDESCRIPTOR descriptor;
if(m_mapCustomButtons.Lookup(nButtonIndex,descriptor))
{
m_mapCustomButtons.SetAt(nButtonIndex+1,descriptor);
m_mapCustomButtons.RemoveKey(nButtonIndex);
}
}
}
RedrawToolBar(TRUE,TRUE);
return lResult;
}
LRESULT COXCoolToolBar::OnDeleteButton(WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
LRESULT lResult=Default();
if((BOOL)lResult)
{
CRect rect;
GetClientRect(rect);
ValidateRect(rect);
int nButtonIndex=(int)wParam;
// delete custom button if any found
OXCUSTOMBUTTONDESCRIPTOR descriptor;
if(GetCustomButton(nButtonIndex,descriptor))
{
descriptor.m_pCBTemplate->CBDelete();
m_mapCustomButtons.RemoveKey(nButtonIndex);
}
// update custom buttons positions
for(int nIndex=nButtonIndex+1;
nIndex<=GetToolBarCtrl().GetButtonCount(); nIndex++)
{
OXCUSTOMBUTTONDESCRIPTOR descriptor;
if(m_mapCustomButtons.Lookup(nIndex,descriptor))
{
m_mapCustomButtons.SetAt(nIndex-1,descriptor);
m_mapCustomButtons.RemoveKey(nIndex);
}
}
if(nButtonIndex<m_nCustomizedButtonIndex)
SetCustomizedButton(m_nCustomizedButtonIndex-1);
else if(nButtonIndex==m_nCustomizedButtonIndex)
SetCustomizedButton(-1);
if(nButtonIndex<m_nDraggedButtonIndex)
SetDraggedButton(m_nDraggedButtonIndex-1);
else if(nButtonIndex==m_nDraggedButtonIndex)
SetDraggedButton(-1);
int nButtonCount=GetToolBarCtrl().GetButtonCount();
if(nButtonIndex==nButtonCount && nButtonCount>0 &&
GetButtonStyle(nButtonCount-1)&TBBS_SEPARATOR &&
!IsCustomButton(nButtonCount-1))
{
m_bNoInternalRedraw=TRUE;
VERIFY(GetToolBarCtrl().DeleteButton(nButtonCount-1));
m_bNoInternalRedraw=FALSE;
}
nButtonCount=GetToolBarCtrl().GetButtonCount();
if(nButtonIndex==0 && nButtonCount>0 &&
GetButtonStyle(0)&TBBS_SEPARATOR && !IsCustomButton(0))
{
m_bNoInternalRedraw=TRUE;
VERIFY(GetToolBarCtrl().DeleteButton(0));
m_bNoInternalRedraw=FALSE;
}
}
RedrawToolBar(TRUE,TRUE);
return lResult;
}
#if _MFC_VER>=0x0420
LRESULT COXCoolToolBar::OnMoveButton(WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
LRESULT lResult=Default();
if((BOOL)lResult && (int)wParam!=(int)lParam)
{
OXCUSTOMBUTTONDESCRIPTOR descriptorMoved;
BOOL bCustomButton=GetCustomButton((int)wParam,descriptorMoved);
BOOL bDeleteMovedDescriptor=FALSE;
int nMinButtonIndex=__min((int)wParam,(int)lParam);
int nMaxButtonIndex=__max((int)wParam,(int)lParam);
// update custom buttons positions
if((int)wParam<(int)lParam)
{
bDeleteMovedDescriptor=
bCustomButton && !IsCustomButton(nMinButtonIndex+1);
for(int nIndex=nMinButtonIndex+1;
nIndex<=nMaxButtonIndex; nIndex++)
{
OXCUSTOMBUTTONDESCRIPTOR descriptor;
if(m_mapCustomButtons.Lookup(nIndex,descriptor))
{
m_mapCustomButtons.SetAt(nIndex-1,descriptor);
m_mapCustomButtons.RemoveKey(nIndex);
}
}
if(bCustomButton)
{
m_mapCustomButtons.SetAt(nMaxButtonIndex,descriptorMoved);
if(bDeleteMovedDescriptor)
{
m_mapCustomButtons.RemoveKey(nMinButtonIndex);
}
}
}
else
{
bDeleteMovedDescriptor=
bCustomButton && !IsCustomButton(nMaxButtonIndex-1);
for(int nIndex=nMaxButtonIndex-1;
nIndex>=nMinButtonIndex; nIndex--)
{
OXCUSTOMBUTTONDESCRIPTOR descriptor;
if(m_mapCustomButtons.Lookup(nIndex,descriptor))
{
m_mapCustomButtons.SetAt(nIndex+1,descriptor);
m_mapCustomButtons.RemoveKey(nIndex);
}
}
if(bCustomButton)
{
m_mapCustomButtons.SetAt(nMinButtonIndex,descriptorMoved);
if(bDeleteMovedDescriptor)
{
m_mapCustomButtons.RemoveKey(nMaxButtonIndex);
}
}
}
UpdateCustomButtons(nMinButtonIndex,nMaxButtonIndex);
}
return lResult;
}
#endif
void COXCoolToolBar::OnLButtonDown(UINT nFlags, CPoint point)
{
if(IsInAdvancedCustomizationMode() && IsCustomizable(TRUE))
{
int nButtonIndex=HitTest(&point);
if(nButtonIndex>=0 && nButtonIndex<GetToolBarCtrl().GetButtonCount())
{
SetCustomizedButton(nButtonIndex);
}
else
{
if(IsCustomButton(-nButtonIndex-1))
{
SetCustomizedButton(-nButtonIndex-1);
}
else
{
SetCustomizedButton(-1);
}
}
CWnd::OnLButtonDown(nFlags,point);
if(nButtonIndex>=0 && nButtonIndex<GetToolBarCtrl().GetButtonCount())
{
int nState=GetToolBarCtrl().GetState(GetItemID(nButtonIndex));
if((nState&TBSTATE_PRESSED)!=0)
{
GetToolBarCtrl().SetState(GetItemID(nButtonIndex),
nState&~TBSTATE_PRESSED);
}
}
return;
}
if (IsFloatingEnabled() || (!IsFloatingEnabled() && HitTest(&point) >= 0))
{
if (AfxGetMainWnd()->SendMessage(WM_QUERYSNAPPING))
{
// only start dragging if clicked in "void" space
if (m_pDockBar != NULL && OnToolHitTest(point, NULL) == -1)
{
// Start dragging
SaveMouseOffset(point);
m_bDragging = TRUE;
SetCapture();
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL));
}
else
{
CWnd::OnLButtonDown(nFlags, point);
}
}
else
CToolBar::OnLButtonDown(nFlags, point);
}
}
void COXCoolToolBar::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_bDragging)
{
ReleaseCapture();
m_bDragging = FALSE;
return;
}
if(IsInAdvancedCustomizationMode() && IsCustomizable(TRUE))
{
return;
}
CToolBar::OnLButtonUp(nFlags,point);
// update the state of the clicked button right away
if(::IsWindow(GetSafeHwnd()))
{
SendMessage(WM_IDLEUPDATECMDUI);
}
}
void COXCoolToolBar::OnMButtonDown(UINT nFlags, CPoint point)
{
if(IsInAdvancedCustomizationMode() && IsCustomizable(TRUE))
{
int nButtonIndex=HitTest(&point);
if(nButtonIndex>=0 && nButtonIndex<GetToolBarCtrl().GetButtonCount())
{
SetCustomizedButton(nButtonIndex);
}
else
{
if(IsCustomButton(-nButtonIndex-1))
{
SetCustomizedButton(-nButtonIndex-1);
}
else
{
SetCustomizedButton(-1);
}
}
return;
}
CToolBar::OnMButtonDown(nFlags,point);
}
void COXCoolToolBar::OnRButtonDown(UINT nFlags, CPoint point)
{
if(IsInAdvancedCustomizationMode() && IsCustomizable(TRUE))
{
int nButtonIndex=HitTest(&point);
if(nButtonIndex>=0 && nButtonIndex<GetToolBarCtrl().GetButtonCount())
{
SetCustomizedButton(nButtonIndex);
}
else
{
if(IsCustomButton(-nButtonIndex-1))
{
SetCustomizedButton(-nButtonIndex-1);
}
else
{
SetCustomizedButton(-1);
}
}
return;
}
CToolBar::OnRButtonDown(nFlags,point);
}
void COXCoolToolBar::OnRButtonUp(UINT nFlags, CPoint point)
{
if(IsInAdvancedCustomizationMode() && IsCustomizable(TRUE))
{
int nCustomizedButtonIndex=GetCustomizedButton();
if(nCustomizedButtonIndex!=-1)
{
ClientToScreen(&point);
VERIFY(DisplayCustomizeButtonContextMenu(nCustomizedButtonIndex,point));
return;
}
}
CToolBar::OnRButtonUp(nFlags,point);
}
void COXCoolToolBar::OnMouseMove(UINT nFlags, CPoint point)
{
if(IsInAdvancedCustomizationMode() && IsCustomizable(TRUE))
{
return;
}
if (m_bDragging)
{
// Make sure the mouse button is still down
if (::GetKeyState(VK_LBUTTON) >= 0)
{
// No longer down
ReleaseCapture();
m_bDragging = FALSE;
return;
}
CPoint ptScreen = point;
ClientToScreen(&point);
CRect rectWindow;
GetWindowRect(rectWindow);
CRect rectDock(point.x, point.y, point.x + rectWindow.Width(), point.y + rectWindow.Height());
// Get the appropriate dock bar. If one is not found then float.
CFrameWnd* pFrameWnd = DYNAMIC_DOWNCAST(CFrameWnd, ::AfxGetMainWnd());
if (pFrameWnd == NULL)
{
ReleaseCapture();
m_bDragging = FALSE;
return;
}
// Handle pending WM_PAINT messages
MSG msg;
while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
{
if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
{
ReleaseCapture();
m_bDragging = FALSE;
return;
}
DispatchMessage(&msg);
}
if (m_pDockContext == NULL)
pFrameWnd->FloatControlBar(this, point);
else
{
COXSizeDockBar* pDockBar = COXSizeDockBar::GetAppropriateDockBar(point, this);
if (pDockBar == NULL || nFlags & MK_CONTROL)
pFrameWnd->FloatControlBar(this, point - m_ptOffset);
else
pDockBar->DockControlBar(this, rectDock);
}
}
else
CToolBar::OnMouseMove(nFlags,point);
}
void COXCoolToolBar::OnLButtonDblClk(UINT nFlags, CPoint point)
{
if(IsInAdvancedCustomizationMode() && IsCustomizable(TRUE))
{
return;
}
if (!IsFloatingEnabled())
{
if (HitTest(&point) >= 0)
CToolBar::OnLButtonDblClk(nFlags,point);
}
else
CToolBar::OnLButtonDblClk(nFlags,point);
}
int COXCoolToolBar::SetCustomizedButton(int nIndex)
{
int nOldCustomizedButtonIndex=m_nCustomizedButtonIndex;
m_nCustomizedButtonIndex=nIndex;
if(nOldCustomizedButtonIndex!=nIndex)
{
RedrawButton(nOldCustomizedButtonIndex);
}
if(nIndex!=-1)
{
int nState=GetToolBarCtrl().GetState(GetItemID(nIndex));
if((nState&TBSTATE_PRESSED)!=0)
{
GetToolBarCtrl().SetState(GetItemID(nIndex),nState&~TBSTATE_PRESSED);
}
else
{
RedrawButton(nIndex);
}
}
SendCustomizeNotification(ID_OXCUSTTB_SET_CUSTOMIZE_BUTTON);
return nOldCustomizedButtonIndex;
}
BOOL COXCoolToolBar::DisplayCustomizeButtonContextMenu(int nButtonIndex, CPoint point)
{
ASSERT(::IsWindow(GetSafeHwnd()));
ASSERT(nButtonIndex>=0 && nButtonIndex<GetToolBarCtrl().GetButtonCount());
CString sText=GetButtonText(nButtonIndex);
TBBUTTON button;
VERIFY(GetToolBarCtrl().GetButton(nButtonIndex,&button));
ASSERT((button.fsStyle&TBSTYLE_SEP)==0 || IsCustomButton(nButtonIndex));
ASSERT(!(sText.IsEmpty() && button.iBitmap==-1));
CMenu menu;
if(!menu.CreatePopupMenu())
return FALSE;
// populate menu
CString sItem;
sItem.LoadString(IDS_OX_CUSTTB_DELETE);
VERIFY(menu.AppendMenu(MF_STRING,ID_OXCUSTTB_DELETE,sItem));
VERIFY(menu.AppendMenu(MF_SEPARATOR));
sItem.LoadString(IDS_OX_CUSTTB_APPEARANCE);
VERIFY(menu.AppendMenu(MF_STRING,ID_OXCUSTTB_APPEARANCE,sItem));
if((button.fsStyle&TBSTYLE_SEP)==0 && !IsCustomButton(nButtonIndex))
{
sItem.LoadString(IDS_OX_CUSTTB_IMAGEONLY);
VERIFY(menu.AppendMenu(MF_STRING|(sText.IsEmpty() ? MF_CHECKED : MF_UNCHECKED),
ID_OXCUSTTB_IMAGEONLY,sItem));
sItem.LoadString(IDS_OX_CUSTTB_IMAGETEXT);
VERIFY(menu.AppendMenu(MF_STRING|(!sText.IsEmpty() && button.iBitmap!=-1 ?
MF_CHECKED : MF_UNCHECKED),ID_OXCUSTTB_IMAGETEXT,sItem));
}
VERIFY(menu.AppendMenu(MF_SEPARATOR));
sItem.LoadString(IDS_OX_CUSTTB_SEPARATOR_BEFORE);
VERIFY(menu.AppendMenu(MF_STRING|
((nButtonIndex>0 && ((GetButtonStyle(nButtonIndex-1)&TBBS_SEPARATOR)==0 ||
IsCustomButton(nButtonIndex-1))) ? 0 : MF_GRAYED),
ID_OXCUSTTB_SEPARATOR_BEFORE,sItem));
sItem.LoadString(IDS_OX_CUSTTB_SEPARATOR_AFTER);
VERIFY(menu.AppendMenu(MF_STRING|
((nButtonIndex<GetToolBarCtrl().GetButtonCount()-1 &&
((GetButtonStyle(nButtonIndex+1)&TBBS_SEPARATOR)==0 ||
IsCustomButton(nButtonIndex+1))) ? 0 : MF_GRAYED),
ID_OXCUSTTB_SEPARATOR_AFTER,sItem));
menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
point.x,point.y,this);
return TRUE;
}
void COXCoolToolBar::OnCustTBDelete()
{
ASSERT(IsInAdvancedCustomizationMode());
int nCustomizedButtonIndex=GetCustomizedButton();
ASSERT(nCustomizedButtonIndex!=-1);
if(SendCustomizeNotification(ID_OXCUSTTB_DELETE))
return;
VERIFY(GetToolBarCtrl().DeleteButton(nCustomizedButtonIndex));
}
void COXCoolToolBar::OnCustTBAppearance()
{
ASSERT(IsInAdvancedCustomizationMode());
int nCustomizedButtonIndex=GetCustomizedButton();
ASSERT(nCustomizedButtonIndex!=-1);
UNUSED(nCustomizedButtonIndex);
SendCustomizeNotification(ID_OXCUSTTB_APPEARANCE);
}
void COXCoolToolBar::OnCustTBImageOnly()
{
ASSERT(IsInAdvancedCustomizationMode());
int nCustomizedButtonIndex=GetCustomizedButton();
ASSERT(nCustomizedButtonIndex!=-1);
if(SendCustomizeNotification(ID_OXCUSTTB_IMAGEONLY))
return;
UINT nCommandID=GetItemID(nCustomizedButtonIndex);
#ifdef _DEBUG
TBBUTTON button;
VERIFY(GetToolBarCtrl().GetButton(nCustomizedButtonIndex,&button));
ASSERT(button.iBitmap!=-1);
#endif
CString sText=GetButtonText(nCustomizedButtonIndex);
if(!sText.IsEmpty())
{
m_mapButtonText.SetAt(nCommandID,sText);
SetButtonText(nCustomizedButtonIndex,_T(""));
RedrawToolBar(TRUE,TRUE);
}
}
void COXCoolToolBar::OnCustTBImageText()
{
ASSERT(IsInAdvancedCustomizationMode());
int nCustomizedButtonIndex=GetCustomizedButton();
ASSERT(nCustomizedButtonIndex!=-1);
if(SendCustomizeNotification(ID_OXCUSTTB_IMAGETEXT))
return;
UINT nCommandID=GetItemID(nCustomizedButtonIndex);
#ifdef _DEBUG
TBBUTTON button;
VERIFY(GetToolBarCtrl().GetButton(nCustomizedButtonIndex,&button));
ASSERT(button.iBitmap!=-1);
#endif
CString sText=GetButtonText(nCustomizedButtonIndex);
if(sText.IsEmpty())
{
if(!m_mapButtonText.Lookup(nCommandID,sText))
{
HINSTANCE hInstance=
AfxFindResourceHandle(MAKEINTRESOURCE(nCommandID),RT_STRING);
ASSERT(hInstance!=NULL);
sText.LoadString(nCommandID);
int nPosition=sText.Find(_T('\n'));
if(nPosition!=-1)
sText=sText.Mid(nPosition+1);
}
if(!sText.IsEmpty())
{
SetButtonText(nCustomizedButtonIndex,sText);
RedrawToolBar(TRUE,TRUE);
}
}
}
void COXCoolToolBar::OnCustTBSeparatorBefore()
{
ASSERT(IsInAdvancedCustomizationMode());
int nCustomizedButtonIndex=GetCustomizedButton();
ASSERT(nCustomizedButtonIndex!=-1);
if(SendCustomizeNotification(ID_OXCUSTTB_SEPARATOR_BEFORE))
return;
TBBUTTON button={ 0 };
button.fsStyle=TBSTYLE_SEP;
button.iString=-1;
button.iBitmap=-1;
VERIFY(GetToolBarCtrl().
InsertButton(nCustomizedButtonIndex,&button));
}
void COXCoolToolBar::OnCustTBSeparatorAfter()
{
ASSERT(IsInAdvancedCustomizationMode());
int nCustomizedButtonIndex=GetCustomizedButton();
ASSERT(nCustomizedButtonIndex!=-1);
if(SendCustomizeNotification(ID_OXCUSTTB_SEPARATOR_AFTER))
return;
TBBUTTON button={ 0 };
button.fsStyle=TBSTYLE_SEP;
button.iString=-1;
button.iBitmap=-1;
VERIFY(GetToolBarCtrl().
InsertButton(nCustomizedButtonIndex+1,&button));
}
LRESULT COXCoolToolBar::SendCustomizeNotification(UINT nCustomizeCmdID,
LPARAM lParam/*=NULL*/)
{
HWND hWnd=m_hWndCustomizeOrganizer;
if(hWnd==NULL)
{
hWnd=::GetParent(GetSafeHwnd());
}
if(hWnd==NULL)
return (LRESULT)0;
NMCTBCUSTOMIZE nmctbCustomize;
nmctbCustomize.nmhdr.code=OXCTBN_CUSTOMIZECMD;
nmctbCustomize.nmhdr.hwndFrom=GetSafeHwnd();
nmctbCustomize.nmhdr.idFrom=GetDlgCtrlID();
nmctbCustomize.nCustomizeEventID=nCustomizeCmdID;
nmctbCustomize.lParam=lParam;
return ::SendMessage(hWnd,WM_NOTIFY,(WPARAM)nmctbCustomize.nmhdr.idFrom,
(LPARAM)&nmctbCustomize);
}
CString COXCoolToolBar::GetRecentButtonText(UINT nCommandID)
{
CString sText(_T(""));
m_mapButtonText.Lookup(nCommandID,sText);
return sText;
}
#if _MFC_VER>=0x0420
////////////////////
void COXCoolToolBar::EraseNonClient()
{
// get window DC that is clipped to the non-client area
CWindowDC dc(this);
CRect rectClient;
GetClientRect(rectClient);
CRect rectWindow;
GetWindowRect(rectWindow);
ScreenToClient(rectWindow);
rectClient.OffsetRect(-rectWindow.left, -rectWindow.top);
rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);
// draw borders in non-client area
if(!IsCool())
{
// only if CoolToolBar is not used in CoolBar
DrawBorders(&dc, rectWindow);
// fixing for spurious edges
if((m_dwStyle&CBRS_BORDER_3D)==0)
{
rectWindow.InflateRect(1,1);
}
}
// erase parts not drawn
dc.IntersectClipRect(rectWindow);
dc.ExcludeClipRect(rectClient);
SendMessage(WM_ERASEBKGND, (WPARAM) dc.m_hDC);
}
void COXCoolToolBar::DrawGripper(CDC& dc, CRect& rect)
{
GetToolbarSkin()->DrawGripper(&dc, rect, this);
}
void COXCoolToolBar::DrawSeparator(CDC& dc, CRect& rc)
{
GetToolbarSkin()->DrawSeparator(&dc, rc, this);
}
void COXCoolToolBar::DrawIcon(CDC& dc, CRect& rect)
{
if(m_hIcon==NULL)
return;
m_iconRect=rect;
if(m_dwStyle&CBRS_ORIENT_HORZ)
{
if(m_iconRect.left==0 && !IsFloating())
{
m_iconRect.left += 10;
m_iconRect.top=(rect.Height()-::GetSystemMetrics(SM_CYSMICON))/2;
}
else
{
m_iconRect.left += 3;
m_iconRect.top = 3;
}
m_iconRect.right=m_iconRect.left+::GetSystemMetrics(SM_CXSMICON);
m_iconRect.bottom=m_iconRect.top+::GetSystemMetrics(SM_CYSMICON);
rect.left=m_iconRect.right+1;
}
else
{
if(m_iconRect.top==0 && !IsFloating())
m_iconRect.top += 10;
else
m_iconRect.top += 3;
m_iconRect.bottom=m_iconRect.top+::GetSystemMetrics(SM_CYSMICON);
m_iconRect.left=(rect.Width()-::GetSystemMetrics(SM_CXSMICON))/2;
m_iconRect.right=m_iconRect.left+::GetSystemMetrics(SM_CXSMICON);
rect.top=m_iconRect.bottom+1;
}
::DrawIconEx(dc,m_iconRect.left,m_iconRect.top,m_hIcon,
m_iconRect.Width(),m_iconRect.Height(),0,NULL,DI_NORMAL);
}
void COXCoolToolBar::DrawCustomizedButton(CDC& dc, CRect& rect)
{
GetToolbarSkin()->DrawCustomizedButton(&dc, rect, this);
}
void COXCoolToolBar::SetDropDownArrow(BOOL bDropDownArrow)
{
if(m_dwComCtlVersion>=_IE40_COMCTL_VERSION)
{
DWORD dwStyleEx=GetStyleEx();
dwStyleEx=bDropDownArrow ? dwStyleEx|TBSTYLE_EX_DRAWDDARROWS :
dwStyleEx&~TBSTYLE_EX_DRAWDDARROWS;
SetStyleEx(dwStyleEx);
}
m_bDropDownArrow=bDropDownArrow;
}
BOOL COXCoolToolBar::IsDropDownArrow() const
{
if(m_dwComCtlVersion>=_IE40_COMCTL_VERSION)
{
return GetStyleEx()&TBSTYLE_EX_DRAWDDARROWS ? TRUE : FALSE;
}
return m_bDropDownArrow;
}
////////////////////
#endif
void COXCoolToolBar::SetCustomizable(BOOL bCustomizable/*=TRUE*/,
BOOL bAdvanced/*=TRUE*/)
{
// set CoolToolBar customizable only if array of bitmap IDs was previously set
// by function SetBitmapIds()
if(m_pBitmapIds==NULL)
{
bCustomizable=FALSE;
}
if(bCustomizable && !bAdvanced)
ModifyStyle(0,CCS_ADJUSTABLE);
else
ModifyStyle(CCS_ADJUSTABLE,0);
m_bAdvancedCutomizable=bCustomizable&bAdvanced;
}
void COXCoolToolBar::SetBitmapIds(UINT* pIds, int nButtons)
{
m_pBitmapIds=pIds;
m_nBitmapButtons=nButtons;
// if we call this function then we probably want our CoolToolBar
// to be customizable
SetCustomizable();
}
int COXCoolToolBar::FindBitmapIndex(UINT nID) const
{
// helper function to find the number of element in array of bitmap IDs
// by its ID
ASSERT(m_pBitmapIds != NULL);
for (int i = 0; i < m_nBitmapButtons ; i++)
{
if (m_pBitmapIds[i] == (int)nID)
return i;
}
return -1;
}
void COXCoolToolBar::SetAdvancedCustomizationMode(BOOL bInAdvancedCustomizationMode,
HWND hWndCustomizeOrganizer/*=NULL*/)
{
if(bInAdvancedCustomizationMode && !IsCustomizable(TRUE))
{
SetCustomizable(TRUE,TRUE);
}
if(!bInAdvancedCustomizationMode)
{
SetCustomizedButton(-1);
}
m_hWndCustomizeOrganizer=hWndCustomizeOrganizer;
m_bInAdvancedCustomizationMode=bInAdvancedCustomizationMode;
// reset the customization mode for custom button windows
POSITION pos=m_mapCustomButtons.GetStartPosition();
while(pos!=NULL)
{
int nIndex=-1;
OXCUSTOMBUTTONDESCRIPTOR descriptor;
m_mapCustomButtons.GetNextAssoc(pos,nIndex,descriptor);
ASSERT(nIndex>=0 && nIndex<GetToolBarCtrl().GetButtonCount());
descriptor.m_pCBTemplate->CBSetCustomizationMode(bInAdvancedCustomizationMode);
}
}
// Return information for bitmap indexes in the toolbar
BOOL COXCoolToolBar::OnTBNGetButtonInfo(NMHDR* pNMHDR, LRESULT* pResult)
{
TBNOTIFY* pTBN=(TBNOTIFY*)pNMHDR;
int nIndex=pTBN->iItem;
if(nIndex<m_nBitmapButtons)
{
*pResult=TRUE;
// find button's ID by its image index
UINT nButtonId=m_pBitmapIds[nIndex];
pTBN->tbButton.iBitmap=nIndex;
pTBN->tbButton.idCommand=nButtonId;
pTBN->tbButton.fsState=TBSTATE_ENABLED;
pTBN->tbButton.fsStyle=TBSTYLE_BUTTON;
pTBN->tbButton.iString=-1;
// use as tooltip as text associated with button shown in Customize dialog
if(pTBN->pszText!=NULL)
{
CString strText;
if(strText.LoadString(nButtonId))
{
// tool tip is after "\n" in the string
LPCTSTR pTipText=_tcschr(strText,_T('\n'));
if(pTipText!=NULL)
{
const int len = (int)_tcslen(pTipText+1);
UTBStr::tcsncpy(pTBN->pszText,len+1,pTipText+1,len);
return TRUE;
}
}
TRACE(_T("COXCoolToolBar:No Tooltip prompt for ID=%d\n"),nButtonId);
UTBStr::tcsncpy(pTBN->pszText,4,_T("???"),3);
}
}
else
{
*pResult=FALSE;
}
return TRUE;
}
BOOL COXCoolToolBar::OnTBNBeginDrag(NMHDR* pNMHDR, LRESULT* pResult)
{
NMTOOLBAR* pNMToolBar=(NMTOOLBAR*)pNMHDR;
BOOL bCustomButton=IsCustomButtonWnd(pNMToolBar->iItem);
int nIndex=(!bCustomButton ? CommandToIndex(pNMToolBar->iItem) :
GetCustomButtonPosition(pNMToolBar->iItem));
ASSERT((nIndex>=0 && nIndex<GetToolBarCtrl().GetButtonCount()));
#ifdef OX_CUSTOMIZE_COMMANDS
if(IsInAdvancedCustomizationMode() || (IsCustomizable(TRUE) &&
((GetStyle()&TBSTYLE_ALTDRAG && ::GetKeyState(VK_MENU)<0) ||
(!(GetStyle()&TBSTYLE_ALTDRAG) && ::GetKeyState(VK_SHIFT)<0))))
{
if(!bCustomButton)
{
int nState=GetToolBarCtrl().GetState(GetItemID(nIndex));
if((nState&TBSTATE_PRESSED)!=0)
{
GetToolBarCtrl().SetState(GetItemID(nIndex),nState&~TBSTATE_PRESSED);
}
}
CWnd* pParentWnd=GetParent();
ASSERT(pParentWnd!=NULL);
pNMToolBar->hdr.code=TBN_QUERYDELETE;
if(pParentWnd->
SendMessage(WM_NOTIFY,pNMToolBar->hdr.idFrom,(LPARAM)pNMToolBar))
{
BOOL bWasInAdvancedCustomizationMode=IsInAdvancedCustomizationMode();
if(GetCustomizedButton()!=nIndex)
{
SetCustomizedButton(nIndex);
}
SetDraggedButton(nIndex);
// mark the control as the one that launched drag'n'drop operation
m_bDragDropOwner=TRUE;
TBBUTTON button;
VERIFY(GetToolBarCtrl().GetButton(nIndex,&button));
COleDataSource* pDataSource=
COXDragDropCommands::PrepareDragDropData(GetButtonText(nIndex),
button.iBitmap,button.idCommand,button.fsStyle);
ASSERT(pDataSource!=NULL);
// analyze current mouse position
CPoint ptMouse;
::GetCursorPos(&ptMouse);
CRect rectWindow;
GetWindowRect(rectWindow);
if(!rectWindow.PtInRect(ptMouse))
{
m_bDragDropOperation=TRUE;
}
DROPEFFECT dropEffect=
COXDragDropCommands::DoDragDrop(pDataSource,GetDropSource());
if((DROPEFFECT_MOVE==dropEffect && m_bDragDropOperation) ||
(DROPEFFECT_NONE==dropEffect && ::GetKeyState(VK_LBUTTON)>=0 &&
m_bDragDropOperation))
{
int nDraggedButtonIndex=GetDraggedButton();
OnRemoveDraggedButton(nDraggedButtonIndex);
}
SetDraggedButton(-1);
m_bDragDropOperation=FALSE;
//delete drag source (we are responsible to do that)
delete pDataSource;
// unmark as the control which launched drag'n'drop operation
m_bDragDropOwner=FALSE;
if(!bWasInAdvancedCustomizationMode)
{
SetCustomizedButton(-1);
}
}
}
#else
UNREFERENCED_PARAMETER(nIndex);
#endif // OX_CUSTOMIZE_COMMANDS
*pResult=0;
return FALSE;
}
BOOL COXCoolToolBar::OnTBNEndDrag(NMHDR* pNMHDR, LRESULT* pResult)
{
NMTOOLBAR* pNMToolBar=(NMTOOLBAR*)pNMHDR;
UNREFERENCED_PARAMETER(pNMToolBar);
*pResult=0;
return FALSE;
}
BOOL COXCoolToolBar::OnTBNQueryInsert(NMHDR* pNMHDR, LRESULT* pResult)
{
NMTOOLBAR* pNMToolBar=(NMTOOLBAR*)pNMHDR;
UNREFERENCED_PARAMETER(pNMToolBar);
*pResult=TRUE; // always allow buttons to be inserted
return TRUE;
}
BOOL COXCoolToolBar::OnTBNQueryDelete(NMHDR* /*pNMHDR*/, LRESULT* pResult)
{
*pResult=TRUE; // always allow buttons to be deleted
return TRUE;
}
BOOL COXCoolToolBar::OnTBNToolBarChange(NMHDR* /*pNMHDR*/, LRESULT* /*pResult*/)
{
SetButtonTextFromID(m_ttID);
return FALSE;
}
#if _MFC_VER>=0x0420
//////////////////////
// custom draw of a toolbar is available since MFC 4.2
// in you derived class you can provide your own custom draw routines
void COXCoolToolBar::OnCustomDraw(NMHDR* pNotify, LRESULT* pResult)
{
GetToolbarSkin()->OnCustomDraw(pNotify, pResult, this);
}
//////////////////////
#endif
void COXCoolToolBar::OnRemoveDraggedButton(int nButtonIndex)
{
// delete button if it was moved
VERIFY(GetToolBarCtrl().DeleteButton(nButtonIndex));
}
// helper function to keep array of all used bitmaps
HBITMAP COXCoolToolBar::AddBitmap(LPTSTR lpszResourceName)
{
HBITMAP hBitmap=NULL;
if(!m_allBitmaps.Lookup(lpszResourceName,hBitmap))
{
if((hBitmap=::LoadBitmap(AfxGetResourceHandle(),
lpszResourceName))==NULL)
{
TRACE(_T("COXCoolToolBar::AddBitmap: unable to load bitmap\n"));
return NULL;
}
m_allBitmaps.SetAt(lpszResourceName,hBitmap);
}
return hBitmap;
}
// helper function to keep array of all used image lists
HIMAGELIST COXCoolToolBar::AddImageList(LPTSTR lpszResourceName, int cx, int cGrow,
COLORREF crMask, UINT uType, UINT uFlags)
{
HANDLE hImageList=NULL;
if(!m_allImageLists.Lookup(lpszResourceName,hImageList))
{
if((hImageList=(HANDLE)::ImageList_LoadImage(AfxGetResourceHandle(),
lpszResourceName,cx,cGrow,crMask,uType,uFlags))==NULL)
{
TRACE(_T("COXCoolToolBar::AddImageList: unable to load image list\n"));
return NULL;
}
m_allImageLists.SetAt(lpszResourceName,hImageList);
}
return (HIMAGELIST)hImageList;
}
// helper function to keep array of all used image lists
HIMAGELIST COXCoolToolBar::AddImageList(LPTSTR lpszResourceName, int cx,
COLORREF crMask, UINT uFlags,
int cInitial, int cGrow)
{
HANDLE hImageList=NULL;
if(!m_allImageLists.Lookup(lpszResourceName,hImageList))
{
CBitmap bitmap;
if(!bitmap.LoadBitmap(lpszResourceName))
{
TRACE(_T("COXCoolToolBar::AddImageList: unable to load image\n"));
return NULL;
}
BITMAP bitmapInfo;
VERIFY(bitmap.GetBitmap(&bitmapInfo)!=0);
if((hImageList=(HANDLE)::ImageList_Create(cx,bitmapInfo.bmHeight,
uFlags,cInitial,cGrow))==NULL)
{
TRACE(_T("COXCoolToolBar::AddImageList: unable to create image list\n"));
return NULL;
}
if(ImageList_AddMasked((HIMAGELIST)hImageList,bitmap,crMask)==-1)
{
TRACE(_T("COXCoolToolBar::AddImageList: unable to populate image list\n"));
ImageList_Destroy((HIMAGELIST)hImageList);
return NULL;
}
m_allImageLists.SetAt(lpszResourceName,hImageList);
}
return (HIMAGELIST)hImageList;
}
// helper function to automatically set text to buttons
// TTID_PLAIN - lookup string resource for var equals button's ID
// if found, set text in button to string text
// (not includded tool tip text)
// TTID_TOOLTIP - lookup string resource for var equals button's ID
// if found, set text in button to tooltip text
// TTID_MENU - lookup menu resource for var equals button's ID
// if found, set text in button to text of corresponding Item in menu
// TTID_NONE - remove all text associated with buttons
// TTID_NOTSET - default value (there is no any text associated with toolbar)
void COXCoolToolBar::SetButtonTextFromID(UINT nFirstButtonID,
UINT nLastButtonID, TextTypeFromID ttID)
{
m_ttID=ttID;
if(ttID==TTID_NOTSET)
{
return;
}
ASSERT(nFirstButtonID<=nLastButtonID);
CToolBarCtrl* pToolBarCtrl = &GetToolBarCtrl();
ASSERT(pToolBarCtrl != NULL);
BOOL bMenuLoaded=FALSE;
CMenu* pMenu=NULL;
if(ttID==TTID_MENU)
{
// try to get a menu associated with framework
if(AfxGetApp()->m_pMainWnd!=NULL)
{
if(AfxGetApp()->m_pMainWnd->GetMenu()!=NULL)
{
pMenu=AfxGetApp()->m_pMainWnd->GetMenu();
bMenuLoaded=TRUE;
}
else
{
TRACE(_T("COXCoolToolBar::SetButtonTextFromID: cannot get framework menu!/n"));
}
}
else
{
TRACE(_T("COXCoolToolBar::SetButtonTextFromID: m_pMainWnd of app is not defined yet menu!/n"));
}
}
UINT nID;
CString strText;
for(int i=0; i<pToolBarCtrl->GetButtonCount(); i++)
{
nID=GetItemID(i);
if(nID>=nFirstButtonID && nID<=nLastButtonID)
{
switch(ttID)
{
// text in string resourse (not included tooltip)
case TTID_PLAIN:
{
if (strText.LoadString(nID))
{
int nPlacement=strText.Find(_T('\n')); // tool tip is after "\n" in the string
if (nPlacement!=-1)
{
strText=strText.Left(nPlacement);
}
}
break;
}
// text in string resourse (only tooltip)
case TTID_TOOLTIP:
{
if (strText.LoadString(nID))
{
int nPlacement=strText.Find(_T('\n')); // tool tip is after "\n" in the string
if (nPlacement!=-1)
{
strText=strText.Mid(nPlacement+1);
}
else
{
strText=_T("");
}
}
break;
}
// text in menu item resourse
case TTID_MENU:
{
if(bMenuLoaded)
{
ASSERT(pMenu!=NULL);
pMenu->GetMenuString(nID,strText,MF_BYCOMMAND);
if(!strText.IsEmpty())
{
int nPlacement=strText.Find(_T('\t')); // accelerator keys are placed after "\t"
if (nPlacement!=-1)
{
strText=strText.Left(nPlacement);
}
}
}
break;
}
// remove any text
case TTID_NONE:
{
strText=_T("");
break;
}
default:
{
m_ttID=TTID_NONE;
strText=_T("");
break;
}
}
SetButtonText(i,strText);
}
}
}
// Save to registry state of buttons in CoolToolBar
BOOL COXCoolToolBar::SaveBarState(LPCTSTR lpszSubKey, LPCTSTR lpszValueName,
BOOL bProperties)
{
#ifndef _MAC
CWinApp* pApp=AfxGetApp();
CString sProfileName;
sProfileName.Format(_T("%s_%s"),lpszSubKey,lpszValueName);
// make sure you called SetButtonsIds()
// makes no sense to load/store buttons state info for uncustomizable CoolToolBar
if(IsCustomizable(TRUE) || IsCustomizable(FALSE))
{
ASSERT(m_pBitmapIds!=NULL);
// make sure you called CWinApp::SetRegistryKey() functions before
if(pApp->m_pszRegistryKey==NULL || pApp->m_pszProfileName==NULL)
{
TRACE(_T("COXCoolToolBar::SaveBarState: haven't called SetRegistryKey()\n"));
return FALSE;
}
// we use default registry key assigned to your application by MFC
HKEY hSecKey=pApp->GetSectionKey(_T(""));
if (hSecKey==NULL)
{
TRACE(_T("COXCoolToolBar::SaveBarState: unable to get section key\n"));
return FALSE;
}
// save buttons settings
//
CString sValueName;
sValueName.Format(_T("%s_ButtonsSettings"),lpszValueName);
CMemFile memFile;
CArchive ar(&memFile,CArchive::store);
int nButtonCount=GetToolBarCtrl().GetButtonCount();
ar<<(DWORD)nButtonCount;
for(int nIndex=0; nIndex<nButtonCount; nIndex++)
{
TBBUTTON button;
VERIFY(GetToolBarCtrl().GetButton(nIndex,&button));
ar<<(DWORD)button.idCommand;
ar<<(DWORD)button.iBitmap;
ar<<button.fsStyle;
CString sText=GetButtonText(nIndex);
ar<<(sText.IsEmpty() ? FALSE : TRUE);
if(sText.IsEmpty())
sText=GetRecentButtonText(button.idCommand);
ar<<sText;
}
ar.Close();
int nBufferLength=(int)memFile.GetLength();
ASSERT(nBufferLength>0);
BYTE* pBuffer=memFile.Detach();
pApp->WriteProfileBinary(lpszSubKey,sValueName,pBuffer,nBufferLength);
::free((void*)pBuffer);
sValueName+=_T("_Size");
pApp->WriteProfileInt(lpszSubKey,sValueName,nBufferLength);
// save custom buttons positions
//
sValueName.Format(_T("%s_CustomButtonsPositions"),lpszValueName);
CMemFile memFileCustom;
CArchive arCustom(&memFileCustom,CArchive::store);
int nCustomButtonCount=PtrToInt(m_mapCustomButtons.GetCount());
arCustom<<(DWORD)nCustomButtonCount;
for(int nCustomButtonIndex=0;
nCustomButtonIndex<GetToolBarCtrl().GetButtonCount();
nCustomButtonIndex++)
{
OXCUSTOMBUTTONDESCRIPTOR descriptor;
if(GetCustomButton(nCustomButtonIndex,descriptor))
{
arCustom<<(DWORD)nCustomButtonIndex;
arCustom<<
(DWORD)descriptor.m_pCBTemplate->CBGetWindow()->GetDlgCtrlID();
}
}
arCustom.Close();
nBufferLength=(int)memFileCustom.GetLength();
ASSERT(nBufferLength>0);
pBuffer=memFileCustom.Detach();
pApp->WriteProfileBinary(lpszSubKey,sValueName,pBuffer,nBufferLength);
::free((void*)pBuffer);
sValueName+=_T("_Size");
pApp->WriteProfileInt(lpszSubKey,sValueName,nBufferLength);
// save buttons state
GetToolBarCtrl().SaveState(hSecKey,lpszSubKey,lpszValueName);
::RegCloseKey(hSecKey);
}
// save custom buttons settings
//
if(!m_bCustomButtonsStateSaved)
{
CString sValueName=_T("Toolbars_CustomButtonsSettings");
CMemFile memFile;
CArchive ar(&memFile,CArchive::store);
int nButtonCount=PtrToInt(m_mapAllCustomButtons.GetCount());
ar<<(DWORD)nButtonCount;
POSITION pos=m_mapAllCustomButtons.GetStartPosition();
while(pos!=NULL)
{
int nCtrlID=-1;
OXCUSTOMBUTTONDESCRIPTOR descriptor;
m_mapAllCustomButtons.GetNextAssoc(pos,nCtrlID,descriptor);
ASSERT(nCtrlID>0);
ar<<(DWORD)nCtrlID;
descriptor.SaveState(ar);
descriptor.m_pCBTemplate->CBSaveState(ar);
}
ar.Close();
int nBufferLength=(int)memFile.GetLength();
ASSERT(nBufferLength>0);
BYTE* pBuffer=memFile.Detach();
pApp->WriteProfileBinary(lpszSubKey,sValueName,pBuffer,nBufferLength);
::free((void*)pBuffer);
sValueName+=_T("_Size");
pApp->WriteProfileInt(lpszSubKey,sValueName,nBufferLength);
m_bCustomButtonsStateSaved=TRUE;
}
// save CoolToolBar properties
if(bProperties)
{
#if _MFC_VER>=0x0420
pApp->WriteProfileInt(sProfileName,szCool,IsCool());
pApp->WriteProfileInt(sProfileName,szGripper,IsGripper());
pApp->WriteProfileInt(sProfileName,szSeparator,IsSeparator());
pApp->WriteProfileInt(sProfileName,szFlat,IsFlat());
pApp->WriteProfileInt(sProfileName,szList,IsList());
pApp->WriteProfileInt(sProfileName,szDropDownArrow,IsDropDownArrow());
pApp->WriteProfileInt(sProfileName,szIndent,GetIndent());
pApp->WriteProfileInt(sProfileName,szDefaultTextColor,GetDefaultTextColor());
pApp->WriteProfileInt(sProfileName,szHotTextColor,GetHotTextColor());
pApp->WriteProfileInt(sProfileName,szSelectedTextColor,GetSelectedTextColor());
pApp->WriteProfileInt(sProfileName,szCheckedTextColor,GetCheckedTextColor());
pApp->WriteProfileInt(sProfileName,szDefaultBkColor,GetDefaultBkColor());
pApp->WriteProfileInt(sProfileName,szHotBkColor,GetHotBkColor());
pApp->WriteProfileInt(sProfileName,szSelectedBkColor,GetSelectedBkColor());
pApp->WriteProfileInt(sProfileName,szCheckedBkColor,GetCheckedBkColor());
pApp->WriteProfileInt(sProfileName,szDefaultBorderColor,GetDefaultBorderColor());
pApp->WriteProfileInt(sProfileName,szHotBorderColor,GetHotBorderColor());
pApp->WriteProfileInt(sProfileName,szSelectedBorderColor,GetSelectedBorderColor());
pApp->WriteProfileInt(sProfileName,szCheckedBorderColor,GetCheckedBorderColor());
pApp->WriteProfileInt(sProfileName,szTextType,GetTextType());
pApp->WriteProfileInt(sProfileName,szTextRows,GetTextRows());
pApp->WriteProfileInt(sProfileName,szMinButtonsWidth,GetButtonsMinMaxWidth().cx);
pApp->WriteProfileInt(sProfileName,szMaxButtonsWidth,GetButtonsMinMaxWidth().cy);
#endif
pApp->WriteProfileInt(sProfileName,szCustomizable,IsCustomizable());
}
return TRUE;
#else
return FALSE;
#endif
}
// Load from registry state of buttons in CoolToolBar
BOOL COXCoolToolBar::LoadBarState(LPCTSTR lpszSubKey, LPCTSTR lpszValueName,
BOOL bProperties)
{
#ifndef _MAC
CWinApp* pApp=AfxGetApp();
CString sProfileName;
sProfileName.Format(_T("%s_%s"),lpszSubKey,lpszValueName);
int nResult;
if(bProperties)
{
nResult=pApp->GetProfileInt(sProfileName,szCustomizable,-1);
if(nResult!=-1)
{
SetCustomizable(nResult);
}
}
BOOL bUpdate=FALSE;
// load and apply CoolToolBar properties
if(bProperties)
{
#if _MFC_VER>=0x0420
nResult=pApp->GetProfileInt(sProfileName,szCool,-1);
if(nResult!=-1)
{
SetCool(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szGripper,-1);
if(nResult!=-1)
{
SetGripper(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szSeparator,-1);
if(nResult!=-1)
{
SetSeparator(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szFlat,-1);
if(nResult!=-1)
{
SetFlat(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szList,-1);
if(nResult!=-1)
{
SetList(nResult);
bUpdate=TRUE;
}
nResult=pApp->GetProfileInt(sProfileName,szDropDownArrow,-1);
if(nResult!=-1)
{
SetDropDownArrow(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szIndent,-1);
if(nResult!=-1)
{
SetIndent(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szDefaultTextColor,-1);
if(nResult!=-1)
{
SetDefaultTextColor(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szHotTextColor,-1);
if(nResult!=-1)
{
SetHotTextColor(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szSelectedTextColor,-1);
if(nResult!=-1)
{
SetSelectedTextColor(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szCheckedTextColor,-1);
if(nResult!=-1)
{
SetCheckedTextColor(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szDefaultBkColor,-1);
if(nResult!=-1)
{
SetDefaultBkColor(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szHotBkColor,-1);
if(nResult!=-1)
{
SetHotBkColor(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szSelectedBkColor,-1);
if(nResult!=-1)
{
SetSelectedBkColor(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szCheckedBkColor,-1);
if(nResult!=-1)
{
SetCheckedBkColor(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szDefaultBorderColor,-1);
if(nResult!=-1)
{
SetDefaultBorderColor(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szHotBorderColor,-1);
if(nResult!=-1)
{
SetHotBorderColor(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szSelectedBorderColor,-1);
if(nResult!=-1)
{
SetSelectedBorderColor(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szCheckedBorderColor,-1);
if(nResult!=-1)
{
SetCheckedBorderColor(nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szTextType,-1);
if(nResult!=-1 && nResult!=GetTextType())
{
if(nResult==TTID_NOTSET)
{
SetButtonTextFromID(TTID_NONE);
}
bUpdate=TRUE;
SetButtonTextFromID((TextTypeFromID)nResult);
}
nResult=pApp->GetProfileInt(sProfileName,szTextRows,-1);
if(nResult!=-1 && nResult!=GetTextRows())
{
SetMaxTextRows(nResult);
bUpdate=TRUE;
}
nResult=pApp->GetProfileInt(sProfileName,szMinButtonsWidth,-1);
if(nResult!=-1 && nResult!=m_sizeMinMaxWidth.cx)
{
m_sizeMinMaxWidth.cx=nResult;
SetButtonsMinMaxWidth(m_sizeMinMaxWidth.cx,m_sizeMinMaxWidth.cy);
}
nResult=pApp->GetProfileInt(sProfileName,szMaxButtonsWidth,-1);
if(nResult!=-1 && nResult!=m_sizeMinMaxWidth.cy)
{
m_sizeMinMaxWidth.cy=nResult;
SetButtonsMinMaxWidth(m_sizeMinMaxWidth.cx,m_sizeMinMaxWidth.cy);
bUpdate=TRUE;
}
#endif
}
// load custom button settings
//
if(!m_bCustomButtonsStateLoaded)
{
CString sValueName=_T("Toolbars_CustomButtonsSettings_Size");
int nSavedBufferLength=pApp->GetProfileInt(lpszSubKey,sValueName,-1);
if(nSavedBufferLength!=-1)
{
ASSERT(nSavedBufferLength>0);
UINT nBufferLength=0;
BYTE* pBuffer=NULL;
sValueName=_T("Toolbars_CustomButtonsSettings");
if(pApp->GetProfileBinary(lpszSubKey,sValueName,&pBuffer,&nBufferLength))
{
ASSERT(nBufferLength>0);
ASSERT(pBuffer!=NULL);
CMemFile memFile(pBuffer,nBufferLength);
CArchive ar(&memFile,CArchive::load);
DWORD dwButtonCount=0;
ar>>dwButtonCount;
for(int nIndex=0; nIndex<(int)dwButtonCount; nIndex++)
{
DWORD dwCtrlID;
ar>>dwCtrlID;
OXCUSTOMBUTTONDESCRIPTOR descriptor;
VERIFY(m_mapAllCustomButtons.Lookup((int)dwCtrlID,descriptor));
descriptor.LoadState(ar);
descriptor.m_pCBTemplate->CBLoadState(ar);
m_mapAllCustomButtons.SetAt((int)dwCtrlID,descriptor);
}
ar.Close();
memFile.Detach();
delete[] pBuffer;
}
}
m_bCustomButtonsStateLoaded=TRUE;
}
// make sure you called SetButtonsIds()
// makes no sense to load/store buttons state info for uncustomizable CoolToolBar
//
// load and apply button settings
if(IsCustomizable(FALSE) || IsCustomizable(TRUE))
{
ASSERT(m_pBitmapIds!=NULL);
// make sure you called CWinApp::SetRegistryKey() functions before
if(pApp->m_pszRegistryKey==NULL || pApp->m_pszProfileName==NULL)
{
TRACE(_T("COXCoolToolBar::LoadBarState: haven't called SetRegistryKey()\n"));
return FALSE;
}
// we use default registry key assigned to your application by MFC
HKEY hSecKey=pApp->GetSectionKey(_T(""));
if (hSecKey==NULL)
{
TRACE(_T("COXCoolToolBar::LoadBarState: unable to get section key\n"));
return FALSE;
}
// before restoring state of buttons we should remove all custom buttons
// and store them temporary in mapDeletedCustomButtons map
CMap<int,int,OXCUSTOMBUTTONDESCRIPTOR,OXCUSTOMBUTTONDESCRIPTOR&>
mapDeletedCustomButtons;
// check if any custom buttons info has been saved
CString sValueName;
sValueName.Format(_T("%s_CustomButtonsPositions_Size"),lpszValueName);
int nSavedBufferLength=pApp->GetProfileInt(lpszSubKey,sValueName,-1);
if(nSavedBufferLength>0)
{
for(int nIndex=GetToolBarCtrl().GetButtonCount()-1; nIndex>=0; nIndex--)
{
OXCUSTOMBUTTONDESCRIPTOR descriptor;
if(GetCustomButton(nIndex,descriptor))
{
ASSERT(::IsWindow(
descriptor.m_pCBTemplate->CBGetWindow()->GetSafeHwnd()));
int nButtonCtrlID=
descriptor.m_pCBTemplate->CBGetWindow()->GetDlgCtrlID();
if(descriptor.m_pCBTemplate->CBIsDynamicallyCreated())
{
// this button will be deleted later
descriptor.m_pCBTemplate=NULL;
}
mapDeletedCustomButtons.SetAt(nButtonCtrlID,descriptor);
GetToolBarCtrl().DeleteButton(nIndex);
}
}
}
m_bNoInternalRedraw=TRUE;
// restore the toolbar contents
GetToolBarCtrl().RestoreState(hSecKey,lpszSubKey,lpszValueName);
::RegCloseKey(hSecKey);
// apply saved button settings
//
sValueName.Format(_T("%s_ButtonsSettings_Size"),lpszValueName);
nSavedBufferLength=pApp->GetProfileInt(lpszSubKey,sValueName,-1);
if(nSavedBufferLength!=-1)
{
ASSERT(nSavedBufferLength>0);
UINT nBufferLength=0;
BYTE* pBuffer=NULL;
sValueName.Format(_T("%s_ButtonsSettings"),lpszValueName);
if(pApp->GetProfileBinary(lpszSubKey,sValueName,&pBuffer,&nBufferLength))
{
ASSERT(nBufferLength>0);
ASSERT(pBuffer!=NULL);
CMemFile memFile(pBuffer,nBufferLength);
CArchive ar(&memFile,CArchive::load);
DWORD dwButtonCount=0;
ar>>dwButtonCount;
for(int nIndex=0; nIndex<(int)dwButtonCount; nIndex++)
{
DWORD dwCommandID;
ar>>dwCommandID;
DWORD dwImageIndex;
ar>>dwImageIndex;
BYTE fsStyle;
ar>>fsStyle;
BOOL bSetText;
ar>>bSetText;
CString sText;
ar>>sText;
if(fsStyle&TBSTYLE_SEP)
continue;
int nButtonIndex=CommandToIndex((UINT)dwCommandID);
if(nButtonIndex!=-1)
{
SetButtonInfo(nButtonIndex,(UINT)dwCommandID,
fsStyle,(int)dwImageIndex);
if(bSetText)
{
SetButtonText(nButtonIndex,sText);
}
else
{
if(!sText.IsEmpty())
m_mapButtonText.SetAt((UINT)dwCommandID,sText);
}
}
}
ar.Close();
memFile.Detach();
delete[] pBuffer;
}
}
// apply saved custom button positions
//
sValueName.Format(_T("%s_CustomButtonsPositions_Size"),lpszValueName);
nSavedBufferLength=pApp->GetProfileInt(lpszSubKey,sValueName,-1);
if(nSavedBufferLength!=-1)
{
ASSERT(nSavedBufferLength>0);
UINT nBufferLength=0;
BYTE* pBuffer=NULL;
sValueName.Format(_T("%s_CustomButtonsPositions"),lpszValueName);
if(pApp->GetProfileBinary(lpszSubKey,sValueName,&pBuffer,&nBufferLength))
{
ASSERT(nBufferLength>0);
ASSERT(pBuffer!=NULL);
CMemFile memFile(pBuffer,nBufferLength);
CArchive ar(&memFile,CArchive::load);
DWORD dwButtonCount=0;
ar>>dwButtonCount;
for(int nIndex=0; nIndex<(int)dwButtonCount; nIndex++)
{
DWORD dwIndex;
ar>>dwIndex;
DWORD dwCtrlID;
ar>>dwCtrlID;
ASSERT((int)dwIndex>=0 &&
(int)dwIndex<=GetToolBarCtrl().GetButtonCount());
OXCUSTOMBUTTONDESCRIPTOR descriptor;
if(mapDeletedCustomButtons.Lookup((int)dwCtrlID,descriptor) &&
descriptor.m_pCBTemplate!=NULL && ::IsWindow(
descriptor.m_pCBTemplate->CBGetWindow()->GetSafeHwnd()))
{
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.
Lookup((int)dwCtrlID,descriptorOrig));
// add placeholder
TBBUTTON button={ 0 };
button.iBitmap=-1;
button.idCommand=0;
button.fsStyle=TBSTYLE_SEP;
button.iString=-1;
VERIFY(GetToolBarCtrl().InsertButton((int)dwIndex,&button));
// add new custom button
m_mapCustomButtons.SetAt((int)dwIndex,descriptorOrig);
}
else
{
int nCustomButtonIndex=GetCustomButtonIndex((int)dwCtrlID);
ASSERT(nCustomButtonIndex!=-1);
VERIFY(InsertCustomButton((int)dwIndex,nCustomButtonIndex));
}
}
ar.Close();
memFile.Detach();
delete[] pBuffer;
}
}
SetButtonTextFromID(m_ttID);
}
m_bNoInternalRedraw=FALSE;
// change the size of CoolToolBar
if(bUpdate)
{
if(GetTextRows()==0)
{
IniSizes(m_sizeImage);
}
else
{
UpdateSizes();
}
RedrawToolBar();
}
else
{
UpdateCustomButtons();
}
return TRUE;
#else
return FALSE;
#endif
}
void COXCoolToolBar::DockControlBarLeftOf(CToolBar *leftOf)
{
ASSERT_VALID(this);
// make sure CControlBar::EnableDocking has been called
ASSERT(m_pDockContext!=NULL);
if(leftOf!=NULL)
{
ASSERT_VALID(leftOf);
}
CFrameWnd* pFrameWnd=GetDockingFrame();
ASSERT_VALID(pFrameWnd);
// get MFC to adjust the dimensions of all docked ToolBars
// so that GetWindowRect will be accurate
pFrameWnd->RecalcLayout();
UINT nDockBarID=0;
CRect rect(0,0,0,0);
if(leftOf!=NULL)
{
leftOf->GetWindowRect(&rect);
rect.OffsetRect(1,0);
DWORD dwStyle=leftOf->GetBarStyle();
nDockBarID=(dwStyle & CBRS_ALIGN_TOP) ? AFX_IDW_DOCKBAR_TOP :
(dwStyle & CBRS_ALIGN_BOTTOM) ? AFX_IDW_DOCKBAR_BOTTOM :
(dwStyle & CBRS_ALIGN_LEFT) ? AFX_IDW_DOCKBAR_LEFT :
(dwStyle & CBRS_ALIGN_RIGHT) ? AFX_IDW_DOCKBAR_RIGHT : 0;
}
// When we take the default parameters on rect, DockControlBar will dock
// each Toolbar on a seperate line. Calculating a rectangle, we in effect
// are simulating a Toolbar being dragged to that location and docked.
pFrameWnd->DockControlBar(this, nDockBarID, &rect);
}
#if _MFC_VER<=0x0421
#define OXCY_BORDER 1
void COXCoolToolBar::SetHeight(int cyHeight)
{
ASSERT_VALID(this);
int nHeight = cyHeight;
if (m_dwStyle & CBRS_BORDER_TOP)
cyHeight -= OXCY_BORDER;
if (m_dwStyle & CBRS_BORDER_BOTTOM)
cyHeight -= OXCY_BORDER;
m_cyBottomBorder = (cyHeight - m_sizeButton.cy) / 2;
// if there is an extra pixel, m_cyTopBorder will get it
m_cyTopBorder = cyHeight - m_sizeButton.cy - m_cyBottomBorder;
if (m_cyTopBorder < 0)
{
TRACE(_T("Warning: COXCoolToolBar::SetHeight(%d) is smaller than button.\n"),
nHeight);
m_cyBottomBorder += m_cyTopBorder;
m_cyTopBorder = 0; // will clip at bottom
}
// recalculate the non-client region
SetWindowPos(NULL, 0, 0, 0, 0,
SWP_DRAWFRAME|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER);
Invalidate(); // just to be nice if called when toolbar is visible
}
#endif
BOOL COXCoolToolBar::IsWindowsNTRunning()
{
BOOL bResult=FALSE;
OSVERSIONINFO verInfo;
verInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if (::GetVersionEx(&verInfo))
{
if (verInfo.dwPlatformId==VER_PLATFORM_WIN32_NT &&
verInfo.dwMajorVersion>=4)
{
bResult=TRUE;
}
}
return bResult;
}
int COXCoolToolBar::GetDropDownArrowWidth() const
{
#if _MFC_VER>=0x0420
HDC hDC = ::GetDC(NULL);
ASSERT(hDC != NULL);
HFONT hFont;
HFONT oldFont=NULL;
int nDropDownArrowWidth=0;
if((hFont=CreateFont(GetSystemMetrics(SM_CYMENUCHECK), 0, 0, 0,
FW_NORMAL, 0, 0, 0, SYMBOL_CHARSET, 0, 0, 0, 0, _T("Marlett")))!=NULL)
{
oldFont = (HFONT)SelectObject(hDC, hFont);
}
VERIFY(GetCharWidth(hDC, '6', '6', &nDropDownArrowWidth));
if(oldFont!=NULL)
{
SelectObject(hDC, oldFont);
}
if(hFont!=NULL)
{
DeleteObject(hFont);
}
::ReleaseDC(NULL, hDC);
return nDropDownArrowWidth;
#else
return 0;
#endif
}
#if _MFC_VER>=0x0420
////////////////////////////////
void COXCoolToolBar::_GetButton(int nIndex, TBBUTTON* pButton) const
{
COXCoolToolBar* pBar = (COXCoolToolBar*)this;
VERIFY(pBar->DefWindowProc(TB_GETBUTTON, nIndex, (LPARAM)pButton));
// TBSTATE_ENABLED == TBBS_DISABLED so invert it
pButton->fsState ^= TBSTATE_ENABLED;
}
void COXCoolToolBar::_SetButton(int nIndex, TBBUTTON* pButton)
{
// get original button state
TBBUTTON button;
VERIFY(DefWindowProc(TB_GETBUTTON, nIndex, (LPARAM)&button));
// prepare for old/new button comparsion
button.bReserved[0] = 0;
button.bReserved[1] = 0;
// TBSTATE_ENABLED == TBBS_DISABLED so invert it
pButton->fsState ^= TBSTATE_ENABLED;
pButton->bReserved[0] = 0;
pButton->bReserved[1] = 0;
// nothing to do if they are the same
if (memcmp(pButton, &button, sizeof(TBBUTTON)) != 0)
{
// don't redraw anything while setting the button
BOOL bWasVisible=(GetStyle()&WS_VISIBLE);
if(bWasVisible)
ModifyStyle(WS_VISIBLE, 0);
VERIFY(DefWindowProc(TB_DELETEBUTTON, nIndex, 0));
VERIFY(DefWindowProc(TB_INSERTBUTTON, nIndex, (LPARAM)pButton));
if(bWasVisible)
{
ModifyStyle(0,WS_VISIBLE);
}
// invalidate appropriate parts
if (((pButton->fsStyle ^ button.fsStyle) & TBSTYLE_SEP) ||
((pButton->fsStyle & TBSTYLE_SEP) && pButton->iBitmap != button.iBitmap))
{
// changing a separator
Invalidate(FALSE);
}
else
{
// invalidate just the button
CRect rect;
if (DefWindowProc(TB_GETITEMRECT, nIndex, (LPARAM)&rect))
InvalidateRect(rect, FALSE); // don't erase background
}
}
}
#ifdef _MAC
#define CX_OVERLAP 1
#else
#define CX_OVERLAP 0
#endif
int COXCoolToolBar::WrapToolBar(TBBUTTON* pData, int nCount, int nWidth)
{
ASSERT(pData != NULL && nCount > 0);
int nResult = 0;
int x = 0;
for (int i = 0; i < nCount; i++)
{
pData[i].fsState &= ~TBSTATE_WRAP;
if (pData[i].fsState & TBSTATE_HIDDEN)
continue;
int dx, dxNext;
// take into account custom button style
if(pData[i].fsStyle & TBSTYLE_SEP)
{
dx = pData[i].iBitmap;
dxNext = dx;
}
else
{
dx = m_sizeButton.cx;
if(pData[i].fsStyle & TBSTYLE_AUTOSIZE)
{
CRect rect;
GetToolBarCtrl().GetItemRect(i,&rect);
dx=rect.Width();
}
// check for dropdown style, but only if the buttons are being drawn
if((pData[i].fsStyle & TBSTYLE_DROPDOWN) && IsDropDownArrow() &&
(pData[i].fsStyle & TBSTYLE_AUTOSIZE)==0)
{
if(!IsFlat() || m_dwComCtlVersion>=_IE40_COMCTL_VERSION)
{
// add size of drop down
if(m_dwComCtlVersion<_IE40_COMCTL_VERSION)
{
m_nDropDownArrowWidth=GetDropDownArrowWidth();
}
dx += m_nDropDownArrowWidth;
}
}
dxNext = dx - CX_OVERLAP;
}
if(x + dx > nWidth)
{
BOOL bFound = FALSE;
for (int j = i; j >= 0 && !(pData[j].fsState & TBSTATE_WRAP); j--)
{
// Find last separator that isn't hidden
// a separator that has a command ID is not
// a separator, but a custom control.
if((pData[j].fsStyle & TBSTYLE_SEP) &&
(pData[j].idCommand == 0) &&
!(pData[j].fsState & TBSTATE_HIDDEN))
{
bFound = TRUE; i = j; x = 0;
pData[j].fsState |= TBSTATE_WRAP;
nResult++;
break;
}
}
if(!bFound)
{
for (int j = i - 1; j >= 0 &&
!(pData[j].fsState & TBSTATE_WRAP); j--)
{
// Never wrap anything that is hidden,
// or any custom controls
if ((pData[j].fsState & TBSTATE_HIDDEN) ||
((pData[j].fsStyle & TBSTYLE_SEP) &&
(pData[j].idCommand != 0)))
{
continue;
}
bFound = TRUE; i = j; x = 0;
pData[j].fsState |= TBSTATE_WRAP;
nResult++;
break;
}
if(!bFound)
{
x += dxNext;
}
}
}
else
{
x += dxNext;
}
}
return nResult + 1;
}
void COXCoolToolBar::SizeToolBar(TBBUTTON* pData, int nCount,
int nLength, BOOL bVert/*=FALSE*/)
{
ASSERT(pData != NULL && nCount > 0);
if (!bVert)
{
int nMin, nMax, nTarget, nCurrent, nMid;
// Wrap ToolBar as specified
nMax = nLength;
nTarget = WrapToolBar(pData, nCount, nMax);
// Wrap ToolBar vertically
nMin = 0;
nCurrent = WrapToolBar(pData, nCount, nMin);
if (nCurrent != nTarget)
{
while (nMin < nMax)
{
nMid = (nMin + nMax) / 2;
nCurrent = WrapToolBar(pData, nCount, nMid);
if (nCurrent == nTarget)
nMax = nMid;
else
{
if (nMin == nMid)
{
WrapToolBar(pData, nCount, nMax);
break;
}
nMin = nMid;
}
}
}
CSize size = CalcSize(pData, nCount);
WrapToolBar(pData, nCount, size.cx);
}
else
{
CSize sizeMax, sizeMin, sizeMid;
// Wrap ToolBar vertically
WrapToolBar(pData, nCount, 0);
sizeMin = CalcSize(pData, nCount);
// Wrap ToolBar horizontally
WrapToolBar(pData, nCount, 32767);
sizeMax = CalcSize(pData, nCount);
while (sizeMin.cx < sizeMax.cx)
{
sizeMid.cx = (sizeMin.cx + sizeMax.cx) / 2;
WrapToolBar(pData, nCount, sizeMid.cx);
sizeMid = CalcSize(pData, nCount);
if (nLength < sizeMid.cy)
{
if (sizeMin == sizeMid)
{
WrapToolBar(pData, nCount, sizeMax.cx);
return;
}
sizeMin = sizeMid;
}
else if (nLength > sizeMid.cy)
sizeMax = sizeMid;
else
return;
}
}
}
CSize COXCoolToolBar::CalcSize(TBBUTTON* pData, int nCount)
{
ASSERT(pData != NULL && nCount > 0);
CPoint cur(0,0);
CSize sizeResult(0,0);
for (int i = 0; i < nCount; i++)
{
int cySep = pData[i].iBitmap;
if(!IsFlat() || m_dwComCtlVersion<_IE40_COMCTL_VERSION)
{
cySep = cySep * 2 / 3;
}
if(pData[i].fsState & TBSTATE_HIDDEN)
continue;
int cx = m_sizeButton.cx;
if(pData[i].fsStyle & TBSTYLE_AUTOSIZE)
{
CRect rect;
GetToolBarCtrl().GetItemRect(i,&rect);
cx=rect.Width();
}
if(pData[i].fsStyle & TBSTYLE_SEP)
{
// a separator represents either a height or width
if (pData[i].fsState & TBSTATE_WRAP)
{
sizeResult.cy = __max(cur.y + m_sizeButton.cy + cySep,
sizeResult.cy);
}
else
{
sizeResult.cx = __max(cur.x + pData[i].iBitmap, sizeResult.cx);
sizeResult.cy = __max(cur.y + m_sizeButton.cy, sizeResult.cy);
}
}
else
{
// check for dropdown style, but only if the buttons are being drawn
if((pData[i].fsStyle & TBSTYLE_DROPDOWN) && IsDropDownArrow() &&
(pData[i].fsStyle & TBSTYLE_AUTOSIZE)==0)
{
if(!IsFlat() || m_dwComCtlVersion>=_IE40_COMCTL_VERSION)
{
// add size of drop down
if(m_dwComCtlVersion<_IE40_COMCTL_VERSION)
{
m_nDropDownArrowWidth=GetDropDownArrowWidth();
}
cx += m_nDropDownArrowWidth;
}
}
sizeResult.cx = __max(cur.x + cx, sizeResult.cx);
sizeResult.cy = __max(cur.y + m_sizeButton.cy, sizeResult.cy);
}
if(pData[i].fsStyle & TBSTYLE_SEP)
{
cur.x += pData[i].iBitmap;
}
else
{
cur.x += cx - CX_OVERLAP;
}
if(pData[i].fsState & TBSTATE_WRAP)
{
cur.x = 0;
cur.y += m_sizeButton.cy;
if(pData[i].fsStyle & TBSTYLE_SEP)
cur.y += cySep;
}
}
// add indention
sizeResult.cx+=m_nIndent;
return sizeResult;
}
struct _AFX_CONTROLPOS
{
int nIndex, nID;
CRect rectOldPos;
};
CSize COXCoolToolBar::CalcLayout(DWORD dwMode, int nLength)
{
ASSERT_VALID(this);
ASSERT(::IsWindow(m_hWnd));
if(dwMode & LM_HORZDOCK)
{
ASSERT(dwMode & LM_HORZ);
}
int nCount;
TBBUTTON* pData=NULL;
CMap<int,int,TBBUTTON*,TBBUTTON*> mapIndexToIgnore;
CSize sizeResult(0,0);
// Load Buttons
{
nCount = PtrToInt(DefWindowProc(TB_BUTTONCOUNT, 0, 0));
if (nCount != 0)
{
int nFlags=(((dwMode & LM_HORZDOCK)==0 && (dwMode & LM_VERTDOCK)==0) ?
OXCBD_SHOWFLOAT : ((dwMode & LM_HORZDOCK)!=0 ?
OXCBD_SHOWHORZ : OXCBD_SHOWVERT));
int i;
pData=new TBBUTTON[nCount];
for(i=0; i<nCount; i++)
{
_GetButton(i,&pData[i]);
// take into account custom button style
OXCUSTOMBUTTONDESCRIPTOR descriptor;
if(GetCustomButton(i,descriptor))
{
if(((descriptor.m_nFlags & OXCBD_SHOWFLOAT)==0 &&
nFlags==OXCBD_SHOWFLOAT) ||
((descriptor.m_nFlags & OXCBD_SHOWHORZ)==0 &&
nFlags==OXCBD_SHOWHORZ) ||
((descriptor.m_nFlags & OXCBD_SHOWVERT)==0 &&
nFlags==OXCBD_SHOWVERT))
{
TBBUTTON* pButton=new TBBUTTON;
*pButton=pData[i];
pData[i].fsStyle&=~TBSTYLE_SEP;
pData[i].fsStyle|=TBSTYLE_BUTTON;
pData[i].iBitmap=descriptor.m_nImageIndex;
mapIndexToIgnore.SetAt(i,pButton);
}
}
}
}
}
if (nCount > 0)
{
if (!(m_dwStyle & CBRS_SIZE_FIXED))
{
BOOL bDynamic = m_dwStyle & CBRS_SIZE_DYNAMIC;
ASSERT(pData!=NULL);
if (bDynamic && (dwMode & LM_MRUWIDTH))
SizeToolBar(pData, nCount, m_nMRUWidth);
else if (bDynamic && (dwMode & LM_HORZDOCK))
SizeToolBar(pData, nCount, 32767);
else if (bDynamic && (dwMode & LM_VERTDOCK))
SizeToolBar(pData, nCount, 0);
else if (bDynamic && (nLength != -1))
{
CRect rect; rect.SetRectEmpty();
CalcInsideRect(rect, (dwMode & LM_HORZ));
BOOL bVert = (dwMode & LM_LENGTHY);
int nLen = nLength + (bVert ? rect.Height() : rect.Width());
SizeToolBar(pData, nCount, nLen, bVert);
}
else if (bDynamic && (m_dwStyle & CBRS_FLOATING))
SizeToolBar(pData, nCount, m_nMRUWidth);
else
SizeToolBar(pData, nCount, (dwMode & LM_HORZ) ? 32767 : 0);
}
sizeResult = CalcSize(pData, nCount);
if (dwMode & LM_COMMIT)
{
_AFX_CONTROLPOS* pControl = NULL;
int nControlCount = 0;
BOOL bIsDelayed = m_bDelayedButtonLayout;
m_bDelayedButtonLayout = FALSE;
int i = 0;
for(i = 0; i < nCount; i++)
{
if ((pData[i].fsStyle & TBSTYLE_SEP) && (pData[i].idCommand != 0))
{
nControlCount++;
}
}
if (nControlCount > 0)
{
pControl = new _AFX_CONTROLPOS[nControlCount];
nControlCount = 0;
for(int i = 0; i < nCount; i++)
{
if ((pData[i].fsStyle & TBSTYLE_SEP) && (pData[i].idCommand != 0))
{
pControl[nControlCount].nIndex = i;
pControl[nControlCount].nID = pData[i].idCommand;
CRect rect;
GetItemRect(i, &rect);
ClientToScreen(&rect);
pControl[nControlCount].rectOldPos = rect;
nControlCount++;
}
}
}
if ((m_dwStyle & CBRS_FLOATING) && (m_dwStyle & CBRS_SIZE_DYNAMIC))
{
m_nMRUWidth = sizeResult.cx;
}
for (i = 0; i < nCount; i++)
{
TBBUTTON* pButton=NULL;
if(mapIndexToIgnore.Lookup(i,pButton))
{
ASSERT(pButton!=NULL);
if(pData[i].fsState & TBSTATE_WRAP)
{
pButton->fsState|=TBSTATE_WRAP;
}
else
{
pButton->fsState&=~TBSTATE_WRAP;
}
_SetButton(i, pButton);
}
else
{
_SetButton(i, &pData[i]);
}
}
if (nControlCount > 0)
{
for (int i = 0; i < nControlCount; i++)
{
CWnd* pWnd = GetDlgItem(pControl[i].nID);
if (pWnd != NULL)
{
CRect rect;
pWnd->GetWindowRect(&rect);
CPoint pt = rect.TopLeft() - pControl[i].rectOldPos.TopLeft();
GetItemRect(pControl[i].nIndex, &rect);
pt = rect.TopLeft() + pt;
pWnd->SetWindowPos(NULL, pt.x, pt.y, 0, 0,
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
}
}
delete[] pControl;
}
m_bDelayedButtonLayout = bIsDelayed;
}
delete[] pData;
}
else
{
CSize sizeButtons=GetButtonsSize();
if(dwMode & LM_HORZ)
{
if(IsFloating())
{
sizeResult.cx=sizeButtons.cx;
}
else
{
sizeResult.cx=sizeButtons.cx/2;
}
sizeResult.cy=sizeButtons.cy;
}
else
{
sizeResult.cx=sizeButtons.cx;
if(IsFloating())
{
sizeResult.cy=sizeButtons.cy;
}
else
{
sizeResult.cy=sizeButtons.cy/2;
}
}
}
POSITION pos=mapIndexToIgnore.GetStartPosition();
while(pos!=NULL)
{
int nIndex=0;
TBBUTTON* pButton=NULL;
mapIndexToIgnore.GetNextAssoc(pos,nIndex,pButton);
ASSERT(pButton!=NULL);
delete pButton;
}
mapIndexToIgnore.RemoveAll();
//BLOCK: Adjust Margins
{
CRect rect; rect.SetRectEmpty();
CalcInsideRect(rect, (dwMode & LM_HORZ));
sizeResult.cy -= rect.Height();
sizeResult.cx -= rect.Width();
CSize size = CControlBar::CalcFixedLayout((dwMode & LM_STRETCH),
(dwMode & LM_HORZ));
sizeResult.cx = __max(sizeResult.cx, size.cx);
sizeResult.cy = __max(sizeResult.cy, size.cy);
}
return sizeResult;
}
CSize COXCoolToolBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
DWORD dwMode = bStretch ? LM_STRETCH : 0;
dwMode |= bHorz ? LM_HORZ : 0;
return CalcLayout(dwMode);
}
CSize COXCoolToolBar::CalcDynamicLayout(int nLength, DWORD dwMode)
{
if ((nLength == -1) && !(dwMode & LM_MRUWIDTH) && !(dwMode & LM_COMMIT) &&
((dwMode & LM_HORZDOCK) || (dwMode & LM_VERTDOCK)))
{
return CalcFixedLayout(dwMode & LM_STRETCH, dwMode & LM_HORZDOCK);
}
return CalcLayout(dwMode, nLength);
}
void COXCoolToolBar::CalcInsideRect(CRect& rect, BOOL bHorz)
{
CToolBar::CalcInsideRect(rect,bHorz);
if(m_hIcon)
{
// Icon size
CSize szIcon(::GetSystemMetrics(SM_CXSMICON),
::GetSystemMetrics(SM_CYSMICON));
if(bHorz)
rect.left+=szIcon.cx+2;
else
rect.top+=szIcon.cy+2;
}
CRect rectBookedSpace(0,0,0,0);
BookSpace(rectBookedSpace,(bHorz ? LM_HORZ : 0));
rect.left+=rectBookedSpace.left;
rect.top+=rectBookedSpace.top;
rect.right-=rectBookedSpace.right;
rect.bottom-=rectBookedSpace.bottom;
if(IsFlat() && IsGripper() && !(m_dwStyle & CBRS_FLOATING))
{
if(bHorz)
{
rect.left+=ID_OXGRIPPER_WIDTH;
}
else
{
rect.top+=ID_OXGRIPPER_WIDTH;
}
}
}
void COXCoolToolBar::RedrawToolBar(BOOL bRecalcLayout/*=TRUE*/,
BOOL bOnlyFrame/*=FALSE*/)
{
ASSERT(::IsWindow(GetSafeHwnd()));
if(m_bNoInternalRedraw)
{
return;
}
// update custom buttons state
UpdateCustomButtons();
if(!IsWindowVisible())
{
return;
}
if(bRecalcLayout)
{
CFrameWnd* pFrameWnd=GetDockingFrame();
if(pFrameWnd!=NULL)
{
m_bNoBkgndRedraw=TRUE;
pFrameWnd->RecalcLayout();
m_bNoBkgndRedraw=FALSE;
for(int nIndex=0; nIndex<GetToolBarCtrl().GetButtonCount(); nIndex++)
{
RedrawButton(nIndex);
CRect rect;
GetItemRect(nIndex,rect);
ValidateRect(rect);
}
}
}
else
{
if(!bOnlyFrame)
{
RedrawWindow(NULL,NULL,
RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE|RDW_FRAME|RDW_ALLCHILDREN);
}
}
if(bOnlyFrame)
{
SetWindowPos(NULL,0,0,0,0,
SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_DRAWFRAME);
}
}
void COXCoolToolBar::RedrawButton(int nIndex)
{
ASSERT(::IsWindow(GetSafeHwnd()));
if(nIndex<0 || nIndex>GetToolBarCtrl().GetButtonCount())
{
return;
}
CRect rect;
GetItemRect(nIndex,rect);
RedrawWindow(rect);
if(IsCustomButton(nIndex))
{
GetCustomButtonWnd(nIndex)->RedrawWindow(rect);
}
}
CString COXCoolToolBar::GetButtonTooltip(int nButtonIndex) const
{
ASSERT(::IsWindow(m_hWnd));
CString sTooltip(_T(""));
UINT nID=GetItemID(nButtonIndex);
if(nID!=0) // will be zero on a separator
{
TCHAR szFullText[256];
// don't handle the message if no string resource found
if(AfxLoadString(nID,szFullText))
{
AfxExtractSubString(sTooltip,szFullText,1,'\n');
}
}
return sTooltip;
}
BOOL COXCoolToolBar::MoveButton(UINT nOldPos, UINT nNewPos)
{
#if _MFC_VER>=0x0420
ASSERT(::IsWindow(m_hWnd));
if((BOOL)::SendMessage(m_hWnd,TB_MOVEBUTTON,nOldPos,nNewPos))
{
if(IsCustomButton(nNewPos))
{
RedrawToolBar(FALSE,TRUE);
}
return TRUE;
}
else
{
return FALSE;
}
#else
if(nOldPos==nNewPos)
return TRUE;
TBBUTTON button;
if(!GetToolBarCtrl().GetButton(nOldPos,&button))
return FALSE;
if(!GetToolBarCtrl().DeleteButton(nOldPos))
return FALSE;
if(nNewPos>nOldPos)
nNewPos--;
return (GetToolBarCtrl().InsertButton(nNewPos,&button))
#endif
}
int COXCoolToolBar::AddCustomButton(COXCustomTBButtonTemplate* pCBTemplate, int nID,
int nWidth, int nHeight/*=-1*/,
int nFlags/*=OXCBD_SHOWANY*/,
int nImageIndex/*=-1*/)
{
OXCUSTOMBUTTONDESCRIPTOR
descriptor(pCBTemplate,nID,nWidth,nHeight,nFlags,nImageIndex);
return AddCustomButton(descriptor);
}
int COXCoolToolBar::AddCustomButton(OXCUSTOMBUTTONDESCRIPTOR& descriptor)
{
ASSERT(descriptor.m_pCBTemplate!=NULL);
ASSERT(!::IsWindow(descriptor.m_pCBTemplate->CBGetWindow()->GetSafeHwnd()));
OXCUSTOMBUTTONDESCRIPTOR descriptorTest;
if(!m_mapAllCustomButtons.Lookup(descriptor.m_nID,descriptorTest))
{
// add new custom button
m_mapAllCustomButtons.SetAt(descriptor.m_nID,descriptor);
return PtrToInt(m_arrAllCustomButtonIDs.Add(descriptor.m_nID));
}
else
{
// custom button has already been inserted
int nCustomButtonIndex=GetCustomButtonIndex(descriptor.m_nID);
ASSERT(nCustomButtonIndex!=-1);
if(!SetCustomButton(nCustomButtonIndex,descriptor))
{
TRACE(_T("COXCoolToolBar::AddCustomButton: failed to update the descriptor of existing custom button\n"));
return -1;
}
else
{
return nCustomButtonIndex;
}
}
}
BOOL COXCoolToolBar::SetCustomButton(int nCustomButtonIndex,
OXCUSTOMBUTTONDESCRIPTOR& descriptor)
{
if(nCustomButtonIndex<0 || nCustomButtonIndex>=m_arrAllCustomButtonIDs.GetSize())
{
TRACE(_T("COXCoolToolBar::SetCustomButton: specified custom button index is out of range\n"));
return FALSE;
}
int nID=m_arrAllCustomButtonIDs[nCustomButtonIndex];
ASSERT(nID==descriptor.m_nID);
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.Lookup(nID,descriptorOrig));
// copy properties to original button descriptor
VERIFY(descriptorOrig.CopyProperties(descriptor));
m_mapAllCustomButtons.SetAt(nID,descriptorOrig);
// apply the same properties for all copies of specified button
// Iterate all the control bars and use only the toolbars
CFrameWnd* pFrameWnd=DYNAMIC_DOWNCAST(CFrameWnd,AfxGetMainWnd());
if(pFrameWnd!=NULL)
{
POSITION pos=pFrameWnd->m_listControlBars.GetHeadPosition();
while(pos!=NULL)
{
COXCoolToolBar* pCoolToolbar=DYNAMIC_DOWNCAST(COXCoolToolBar,
(CControlBar*)pFrameWnd->m_listControlBars.GetNext(pos));
//If it is a COXCoolToolBar
if(pCoolToolbar!=NULL)
{
POSITION pos=pCoolToolbar->m_mapCustomButtons.GetStartPosition();
while(pos!=NULL)
{
int nIndex=-1;
OXCUSTOMBUTTONDESCRIPTOR descriptorExisting;
pCoolToolbar->
m_mapCustomButtons.GetNextAssoc(pos,nIndex,descriptorExisting);
ASSERT(nIndex!=-1);
if(descriptorExisting.m_nID==descriptor.m_nID)
{
VERIFY(descriptorExisting.CopyProperties(descriptor));
pCoolToolbar->
m_mapCustomButtons.SetAt(nIndex,descriptorExisting);
pCoolToolbar->RedrawToolBar(TRUE,TRUE);
break;
}
}
}
}
}
return TRUE;
}
BOOL COXCoolToolBar::CreateCustomButton(int nCustomButtonIndex,
OXCUSTOMBUTTONDESCRIPTOR& descriptor,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE*/,
DWORD dwStyleEx/*=0*/,
LPCTSTR lpszClassName/*=AfxRegisterWndClass(CS_DBLCLKS)*/,
LPCTSTR lpszWindowName/*=_T("")*/)
{
if(nCustomButtonIndex<0 || nCustomButtonIndex>=m_arrAllCustomButtonIDs.GetSize())
{
TRACE(_T("COXCoolToolBar::CreateCustomButton: specified custom button index is out of range\n"));
return FALSE;
}
int nID=m_arrAllCustomButtonIDs[nCustomButtonIndex];
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.Lookup(nID,descriptorOrig));
// check if any instance of this button has already been created
if(!::IsWindow(descriptorOrig.m_pCBTemplate->CBGetWindow()->GetSafeHwnd()))
{
if(!descriptorOrig.m_pCBTemplate->CBCreate(descriptorOrig.m_nID,this,dwStyle,
dwStyleEx,lpszClassName,lpszWindowName))
{
TRACE(_T("COXCoolToolBar::CreateCustomButton: failed to create custom button\n"));
return FALSE;
}
m_mapAllCustomButtons.SetAt(descriptorOrig.m_nID,descriptorOrig);
descriptor=descriptorOrig;
}
else
{
descriptor=descriptorOrig;
// create a copy of the existing button
descriptor.m_pCBTemplate=
(COXCustomTBButtonWnd<CWnd>*)descriptorOrig.m_pCBTemplate->
CBCreateCopy(this);
if(descriptor.m_pCBTemplate==NULL)
{
TRACE(_T("COXCoolToolBar::CreateCustomButton: failed to create custom button\n"));
return FALSE;
}
}
return TRUE;
}
BOOL COXCoolToolBar::InsertCustomButton(int nIndex, int nCustomButtonIndex,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE*/,
DWORD dwStyleEx/*=0*/,
LPCTSTR lpszClassName/*=AfxRegisterWndClass(CS_DBLCLKS)*/,
LPCTSTR lpszWindowName/*=_T("")*/)
{
if(nIndex<0 || nIndex>GetToolBarCtrl().GetButtonCount())
{
TRACE(_T("COXCoolToolBar::InsertCustomButton: specified index is out of range\n"));
return FALSE;
}
if(nCustomButtonIndex<0 || nCustomButtonIndex>=m_arrAllCustomButtonIDs.GetSize())
{
TRACE(_T("COXCoolToolBar::InsertCustomButton: specified custom button index is out of range\n"));
return FALSE;
}
// add placeholder
TBBUTTON button={ 0 };
button.iBitmap=-1;
button.idCommand=0;
button.fsStyle=TBSTYLE_SEP;
button.iString=-1;
// don't redraw the toolbar contents, we will do it later
m_bNoInternalRedraw=TRUE;
if(!GetToolBarCtrl().InsertButton(nIndex,&button))
{
m_bNoInternalRedraw=FALSE;
TRACE(_T("COXCoolToolBar::InsertCustomButton: failed to insert new button\n"));
return FALSE;
}
m_bNoInternalRedraw=FALSE;
// create new custom button
OXCUSTOMBUTTONDESCRIPTOR descriptorCreated;
if(!CreateCustomButton(nCustomButtonIndex,descriptorCreated,dwStyle,
dwStyleEx,lpszClassName,lpszWindowName))
{
TRACE(_T("COXCoolToolBar::InsertCustomButton: failed to create custom button\n"));
// don't redraw the toolbar contents, we just rollback to the original state
m_bNoInternalRedraw=TRUE;
GetToolBarCtrl().DeleteButton(nIndex);
m_bNoInternalRedraw=FALSE;
return FALSE;
}
// add new custom button
m_mapCustomButtons.SetAt(nIndex,descriptorCreated);
RedrawToolBar(TRUE,TRUE);
return TRUE;
}
int COXCoolToolBar::GetCustomButtonPosition(int nCtrlID) const
{
POSITION pos=m_mapCustomButtons.GetStartPosition();
while(pos!=NULL)
{
int nIndex=-1;
OXCUSTOMBUTTONDESCRIPTOR descriptor;
m_mapCustomButtons.GetNextAssoc(pos,nIndex,descriptor);
ASSERT(nIndex!=-1);
ASSERT(::IsWindow(descriptor.m_pCBTemplate->CBGetWindow()->GetSafeHwnd()));
if(descriptor.m_pCBTemplate->CBGetWindow()->GetDlgCtrlID()==nCtrlID)
{
return nIndex;
}
}
return -1;
}
BOOL COXCoolToolBar::IsCustomButtonWnd(int nCtrlID) const
{
POSITION pos=m_mapCustomButtons.GetStartPosition();
while(pos!=NULL)
{
int nIndex=-1;
OXCUSTOMBUTTONDESCRIPTOR descriptor;
m_mapCustomButtons.GetNextAssoc(pos,nIndex,descriptor);
ASSERT(nIndex!=-1);
ASSERT(::IsWindow(descriptor.m_pCBTemplate->CBGetWindow()->GetSafeHwnd()));
if(descriptor.m_pCBTemplate->CBGetWindow()->GetDlgCtrlID()==nCtrlID)
{
return TRUE;
}
}
return FALSE;
}
BOOL COXCoolToolBar::InsertComboBox(int nIndex, int nCustomButtonIndex,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE|CBS_DROPDOWN|WS_VSCROLL*/,
DWORD dwStyleEx/*=0*/)
{
#ifdef _DEBUG
int nID=m_arrAllCustomButtonIDs[nCustomButtonIndex];
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.Lookup(nID,descriptorOrig));
ASSERT_KINDOF(CComboBox,descriptorOrig.m_pCBTemplate->CBGetWindow());
#endif // _DEBUG
return InsertCustomButton(
nIndex,nCustomButtonIndex,dwStyle,dwStyleEx,_T("ComboBox"));
}
BOOL COXCoolToolBar::InsertEditBox(int nIndex, int nCustomButtonIndex,
LPCTSTR lpszWindowName/*=_T("")*/,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL*/,
DWORD dwStyleEx/*=WS_EX_CLIENTEDGE*/)
{
#ifdef _DEBUG
int nID=m_arrAllCustomButtonIDs[nCustomButtonIndex];
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.Lookup(nID,descriptorOrig));
ASSERT_KINDOF(CEdit,descriptorOrig.m_pCBTemplate->CBGetWindow());
#endif // _DEBUG
return InsertCustomButton(
nIndex,nCustomButtonIndex,dwStyle,dwStyleEx,_T("Edit"),lpszWindowName);
}
BOOL COXCoolToolBar::InsertRichEditBox(int nIndex, int nCustomButtonIndex,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL*/,
DWORD dwStyleEx/*=WS_EX_CLIENTEDGE*/)
{
#ifdef _DEBUG
int nID=m_arrAllCustomButtonIDs[nCustomButtonIndex];
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.Lookup(nID,descriptorOrig));
ASSERT_KINDOF(CRichEditCtrl,descriptorOrig.m_pCBTemplate->CBGetWindow());
#endif // _DEBUG
return InsertCustomButton(
nIndex,nCustomButtonIndex,dwStyle,dwStyleEx,_T("RICHEDIT"));
}
BOOL COXCoolToolBar::InsertStaticCtrl(int nIndex, int nCustomButtonIndex,
LPCTSTR lpszWindowName,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE|SS_LEFT|SS_SIMPLE*/,
DWORD dwStyleEx/*=0*/)
{
#ifdef _DEBUG
int nID=m_arrAllCustomButtonIDs[nCustomButtonIndex];
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.Lookup(nID,descriptorOrig));
ASSERT_KINDOF(CStatic,descriptorOrig.m_pCBTemplate->CBGetWindow());
#endif // _DEBUG
return InsertCustomButton(
nIndex,nCustomButtonIndex,dwStyle,dwStyleEx,_T("Static"),lpszWindowName);
}
BOOL COXCoolToolBar::InsertHotKeyCtrl(int nIndex, int nCustomButtonIndex,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE*/,
DWORD dwStyleEx/*=0*/)
{
#ifdef _DEBUG
int nID=m_arrAllCustomButtonIDs[nCustomButtonIndex];
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.Lookup(nID,descriptorOrig));
ASSERT_KINDOF(CHotKeyCtrl,descriptorOrig.m_pCBTemplate->CBGetWindow());
#endif // _DEBUG
return InsertCustomButton(
nIndex,nCustomButtonIndex,dwStyle,dwStyleEx,_T("msctls_hotkey32"));
}
BOOL COXCoolToolBar::InsertButtonCtrl(int nIndex, int nCustomButtonIndex,
LPCTSTR lpszWindowName,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON*/,
DWORD dwStyleEx/*=0*/)
{
#ifdef _DEBUG
int nID=m_arrAllCustomButtonIDs[nCustomButtonIndex];
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.Lookup(nID,descriptorOrig));
ASSERT_KINDOF(CButton,descriptorOrig.m_pCBTemplate->CBGetWindow());
#endif // _DEBUG
return InsertCustomButton(
nIndex,nCustomButtonIndex,dwStyle,dwStyleEx,_T("Button"),lpszWindowName);
}
BOOL COXCoolToolBar::InsertCheckBox(int nIndex, int nCustomButtonIndex,
LPCTSTR lpszWindowName,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE|BS_CHECKBOX*/,
DWORD dwStyleEx/*=0*/)
{
#ifdef _DEBUG
int nID=m_arrAllCustomButtonIDs[nCustomButtonIndex];
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.Lookup(nID,descriptorOrig));
ASSERT_KINDOF(CButton,descriptorOrig.m_pCBTemplate->CBGetWindow());
#endif // _DEBUG
return InsertCustomButton(
nIndex,nCustomButtonIndex,dwStyle,dwStyleEx,_T("Button"),lpszWindowName);
}
BOOL COXCoolToolBar::InsertProgressBar(int nIndex, int nCustomButtonIndex,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE*/,
DWORD dwStyleEx/*=0*/)
{
#ifdef _DEBUG
int nID=m_arrAllCustomButtonIDs[nCustomButtonIndex];
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.Lookup(nID,descriptorOrig));
ASSERT_KINDOF(CProgressCtrl,descriptorOrig.m_pCBTemplate->CBGetWindow());
#endif // _DEBUG
return InsertCustomButton(
nIndex,nCustomButtonIndex,dwStyle,dwStyleEx,_T("msctls_progress32"));
}
BOOL COXCoolToolBar::InsertSlider(int nIndex, int nCustomButtonIndex,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE|TBS_HORZ*/,
DWORD dwStyleEx/*=0*/)
{
#ifdef _DEBUG
int nID=m_arrAllCustomButtonIDs[nCustomButtonIndex];
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.Lookup(nID,descriptorOrig));
ASSERT_KINDOF(CSliderCtrl,descriptorOrig.m_pCBTemplate->CBGetWindow());
#endif // _DEBUG
return InsertCustomButton(
nIndex,nCustomButtonIndex,dwStyle,dwStyleEx,_T("msctls_trackbar32"));
}
#if _MFC_VER>0x0421
/////////////////////////////////////////////////////////////////////////////////
BOOL COXCoolToolBar::InsertDateTimePicker(int nIndex, int nCustomButtonIndex,
COleDateTime date,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE*/,
DWORD dwStyleEx/*=0*/)
{
// register date-time and mont calendar window classes
INITCOMMONCONTROLSEX icex;
icex.dwSize=sizeof(INITCOMMONCONTROLSEX);
icex.dwICC=ICC_DATE_CLASSES;
::InitCommonControlsEx(&icex);
if(!InsertCustomButton(
nIndex,nCustomButtonIndex,dwStyle,dwStyleEx,_T("SysDateTimePick32")))
{
return FALSE;
}
else
{
CWnd* pWnd=GetCustomButtonWnd(nIndex);
ASSERT(pWnd!=NULL);
CDateTimeCtrl* pDateTimeCtrl=(CDateTimeCtrl*)(pWnd);
pDateTimeCtrl->SetTime(date);
return TRUE;
}
}
BOOL COXCoolToolBar::InsertIPAddressCtrl(int nIndex, int nCustomButtonIndex,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE*/,
DWORD dwStyleEx/*=0*/)
{
#ifdef _DEBUG
int nID=m_arrAllCustomButtonIDs[nCustomButtonIndex];
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.Lookup(nID,descriptorOrig));
ASSERT_KINDOF(CIPAddressCtrl,descriptorOrig.m_pCBTemplate->CBGetWindow());
#endif // _DEBUG
// register date-time and mont calendar window classes
INITCOMMONCONTROLSEX icex;
icex.dwSize=sizeof(INITCOMMONCONTROLSEX);
icex.dwICC=ICC_INTERNET_CLASSES;
::InitCommonControlsEx(&icex);
return InsertCustomButton(
nIndex,nCustomButtonIndex,dwStyle,dwStyleEx,_T("SysIPAddress32"));
}
BOOL COXCoolToolBar::InsertComboBoxEx(int nIndex, int nCustomButtonIndex,
DWORD dwStyle/*=WS_CHILD|WS_VISIBLE|CBS_DROPDOWN*/,
DWORD dwStyleEx/*=0*/)
{
#ifdef _DEBUG
int nID=m_arrAllCustomButtonIDs[nCustomButtonIndex];
OXCUSTOMBUTTONDESCRIPTOR descriptorOrig;
VERIFY(m_mapAllCustomButtons.Lookup(nID,descriptorOrig));
ASSERT_KINDOF(CComboBoxEx,descriptorOrig.m_pCBTemplate->CBGetWindow());
#endif // _DEBUG
return InsertCustomButton(
nIndex,nCustomButtonIndex,dwStyle,dwStyleEx,WC_COMBOBOXEX);
}
/////////////////////////////////////////////////////////////////////////////////
#endif // _MFC_VER>0x0421
BOOL COXCoolToolBar::ShowCustomButton(int nIndex)
{
OXCUSTOMBUTTONDESCRIPTOR descriptor;
if(!GetCustomButton(nIndex,descriptor))
{
TRACE(_T("COXCoolToolBar::ShowCustomButton: there is no custom button at specified index\n"));
return FALSE;
}
BOOL bIsVisible=IsWindowVisible();
BOOL bShowCustomButton=((descriptor.m_nFlags&(OXCBD_SHOWANY))==(OXCBD_SHOWANY));
if(!bShowCustomButton)
{
if(IsFloating())
{
bShowCustomButton=(descriptor.m_nFlags&OXCBD_SHOWFLOAT);
}
else
{
if(m_dwStyle&CBRS_ORIENT_HORZ)
{
bShowCustomButton=(descriptor.m_nFlags&OXCBD_SHOWHORZ);
}
else
{
bShowCustomButton=(descriptor.m_nFlags&OXCBD_SHOWVERT);
}
}
}
if(bShowCustomButton)
{
UINT nIDTest;
UINT nStyleTest;
int nWidthTest;
GetButtonInfo(nIndex,nIDTest,nStyleTest,nWidthTest);
if((nStyleTest&TBBS_SEPARATOR)!=TBBS_SEPARATOR ||
nWidthTest!=descriptor.m_nWidth)
{
SetButtonInfo(
nIndex,descriptor.m_pCBTemplate->CBGetWindow()->GetDlgCtrlID(),
TBBS_SEPARATOR,descriptor.m_nWidth);
}
CRect rect;
GetItemRect(nIndex,&rect);
rect.DeflateRect(2,0);
if(descriptor.m_nHeight>0)
{
if(descriptor.m_nHeight<rect.Height())
{
rect.top+=(rect.Height()-descriptor.m_nHeight)/2;
}
rect.bottom=rect.top+descriptor.m_nHeight;
}
CWnd* pWnd = descriptor.m_pCBTemplate->CBGetWindow();
if (DYNAMIC_DOWNCAST(CComboBox, pWnd))
{
// Center the combo box
RECT rectButton;
GetItemRect(0, &rectButton);
rect.OffsetRect(0, (rectButton.bottom - 22) / 2 + 1);
}
pWnd->MoveWindow(rect,bIsVisible);
pWnd->ShowWindow(SW_SHOWNA);
}
else
{
UINT nIDTest;
UINT nStyleTest;
int nWidthTest;
GetButtonInfo(nIndex,nIDTest,nStyleTest,nWidthTest);
if((nStyleTest&TBBS_SEPARATOR)==TBBS_SEPARATOR ||
(int)nIDTest!=descriptor.m_pCBTemplate->CBGetWindow()->GetDlgCtrlID())
{
#if _MFC_VER > 0x0421
SetButtonInfo(
nIndex,descriptor.m_pCBTemplate->CBGetWindow()->GetDlgCtrlID(),
TBBS_BUTTON,descriptor.m_nImageIndex);
TBBUTTONINFO buttonInfo={ sizeof(TBBUTTONINFO) };
buttonInfo.dwMask=TBIF_STYLE;
if(GetToolBarCtrl().
GetButtonInfo(descriptor.m_pCBTemplate->CBGetWindow()->GetDlgCtrlID(),
&buttonInfo))
{
buttonInfo.fsStyle|=TBSTYLE_AUTOSIZE;
}
else
{
buttonInfo.fsStyle=TBSTYLE_AUTOSIZE;
}
VERIFY(GetToolBarCtrl().
SetButtonInfo(descriptor.m_pCBTemplate->CBGetWindow()->GetDlgCtrlID(),
&buttonInfo));
#else
SetButtonInfo(
nIndex,descriptor.m_pCBTemplate->CBGetWindow()->GetDlgCtrlID(),
TBBS_BUTTON,descriptor.m_nImageIndex);
TBBUTTONINFO buttonInfo={ sizeof(TBBUTTONINFO) };
buttonInfo.dwMask=TBIF_STYLE;
if(GetToolBarCtrl().SendMessage(TB_GETBUTTONINFO,
(WPARAM) descriptor.m_pCBTemplate->CBGetWindow()->GetDlgCtrlID(),
(LPARAM)(LPTBBUTTONINFO) &buttonInfo))
{
buttonInfo.fsStyle|=TBSTYLE_AUTOSIZE;
}
else
{
buttonInfo.fsStyle=TBSTYLE_AUTOSIZE;
}
VERIFY(GetToolBarCtrl().SendMessage(TB_GETBUTTONINFO,
(WPARAM) descriptor.m_pCBTemplate->CBGetWindow()->GetDlgCtrlID(),
(LPARAM)(LPTBBUTTONINFO) &buttonInfo));
#endif
}
descriptor.m_pCBTemplate->CBGetWindow()->ShowWindow(SW_HIDE);
}
if(bIsVisible!=IsWindowVisible())
{
if(bIsVisible)
{
ModifyStyle(0,WS_VISIBLE,SWP_NOREDRAW);
}
else
{
ModifyStyle(WS_VISIBLE,0,SWP_NOREDRAW);
}
}
return TRUE;
}
int COXCoolToolBar::GetCustomButtonIndex(int nCtrlID)
{
for(int nIndex=0; nIndex<m_arrAllCustomButtonIDs.GetSize(); nIndex++)
{
if(m_arrAllCustomButtonIDs[nIndex]==nCtrlID)
{
return nIndex;
}
}
return -1;
}
int COXCoolToolBar::GetCustomButtonIndex(CWnd* pWnd)
{
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
return GetCustomButtonIndex(pWnd->GetDlgCtrlID());
}
void COXCoolToolBar::UpdateCustomButtons(int nFirstButtonIndex/*=0*/,
int nLastButtonIndex/*=-1*/)
{
if(nLastButtonIndex==-1)
{
nLastButtonIndex=GetToolBarCtrl().GetButtonCount()-1;
}
for(int nIndex=nFirstButtonIndex; nIndex<=nLastButtonIndex; nIndex++)
{
OXCUSTOMBUTTONDESCRIPTOR descriptor;
if(m_mapCustomButtons.Lookup(nIndex,descriptor))
{
ShowCustomButton(nIndex);
}
}
}
HRESULT COXCoolToolBar::GetComCtlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor) const
{
if(IsBadWritePtr(pdwMajor, sizeof(DWORD)) ||
IsBadWritePtr(pdwMinor, sizeof(DWORD)))
{
return E_INVALIDARG;
}
// get handle of the common control DLL
BOOL bAlreadyLoaded=TRUE;
HINSTANCE hComCtl=::GetModuleHandle(_T("comctl32.dll"));
if(hComCtl==NULL)
{
// load the DLL
hComCtl=::LoadLibrary(_T("comctl32.dll"));
bAlreadyLoaded=FALSE;
}
if(hComCtl)
{
HRESULT hr=S_OK;
DLLGETVERSIONPROC pDllGetVersion;
/*
You must get this function explicitly because earlier versions of the DLL
don't implement this function. That makes the lack of implementation of the
function a version marker in itself.
*/
pDllGetVersion=(DLLGETVERSIONPROC)GetProcAddress(hComCtl, "DllGetVersion");
if(pDllGetVersion)
{
DLLVERSIONINFO dvi;
ZeroMemory(&dvi, sizeof(dvi));
dvi.cbSize=sizeof(dvi);
hr = (*pDllGetVersion)(&dvi);
if(SUCCEEDED(hr))
{
*pdwMajor = dvi.dwMajorVersion;
*pdwMinor = dvi.dwMinorVersion;
}
else
{
hr = E_FAIL;
}
}
else
{
// If GetProcAddress failed, then the DLL is a version previous
// to the one shipped with IE 3.x.
*pdwMajor = 4;
*pdwMinor = 0;
}
if(!bAlreadyLoaded)
::FreeLibrary(hComCtl);
return hr;
}
return E_FAIL;
}
#if _MFC_VER >= 0x0700
void COXCoolToolBar::DrawBorders(CDC* pDC, CRect& rect)
{
ASSERT_VALID(this);
ASSERT_VALID(pDC);
DWORD dwStyle = m_dwStyle;
if (!(dwStyle & CBRS_BORDER_ANY))
return;
// prepare for dark lines
ASSERT(rect.top == 0 && rect.left == 0);
CRect rect1, rect2;
rect1 = rect;
rect2 = rect;
COLORREF clr = afxData.clrBtnShadow;
// draw dark line one pixel back/up
if (dwStyle & CBRS_BORDER_3D)
{
rect1.right -= CX_BORDER;
rect1.bottom -= CY_BORDER;
}
if (dwStyle & CBRS_BORDER_TOP)
rect2.top += afxData.cyBorder2;
if (dwStyle & CBRS_BORDER_BOTTOM)
rect2.bottom -= afxData.cyBorder2;
// draw left and top
if (dwStyle & CBRS_BORDER_LEFT)
pDC->FillSolidRect(0, rect2.top, CX_BORDER, rect2.Height(), clr);
if (dwStyle & CBRS_BORDER_TOP)
pDC->FillSolidRect(0, 0, rect.right, CY_BORDER, clr);
// draw right and bottom
if (dwStyle & CBRS_BORDER_RIGHT)
pDC->FillSolidRect(rect1.right, rect2.top, -CX_BORDER, rect2.Height(), clr);
if (dwStyle & CBRS_BORDER_BOTTOM)
pDC->FillSolidRect(0, rect1.bottom, rect.right, -CY_BORDER, clr);
if (dwStyle & CBRS_BORDER_3D)
{
// prepare for hilite lines
clr = afxData.clrBtnHilite;
// draw left and top
if (dwStyle & CBRS_BORDER_LEFT)
pDC->FillSolidRect(1, rect2.top, CX_BORDER, rect2.Height(), clr);
if (dwStyle & CBRS_BORDER_TOP)
pDC->FillSolidRect(0, 1, rect.right, CY_BORDER, clr);
// draw right and bottom
if (dwStyle & CBRS_BORDER_RIGHT)
pDC->FillSolidRect(rect.right, rect2.top, -CX_BORDER, rect2.Height(), clr);
if (dwStyle & CBRS_BORDER_BOTTOM)
pDC->FillSolidRect(0, rect.bottom, rect.right, -CY_BORDER, clr);
}
if (dwStyle & CBRS_BORDER_LEFT)
rect.left += afxData.cxBorder2;
if (dwStyle & CBRS_BORDER_TOP)
rect.top += afxData.cyBorder2;
if (dwStyle & CBRS_BORDER_RIGHT)
rect.right -= afxData.cxBorder2;
if (dwStyle & CBRS_BORDER_BOTTOM)
rect.bottom -= afxData.cyBorder2;
}
#endif // _MFC_VER >= 0x0700
////////////////////////////////
#endif //_MFC_VER>=0x0420
COXToolbarSkin* COXCoolToolBar::GetToolbarSkin()
{
// Check if the app is derived from COXSkinnedApp
COXSkinnedApp* pSkinnedApp = DYNAMIC_DOWNCAST(COXSkinnedApp, AfxGetApp());
if (pSkinnedApp != NULL && pSkinnedApp->GetCurrentSkin() != NULL)
return pSkinnedApp->GetCurrentSkin()->GetToolbarSkin();
else
{
// Create a classic skin for this class if not created already
if (m_pToolbarSkin == NULL)
m_pToolbarSkin = new COXToolbarSkinClassic();
return m_pToolbarSkin;
}
}
BOOL COXCoolToolBar::OnDropDownButton(NMHDR* pNMHDR, LRESULT* result)
{
// Save the index of the last drop down button
LPNMTOOLBAR pNMToolBar = (LPNMTOOLBAR) pNMHDR;
m_iDropDownIndex = pNMToolBar->iItem;
m_iLastDropDownIndex = pNMToolBar->iItem;
result = 0;
return FALSE;
}
BOOL COXCoolToolBar::IsFloatingEnabled()
{
return m_bFloatingEnabled;
}
void COXCoolToolBar::EnableFloating(BOOL bEnable)
{
m_bFloatingEnabled = bEnable;
}
void COXCoolToolBar::EnableDocking(DWORD dwDockStyle, BOOL bSnapWhileDragging)
{
// must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);
// CBRS_SIZE_DYNAMIC toolbar cannot have the CBRS_FLOAT_MULTI style
ASSERT(((dwDockStyle & CBRS_FLOAT_MULTI) == 0) || ((m_dwStyle & CBRS_SIZE_DYNAMIC) == 0));
m_dwDockStyle = dwDockStyle;
if (m_pDockContext == NULL)
m_pDockContext = new CDockContext(this);
// permanently wire the bar's owner to its current parent
if (m_hWndOwner == NULL)
m_hWndOwner = ::GetParent(m_hWnd);
m_bSnapWhileDragging = bSnapWhileDragging;
}
void COXCoolToolBar::SaveMouseOffset(CPoint point)
{
// Calculate and save the offset
CRect rectWindow;
GetWindowRect(rectWindow);
ScreenToClient(&rectWindow);
m_ptOffset = point - rectWindow.TopLeft();
}