如何使 CMFCToolBarComboBoxButton 能够在垂直模式下工作? [英] How to make CMFCToolBarComboBoxButton able to works in vertical mode?

查看:67
本文介绍了如何使 CMFCToolBarComboBoxButton 能够在垂直模式下工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

MFC Feature Pack 工具栏组合按钮(class CMFCToolBarComboBoxButton)在水平工具栏模式下工作完美.但在垂直布局模式下,它是简单的按钮,没有组合框功能.

如何使

垂直模式

课程代码:

class CVerticalableToolBarComboBoxButton:公共 CMFCToolBarComboBoxButton{DECLARE_SERIAL(CVerticalableToolBarComboBoxButton)上市:typedef CMFCToolBarComboBoxButton TBase;受保护:bool m_bDoVerticalMode;上市:CVerticalableToolBarComboBoxButton(bool bDoVerticalMode = true);CVerticalableToolBarComboBoxButton(UINT uiID, int iImage, DWORD dwStyle = CBS_DROPDOWNLIST, int iWidth = 0, bool bDoVerticalMode = true);虚拟 ~CVerticalableToolBarComboBoxButton();虚拟无效序列化(CArchive& ar);虚拟 BOOL OnClick(CWnd* pWnd, BOOL bDelay = TRUE);虚拟无效 OnChangeParentWnd(CWnd* pWndParent);虚空 OnMove();虚拟无效 OnSize(int iSize);受保护:void AdjustVerticalRect();};///////////////////////////////////////////////////////////////////////////////CVerticalableToolBarComboBoxButton实现序列(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);如果(ar.IsLoading()){>>m_bDoVerticalMode;}别的 {ar<SetFocus();}别的 {m_pWndEdit->SetFocus();}m_pWndCombo->ShowDropDown();如果(pWnd!= NULL){pWnd->InvalidateRect(m_rectCombo);}bRes = TRUE;}}如果(b默认){bRes = TBase::OnClick(pWnd, bDelay);}返回 bRes;}void CVerticalableToolBarComboBoxButton::OnChangeParentWnd(CWnd* pWndParent){TBase::OnChangeParentWnd(pWndParent);如果 (!m_bHorz & m_bDoVerticalMode) {调整垂直矩形();}}void CVerticalableToolBarComboBoxButton::OnMove(){TBase::OnMove();如果 (!m_bHorz & m_bDoVerticalMode) {调整垂直矩形();}}void CVerticalableToolBarComboBoxButton::OnSize(int iSize){TBase::OnSize(iSize);如果 (!m_bHorz & m_bDoVerticalMode) {调整垂直矩形();}}void CVerticalableToolBarComboBoxButton::AdjustVerticalRect(){断言(m_bDoVerticalMode);断言(!m_bHorz);if (m_pWndCombo->GetSafeHwnd() == NULL || m_rect.IsRectEmpty()) {m_rectCombo.SetRectEmpty();m_rectButton.SetRectEmpty();返回;}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 矩形;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();如果(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);}如果(m_bFlat){m_rectButton = m_rectCombo;}别的 {m_rectButton.SetRectEmpty();}}//CVerticalableToolBarComboBoxButton////////////////////////////////////////////////////////////////////////////

The MFC Feature Pack toolbar combo-button (class CMFCToolBarComboBoxButton) works perfectly in horizontal toolbar mode. But in vertical layout mode it is the simple press button without combobox feature.

How to make CMFCToolBarComboBoxButton able to works in vertical mode?

解决方案

This my solution. I overwrote the behavior of the buttons in vertical mode. And now the button shows combobox drop down window when it is pressed in vertical mode.

You should use class CVerticalableToolBarComboBoxButton instead of CMFCToolBarComboBoxButton in ReplaceButton() method when you add combobox button to your toolbar.

Example: In the images below you can see the behavior of the buttons in the horizontal and vertical modes.

Horizontal mode

Vertical mode

Class code:

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 能够在垂直模式下工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