如何使 CMFCToolBarComboBoxButton 能够在垂直模式下工作?

Posted

技术标签:

【中文标题】如何使 CMFCToolBarComboBoxButton 能够在垂直模式下工作?【英文标题】:How to make CMFCToolBarComboBoxButton able to works in vertical mode? 【发布时间】:2015-12-08 15:58:49 【问题描述】:

MFC 功能包工具栏组合按钮(CMFCToolBarComboBoxButton 类)在水平工具栏模式下完美运行。但在垂直布局模式下,它是没有组合框功能的简单按钮。

如何让CMFCToolBarComboBoxButton能够在垂直模式下工作?

【问题讨论】:

【参考方案1】:

这是我的解决方案。我在垂直模式下覆盖了按钮的行为。现在该按钮在垂直模式下按下时会显示组合框下拉窗口。

当您将组合框按钮添加到工具栏时,您应该在 ReplaceButton() 方法中使用 CVerticalableToolBarComboBoxButton 类而不是 CMFCToolBarComboBoxButton。

示例:在下图中,您可以看到按钮在水平和垂直模式下的行为。

水平模式

垂直模式

类代码:

class CVerticalableToolBarComboBoxButton
    : public CMFCToolBarComboBoxButton

    DECLARE_SERIAL(CVerticalableToolBarComboBoxButton)

public:
    typedef CMFCToolBarComboBoxButton TBase;

protected:

    bool                m_bDoVerticalMode;

public:
    CVerticalableToolBarComboBoxButton(bool bDoVerticalMode = true);
    CVerticalableToolBarComboBoxButton(UINT uiID, int iImage, DWORD dwStyle = CBS_DROPDOWNLIST, int iWidth = 0, bool bDoVerticalMode = true);

    virtual ~CVerticalableToolBarComboBoxButton();

    virtual void Serialize(CArchive& ar);

    virtual BOOL OnClick(CWnd* pWnd, BOOL bDelay = TRUE);
    virtual void OnChangeParentWnd(CWnd* pWndParent);
    virtual void OnMove();
    virtual void OnSize(int iSize);

protected:
    void AdjustVerticalRect();
;


/////////////////////////////////////////////////////////////////////////////
// CVerticalableToolBarComboBoxButton
IMPLEMENT_SERIAL(CVerticalableToolBarComboBoxButton, CVerticalableToolBarComboBoxButton::TBase, VERSIONABLE_SCHEMA | 1)

    CVerticalableToolBarComboBoxButton::CVerticalableToolBarComboBoxButton(bool bDoVerticalMode /*= true*/)
    : m_bDoVerticalMode(bDoVerticalMode)


CVerticalableToolBarComboBoxButton::CVerticalableToolBarComboBoxButton(UINT uiID, int iImage, DWORD dwStyle /*= CBS_DROPDOWNLIST*/, int iWidth /*= 0*/, bool bDoVerticalMode /*= true*/)
    : TBase(uiID, iImage, dwStyle, iWidth)
    , m_bDoVerticalMode(bDoVerticalMode)


CVerticalableToolBarComboBoxButton::~CVerticalableToolBarComboBoxButton()


void CVerticalableToolBarComboBoxButton::Serialize(CArchive& ar)

    TBase::Serialize(ar);

    if (ar.IsLoading()) 
        ar >> m_bDoVerticalMode;
    
    else 
        ar << m_bDoVerticalMode;
    


BOOL CVerticalableToolBarComboBoxButton::OnClick(CWnd* pWnd, BOOL bDelay /*= TRUE*/)

    BOOL bRes = FALSE;

    bool bDefault = m_bHorz || !m_bDoVerticalMode;
    if (!bDefault) 
        if (IsFlatMode()) 

            if (m_pWndEdit == NULL) 
                m_pWndCombo->SetFocus();
            
            else 
                m_pWndEdit->SetFocus();
            

            m_pWndCombo->ShowDropDown();

            if (pWnd != NULL) 
                pWnd->InvalidateRect(m_rectCombo);
            

            bRes = TRUE;
        
    

    if (bDefault) 
        bRes = TBase::OnClick(pWnd, bDelay);
    

    return bRes;


void CVerticalableToolBarComboBoxButton::OnChangeParentWnd(CWnd* pWndParent)

    TBase::OnChangeParentWnd(pWndParent);

    if (!m_bHorz & m_bDoVerticalMode) 
        AdjustVerticalRect();
    


void CVerticalableToolBarComboBoxButton::OnMove()

    TBase::OnMove();

    if (!m_bHorz & m_bDoVerticalMode) 
        AdjustVerticalRect();
    


void CVerticalableToolBarComboBoxButton::OnSize(int iSize)

    TBase::OnSize(iSize);

    if (!m_bHorz & m_bDoVerticalMode) 
        AdjustVerticalRect();
    


void CVerticalableToolBarComboBoxButton::AdjustVerticalRect()

    ASSERT(m_bDoVerticalMode);
    ASSERT(!m_bHorz);

    if (m_pWndCombo->GetSafeHwnd() == NULL || m_rect.IsRectEmpty()) 

        m_rectCombo.SetRectEmpty();
        m_rectButton.SetRectEmpty();
        return;
    

    CMFCToolBar* pParentBar = nullptr;
    
        CWnd* pNextBar = m_pWndCombo->GetParent();
        while (pParentBar == nullptr && pNextBar != nullptr) 
            pParentBar = DYNAMIC_DOWNCAST(CMFCToolBar, pNextBar);
            pNextBar = pNextBar->GetParent();
        
    

    if (IsCenterVert() && (!m_bTextBelow || m_strText.IsEmpty()) && (pParentBar != nullptr))
    
        const int nRowHeight = pParentBar->GetRowHeight();
        const int yOffset = std::max<>(0, (nRowHeight - m_rect.Height()) / 2);

        m_rect.OffsetRect(0, yOffset);
    


    CRect rect;
    m_pWndCombo->GetWindowRect(&rect);
    const int nWidth = std::max<>(rect.Width(), m_iWidth);

    rect.left = m_rect.left;
    rect.top = m_rect.top;
    rect.right = m_rect.left + nWidth;
    rect.bottom = m_rect.top + m_nDropDownHeight;

    if ((pParentBar != nullptr) && pParentBar->IsDocked()) 
        const UINT nID = pParentBar->GetParentDockSite()->GetDockSiteID();
        if (nID == AFX_IDW_DOCKBAR_RIGHT) 
            rect.left = m_rect.right - nWidth;
            rect.right = m_rect.right;
        
    

    m_pWndCombo->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER | SWP_NOACTIVATE);
    m_pWndCombo->SetEditSel(-1, 0);



    m_pWndCombo->GetWindowRect(&m_rectCombo);
    m_pWndCombo->ScreenToClient(&m_rectCombo);
    m_pWndCombo->MapWindowPoints(m_pWndCombo->GetParent(), &m_rectCombo);



if (m_bFlat) 
    m_rectButton = m_rectCombo;

else 
    m_rectButton.SetRectEmpty();



// CVerticalableToolBarComboBoxButton
/////////////////////////////////////////////////////////////////////////////

【讨论】:

以上是关于如何使 CMFCToolBarComboBoxButton 能够在垂直模式下工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 RelativeLayout 半透明但不使活动

如何用word使图片上下居中

如何使图像自动调整大小,使宽度为 100% 并相应调整高度?

如何使 UISegmentedcontrol 透明?

如何使 textarea 填充 div 块?

如何使 UITableViewCell 显示为禁用?