// CEditBar.h

 // 可调用InsertControl向工具栏添加控件,调用HideButton来隐藏button或控件

 CToolBar
{
public:
 
    CEditorBar();
    
virtual ~CEditorBar();

    BOOL        m_bHideChildWndOnVertical;    
// Hide the windows when docked vertical            

    BOOL CreateEx(CWnd
* pParentWnd,DWORD dwCtrlStyle = TBSTYLE_FLAT,DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP);
    LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
    
    CWnd
* InsertControl(CRuntimeClass* pClass,LPCTSTR lpszWindowName,CRect& rect,UINT nID,DWORD dwStyle );
    CWnd
* InsertControl(CWnd* pCtrl,CRect& rect,UINT nID);
    BOOL HideButton( 
int nID, BOOL bHide = TRUE  );


protected:
    CObList
*            m_pControls;            // CObject pointer list which contains controls added to the toolbar
    map<int, CWnd*>        m_mapID2Ctrl;

    BOOL IsVertDocked();


    DECLARE_MESSAGE_MAP()
    DECLARE_EVENTSINK_MAP()
};

 // CEditBar.cpp

CEditorBar::CEditorBar()
{
    m_pControls = NULL;
}

CEditorBar::
~CEditorBar()
{
    
if( m_pControls ) 
    {
        
for( POSITION pos = m_pControls->GetHeadPosition() ; pos ; ) 
        {
            delete m_pControls
->GetNext(pos);
        }

        delete m_pControls;
    }
    m_mapID2Ctrl.clear();
}


BOOL CEditorBar::CreateEx(CWnd
* pParentWnd,DWORD dwCtrlStyle,DWORD dwStyle)
{
   
if (!CToolBar::CreateEx(pParentWnd,dwCtrlStyle,dwStyle) || !LoadToolBar(IDR_MAINFRAME))
        
return FALSE;

    
return TRUE;
}

// Since we're inside an ActiveX control, we don't own the message
// loop. Thus, the CWnd::PreTranslateMessage function is not called.
// As a result, we must manually call the FilterToolTipMessage()
// function to get tooltips. If you don't care about tooltips then
// you can remove this function from your toolbar.

BEGIN_MESSAGE_MAP(CEditorBar, CToolBar)
    
//{{AFX_MSG_MAP(CEditorBar)
    
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BEGIN_EVENTSINK_MAP(CEditorBar, CToolBar)
    
//{{AFX_EVENTSINK_MAP(CEditorBar)
    
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()


LRESULT CEditorBar::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
//AFX_MANAGE_STATE( AfxGetStaticModuleState() );
//#ifndef _DEBUG

    MSG msg;
    msg.hwnd 
= m_hWnd;
    msg.message 
= message;
    msg.wParam 
= wParam;
    msg.lParam 
= lParam;

    GetCursorPos(
&msg.pt);
    FilterToolTipMessage(
&msg);
//#endif //_DEBUG        
    return CToolBar::WindowProc(message,wParam,lParam);
}

//Inserts a control into the toolbar at the given button id.
CWnd* CEditorBar::InsertControl( CRuntimeClass* pClass, LPCTSTR lpszWindowName, CRect& rect, UINT nID, DWORD dwStyle )
{
    CWnd 
*pCtrl = NULL;
    
    
if( pClass->IsDerivedFrom( RUNTIME_CLASS( CSymbolCombo )))    // CComboBox control.
    {
        pCtrl 
= new CSymbolCombo;

        ASSERT_VALID( pCtrl );

        
if(((CSymbolCombo*)pCtrl)->Create( WS_CHILD|WS_VISIBLE|dwStyle, rect, this, nID ) == FALSE )
        {
            delete pCtrl;
            
return NULL;
        }
    }
else if( pClass->IsDerivedFrom( RUNTIME_CLASS( CEdit )))        // CEdit control.
    {
        pCtrl 
= new CEdit;
                            
        ASSERT_VALID( pCtrl );

        
if(((CEdit*)pCtrl)->Create( WS_CHILD|WS_VISIBLE|dwStyle, rect, this, nID ) == FALSE )
        {
            delete pCtrl;
            
return NULL;
        }
    }
    
else if( pClass->IsDerivedFrom( RUNTIME_CLASS( CButton )))        // CButton control.
    {
        pCtrl 
= new CButton;

        ASSERT_VALID( pCtrl );

        
if(((CButton*)pCtrl)->Create( lpszWindowName, WS_CHILD|WS_VISIBLE|dwStyle, rect, this, nID ) == FALSE )
        {
            delete pCtrl;
            
return NULL;
        }
    }
    
else if( pClass->IsDerivedFrom( RUNTIME_CLASS( CWnd )))            // CWnd object.
    {
        pCtrl 
= new CWnd;
        
        ASSERT_VALID( pCtrl );

#ifdef _UNICODE
        TCHAR szClassName[ 
256 ];

        MultiByteToWideChar( CP_ACP,
                             MB_PRECOMPOSED,
                             pClass
->m_lpszClassName,
                             
-1,
                             szClassName,
                             
255 );

        
if(((CWnd*)pCtrl)->Create( szClassName, lpszWindowName, WS_CHILD|WS_VISIBLE|dwStyle, rect, this, nID ) == FALSE )
        {
            delete pCtrl;
            
return NULL;
        }
#else
        
if(((CWnd*)pCtrl)->Create( pClass->m_lpszClassName, lpszWindowName, WS_CHILD|WS_VISIBLE|dwStyle, rect, this, nID ) == FALSE )
        {
            delete pCtrl;
            
return NULL;
        }
#endif
    }
    
else    // An invalid object was passed in
    {
        ASSERT( FALSE );
        
return NULL;
    }

    
return InsertControl( pCtrl, rect, nID );
}

