当前位置: 代码迷 >> 综合 >> MFC CMFCTabCtrl 笔记
  详细解决方案

MFC CMFCTabCtrl 笔记

热度:59   发布时间:2023-10-19 11:49:38.0

控件手动创建过程

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里的字符串IDvirtual 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向父窗口都发送了什么消息,大家就可以根据需要截获消息使用了

  相关解决方案