3

我有 4 个按钮没有直接应用于我的程序。我想隐藏或删除它们。我已经搜索到它们被称为什么......它们看起来像导航,左/右箭头,下一个/上一个。我似乎找不到他们叫什么。我在微软网站上看过,看着CTabView成员似乎并没有跳出来说“嘿,这些就是你要找的东西”....

我想删除的按钮

我希望这是一个相对容易的任务。有人知道如何“关闭它们”吗?

谢谢。

更新:

我能够通过在现有功能之前移动新功能来解决提到的 C4430,OutputWnd.h并且解决了箭头现在消失的输出窗格区域中的问题。我忘了提到的是我有另一种机制AddView,它创建 2 个运行时类并将它们放入选项卡式文档视图中。这一次,我一直在使用GetTabControl()它来让它变得漂亮,但这也遇到了同样的问题,滚动箭头现在出现了。

这是创建 2 个新选项卡的代码的样子:

Above this code is the constructor/destructor/headers, nothing else.

IMPLEMENT_DYNCREATE(CTrackView, CTabView)

void CTrackView::OnInitialUpdate()
{

    // add document views   
    AddView(RUNTIME_CLASS(CTrainView), AfxStringID(IDS_TRAIN));
    AddView(RUNTIME_CLASS(CStationView), AfxStringID(IDS_STATION));
    GetTabControl().EnableTabSwap(TRUE);
    GetTabControl().SetLocation(CMFCBaseTabCtrl::Location::LOCATION_BOTTOM);
    GetTabControl().ModifyTabStyle(CMFCTabCtrl::STYLE_3D);
    GetTabControl().SetActiveTabBoldFont(TRUE);

    CTabView::OnInitialUpdate();
    
}

我试图发表评论,CTabView::OnInitialUpdate();但我知道它不会也不会影响箭头。我对控件进行了一些搜索,但没有看到任何删除箭头的示例,我假设另一个覆盖是有序的。我将遵循另一个示例中显示的方法,我正在寻找是否可以修复它,类似于已显示的内容。

这些是否共享相同的CMFCTabCtrl机制或者这是不同的东西?

更新 2:

MFC 向导创建的 OutputWnd.cpp 具有相同的问题,因为我已经修改了选项卡控件,我找不到正确的指针来解决&tabCtrl()未知标识符的问题。编辑:这是问题,我找到了修复,请参阅更新 3 以查看解决方案。

int COutputWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CDockablePane::OnCreate(lpCreateStruct) == -1)
        return -1;

    CRect rectDummy;
    rectDummy.SetRectEmpty();

    // Create User Define tab style:
    int UserTabStyle = AfxGetApp()->GetProfileInt(_T("Settings"), _T("UserTabStyle"), 0); //Get value from registry
    // If the key doesn't exist, UserTableStyle will be 0 or FALSE;

    if (UserTabStyle != FALSE && UserTabStyle <= 8) { // User selected tab style type

        int EnumUserTabStyle = UserTabStyle - 1; // Fix enum if key doesn't exist.

        if (!m_wndTabs.Create(static_cast<CMFCTabCtrl::Style>(EnumUserTabStyle), rectDummy, this, 1))
        {
            TRACE0("Failed to create output tab window\n");
            return -1;      // fail to create
        }
    }
    else { // Default tabs style if Reg key does not exist i.e. new install/program reset
        
        if (!m_wndTabs.Create(CMFCTabCtrl::STYLE_FLAT, rectDummy, this, 1))
            {
                TRACE0("Failed to create output tab window\n");
                return -1;      // fail to create
            }
    }

    // Nicely hack to access protected member
    class CMFCTabCtrlEx : public CMFCTabCtrl
    {
    public:
        void SetDisableScroll() { m_bScroll = FALSE; }
    };

    // One-Liner to Disable navigation control
    ((CMFCTabCtrlEx*)&tabCtrl())->SetDisableScroll();

    // Create output panes:
    const DWORD dwStyle = LBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | WS_BORDER;

    if (!m_wndOutputBuild.Create(dwStyle, rectDummy, &m_wndTabs, 2) ||
        !m_wndOutputDebug.Create(dwStyle, rectDummy, &m_wndTabs, 3))
    {
        TRACE0("Failed to create output windows\n");
        return -1;      // fail to create
    }   

    UpdateFonts();

    CString strTabName;
    BOOL bNameValid;

    //Attach list windows to tab:
    bNameValid = strTabName.LoadString(IDS_STATUS_TAB);
    ASSERT(bNameValid);
    m_wndTabs.AddTab(&m_wndOutputBuild, strTabName, (UINT)0);

    bNameValid = strTabName.LoadString(IDS_DEBUG_TAB);
    ASSERT(bNameValid);
    m_wndTabs.AddTab(&m_wndOutputDebug, strTabName, (UINT)1);

    int EnableDebugTab = AfxGetApp()->GetProfileInt(_T("Settings"), _T("EnableDebugTab"), 0); //Get value from registry
    if (EnableDebugTab == FALSE)
    {
        OnOutputtabsDebug(); //Check to see if it should be enabled
    }

    return 0;
}

更新 3:

我找到了未知标识符的答案,我试图调用一个不存在的函数。像这样进行了改革,它按预期工作:

// Nicely hack to access protected member
class CMFCTabCtrlEx : public CMFCTabCtrl
{
public:
    void SetDisableScroll() { m_bScroll = FALSE; }
};

// One-Liner to Disable navigation control
((CMFCTabCtrlEx*)&m_wndTabs)->SetDisableScroll();
4

2 回答 2

3

没有公开的、记录在案的 API 来隐藏这些导航按钮。然而,深入研究 MFC 的源代码后发现:

  • 箭头CMFCTabButton m_btnScrollLeft, m_btnScrollRight, m_btnScrollFirst, m_btnScrollLast;CMFCTabCtrl

  • 它们是在CMFCTabCtrl::OnCreate任何时候创建CMFCTabCtrl::m_bScrollTRUE

  • CMFCTabCtrl::m_bScroll如果使用任何样式、、、、或,则设置为TRUEin 。CMFCTabCtrl::CreateSTYLE_FLATSTYLE_FLAT_SHARED_HORZ_SCROLLSTYLE_3D_SCROLLEDSTYLE_3D_ONENOTESTYLE_3D_VS2005STYLE_3D_ROUNDED_SCROLL

有了这种洞察力,导航按钮可以通过多种方式关闭。

  • 按书本:创建CMFCTabCtrl没有任何启用这些按钮的样式,仅保留STYLE_3D可用的样式。这确实丢失了导航按钮,但选项卡控件的样式也变得不同,并且选项卡本身显示为小矩形而不是梯形。

  • 未记录:在创建选项卡窗口之前覆盖CMFCTabCtrl::m_bScroll并将其设置为。FALSE例如,派生一个CMyTabCtrl要清除的类m_bScroll

    class CMyTabCtrl : public CMFCTabCtrl
    {
    protected:
      BOOL PreCreateWindow(CREATESTRUCT &cs) override
      {
        m_bScroll = FALSE;
        return CMFCTabCtrl::PreCreateWindow(cs);
      }
    };
    

    然后将控件实例化为CMyTabCtrl m_wndTabs;而不是CMFCTabCtrl m_wndTabs;.

于 2021-04-15T21:54:55.633 回答
1

我记得我过去用 One-liner 解决了这个问题。
这是直接访问 CTrackView::::OnCreate() 函数中的 m_bScroll 变量的解决方案(hack)。正如 dxiv 解释的那样,OnInitialUpdate() 来得太晚了。

int void CTrackView::::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
   if (CTabView::OnCreate(lpCreateStruct) == -1)
     return -1;

     // add document views   
     AddView(RUNTIME_CLASS(CTrainView), AfxStringID(IDS_TRAIN));
     AddView(RUNTIME_CLASS(CStationView), AfxStringID(IDS_STATION));
     :
     :
   
     // Nicely hack to access protected member
     class CMFCTabCtrlEx : public CMFCTabCtrl
     {
       public:
         void SetDisableScroll() { m_bScroll = FALSE; }
     };

     // One-Liner to Disable navigation control
     ((CMFCTabCtrlEx*)&GetTabControl())->SetDisableScroll();

 }   
于 2021-04-19T10:07:42.380 回答