CWnd
* CEditorBar::InsertControl(CWnd* pCtrl, CRect & rect, UINT nID)
{
    ASSERT_VALID( pCtrl );
    ASSERT(IsWindow(pCtrl
->m_hWnd));

    
// make sure the id is valid, and set the button 
    
// style for a seperator.
    int nIndex = CommandToIndex( nID ) ;
    
if (nIndex>-1)
    {
        ASSERT( nIndex 
>= 0 );
        SetButtonInfo( nIndex, nID, TBBS_SEPARATOR, rect.Width());
        
// insert the control into the toolbar.
        GetItemRect( nIndex, &rect );
        CRect rt;
        pCtrl
->GetWindowRect(&rt);
        rect.top
+=max((rect.Height()-rt.Height())/2,0);     //move to middle
        pCtrl->SetWindowPos(0, rect.left, rect.top, 00,
            SWP_NOZORDER 
| SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOCOPYBITS );
        pCtrl
->SetFont( GetFont( ));

        BOOL bVert 
=  IsVertDocked(); //(m_dwStyle & CBRS_ORIENT_VERT) != 0;

        
if (bVert && m_bHideChildWndOnVertical)
        {
               
int nState=GetToolBarCtrl().GetState(nIndex);
               GetToolBarCtrl().SetState(nID,(nState 
| TBSTATE_HIDDEN));
            pCtrl
->ShowWindow( SW_HIDE );
        }
        
else
        {
               
int nState=GetToolBarCtrl().GetState(nIndex);
               GetToolBarCtrl().SetState(nIndex,(nState 
& ~TBSTATE_HIDDEN));
            pCtrl
->ShowWindow( SW_SHOW );
        }

    }
    
else
    {
        pCtrl
->ShowWindow( SW_HIDE);
    }

    ModifyStyle(
0,WS_CLIPCHILDREN);

    
// if our object list has not been allocated, do it nowMFC toolbar上添加其他控件
    if( m_pControls == NULL )
    {
        m_pControls 
= new CObList();
        ASSERT( m_pControls );
    }

    
// we have to remember this control, so we can delete it later
    m_pControls->AddTail( pCtrl );

    m_mapID2Ctrl[nID] 
= pCtrl;

    
return pCtrl;
}
// 支持运行时隐藏button或控件
BOOL CEditorBar::HideButton( int nID, BOOL bHide)
{
    
int ix = -1;
    CRect rect;
    
    BOOL bSuccess 
= FALSE;
    CToolBarCtrl 
&toolbar = this->GetToolBarCtrl();
     
    
if (bHide) // to hide
    {
        ix 
= CommandToIndex(nID);
        GetItemRect(ix, 
&rect);
        bSuccess 
= toolbar.HideButton(nID, bHide);
    }
    
else // to show
    {
        bSuccess 
= toolbar.HideButton(nID, bHide);
        ix 
= CommandToIndex(nID);
        GetItemRect(ix, 
&rect);
    }

    map
<int, CWnd*>    ::iterator iter = m_mapID2Ctrl.begin();
    
for( ; iter != m_mapID2Ctrl.end(); ++iter) 
    {
        
int nCtrlID =  (*iter).first;
        CWnd 
*pCtrl = (*iter).second;
        
int ixCtrl = this->CommandToIndex(nCtrlID);
        
// skip controls which are before this nID
        if (ixCtrl <= ix)
        {
            
continue;
        }

        
if (pCtrl && ::IsWindow(pCtrl->m_hWnd) )
        {
            CRect rcCtrl;
            pCtrl
->GetWindowRect(&rcCtrl);
            
this->ScreenToClient(&rcCtrl);
            
int nLeft = rcCtrl.left;
            
if (bHide) // to hide
            {
                nLeft 
= rcCtrl.left - rect.Width();
            } 
            
else // to show
            {
                nLeft 
= rcCtrl.left + rect.Width();
            }
            pCtrl
->SetWindowPos(0, nLeft, rcCtrl.top, 00,
                SWP_NOZORDER 
| SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOCOPYBITS );
        }
    }
        
    
return bSuccess;
}

BOOL CEditorBar::IsVertDocked()
{
    UINT nID 
=GetParent()->GetDlgCtrlID();
    
return ( (nID ==AFX_IDW_DOCKBAR_LEFT) || (nID== AFX_IDW_DOCKBAR_RIGHT));
}

 

相关文章: