MFC CMFCTabCtrl 笔记

控件手动创建过程

BOOL Create(Style style, const RECT& rect, CWnd* pParentWnd, UINT nID, Location location = LOCATION_BOTTOM, BOOL bCloseBtn = FALSE);

style:	STYLE_3D                      = 0,
		STYLE_FLAT                    = 1,
		STYLE_FLAT_SHARED_HORZ_SCROLL = 2,
		STYLE_3D_SCROLLED             = 3,
		STYLE_3D_ONENOTE              = 4,
		STYLE_3D_VS2005               = 5,
		STYLE_3D_ROUNDED              = 6,
		STYLE_3D_ROUNDED_SCROLL       = 7,
rect:放置位置 无所谓,在OnSize中再自行调整
pParentWnd:父窗口不可为空,一般填this
nID:控件ID号 不可与同级控件冲突
location:	LOCATION_BOTTOM = 0,//选项卡的位置标识 默认是下部
		    LOCATION_TOP = 1
bCloseBtn :指示是否要选项卡关闭按钮,默认是不要

二次设置部分(选用)

void EnableAutoColor(BOOL bEnable = TRUE);//允许每个选项卡自动变换颜色
void SetAutoColors(const CArray<COLORREF, COLORREF>& arColors);//设定自动变换颜色的范围
void EnableTabSwap(BOOL bEnable) ;//允许选项卡之间交换位置
void EnableActiveTabCloseButton(BOOL bEnable = TRUE);//启用关闭按钮
virtual void EnableInPlaceEdit(BOOL bEnable);//启动标题栏修改
void HidSingleTab(BOOL bEnable = TRUE);//当只剩一个选项卡的时候隐藏选项卡栏
。。。 更多看VS软件的手册helpView

添加新的标签页


virtual BOOL AddTab(CWnd* pNewBar, BOOL bVisible = TRUE, BOOL bSetActive = TRUE, BOOL bDetachable = TRUE);
	pNewBar:标签页里要放置的窗口
    bVisible:是否可视的
    bSetActive:是否这是为活动页
    bDetachable:是否分离出去
virtual void InsertTab(CWnd* pNewWnd, LPCTSTR lpszTabLabel, int nInsertAt, UINT uiImageId = (UINT)-1, BOOL bDetachable = TRUE);
lpszTabLabel:选项卡名称
nInsertAt:选项卡的顺序
uiImageId :选项卡名称旁边的图标序号

	virtual void InsertTab(CWnd* pNewWnd, UINT uiResTabLabel, int nInsertAt, UINT uiImageId = (UINT)-1, BOOL bDetachable = TRUE);
uiResTabLabel:string table里的字符串ID

virtual BOOL ShowTab(int iTab, BOOL bShow = TRUE, BOOL bRecalcLayout = TRUE, BOOL bActivate = FALSE);
bShow  指定选项卡是否隐藏 
bActivate 此选项卡是否活跃 即是否前台展示

virtual BOOL RemoveTab(int iTab, BOOL bRecalcLayout = TRUE);
移除指定选项卡,并且销毁传入的窗口

发现的异常现象

允许选项卡的关闭按钮后虽然点击的关闭按钮 却执行了

BOOL CMFCTabCtrl::OnCommand(WPARAM wParam, LPARAM lParam)
{
。。。
else if ((HWND)lParam == m_btnClose.GetSafeHwnd())
	{
		CWnd* pWndActive = GetActiveWnd();
		if (pWndActive != NULL)
		{
			pWndActive->SendMessage(WM_CLOSE);
		}

		return TRUE;
	}
。。。
}

也就是说他只关闭了选项卡内嵌的窗口 缺依旧保留选项卡框架,因此我 只能继承并截获此操作自定义自己需要的结果,比如我做了如下的操作

void CMFCMyTabCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
    if(m_rectCloseButton.PtInRect(point))//判断点击是否在关闭按钮上
    {
        int nTab=GetActiveTab();//获取当前的 活动窗口
        if(nTab>-1)
        {
           showTab(nTab,0); //只隐藏不清理
         }
    }
CMFCTabCtrl::OnLButtonUp( nFlags,  point);
}

其他我未研究,但是通过源码看到的几个发给父窗口的消息

LRESULT lResult = GetParent()->SendMessage(AFX_WM_GETDRAGBOUNDS, (WPARAM)(LPVOID)this, (LPARAM)(LPVOID) &rectBounds); //afxtabctrl.cpp 1280行 应该是限定拖动范围的 具体操作 LPARAM参数

GetParent()->SendMessage(AFX_WM_ON_HSCROLL, wParam);//afxtabctrl.cpp 1616行 应该是告知父窗口移动的位置

GetParent()->SendMessage(AFX_WM_ON_MOVETABCOMPLETE, (WPARAM) this, (LPARAM) MAKELPARAM(point.x, point.y));//afxtabctrl.cpp 2101行 应该是告知父窗口移动选项卡结束

GetParent()->SendMessage(AFX_WM_ON_DRAGCOMPLETE, (WPARAM) this, (LPARAM) &rect);//afxtabctrl.cpp 2140行 应该是告知父窗口选项卡调整后的尺寸

(GetParent()->SendMessage(AFX_WM_ON_TABGROUPMOUSEMOVE, nFlags, MAKELPARAM(point.x, point.y));//afxtabctrl.cpp 2235行 应该是告知父窗口鼠标在选项卡上的 位置

GetParent()->SendMessage(AFX_WM_ON_CANCELTABMOVE);//afxtabctrl.cpp 2262行

GetParent()->SendMessage(WM_MDIACTIVATE, (WPARAM) pActiveWnd->GetSafeHwnd());//afxtabctrl.cpp 3163行

//afxbasetabctrl.cpp
GetParent()->SendMessage(WM_IDLEUPDATECMDUI);
pWndParent->SendMessage(AFX_WM_ON_MOVE_TAB, m_iTabBeforeDrag, m_iActiveTab);
GetParent()->SendMessage(AFX_WM_ON_RENAME_TAB, m_iEditedTab, (LPARAM)(LPCTSTR) strName);
pParent->SendMessage(AFX_WM_CHANGE_ACTIVE_TAB, nNewTab, (LPARAM)this);
pParent->SendMessage(AFX_WM_ON_GET_TAB_TOOLTIP, 0, (LPARAM) &info);
pParentFrame->SendMessage(AFX_WM_ON_GET_TAB_TOOLTIP, 0, (LPARAM) &info);

知道tabCtrl向父窗口都发送了什么消息,大家就可以根据需要截获消息使用了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值