如何使 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 能够在垂直模式下工作?的主要内容,如果未能解决你的问题,请参考以下文章