// OXCoolToolBar.cpp : implementation file // // Version: 9.3 #include "stdafx.h" #include #include "OXCoolToolBar.h" #include "UTBStrOp.h" #ifdef OX_CUSTOMIZE_COMMANDS #include "OXDragDropCommands.h" #endif // OX_CUSTOMIZE_COMMANDS #if _MFC_VER>0x0421 #include #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 COXCoolToolBar::m_mapAllCustomButtons; CArray 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); } LONG 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); } LONG 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; } LONG 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; } LONG 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(nDraggedButtonIndex0 && ((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(nButtonIndex0 && 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=0 && nButtonIndex= 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=0 && nButtonIndex= 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 && nButtonIndex0 && ((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=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 && nIndexCBSetCustomizationMode(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(nIndextbButton.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 && nIndexhdr.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; iGetButtonCount(); 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; nIndex0); 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; nCustomButtonIndexCBGetWindow()->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 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 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 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; nIndexGetToolBarCtrl().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*)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_nHeightCBGetWindow(); 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; nIndexGetSafeHwnd())); 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(); }