控件手动创建过程
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向父窗口都发送了什么消息,大家就可以根据需要截获消息使用了