如何使 CMFCToolBarComboBoxButton 能够在垂直模式下工作? [英] How to make CMFCToolBarComboBoxButton able to works in vertical mode?
问题描述
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屋!