文章链接地址 : http://www.pcw8510.com/?p=1258
最近本人在项目过程中和CMFCTabCtrl多次交手,该控件是出现在VS2008之后的,说实话,一般的控件也没啥新意,看看MSDN,自己查查资料就搞定了。这次主要是连续两个问题都出在改控件上,所以我就把这个系列问题记录下来,仅供大家以后参考。
一、CMFCTabCtrl标签关闭按钮
该控件的主要表现形式就是X按钮,但是无效果。那只能自己丰衣足食了。
1. 先把CMFCTabCtrl继承过来
PublicCMYMFCTabCtrl::CMFCTabCtrl
2. 复写WM_LBUTTONDOWN的消息对应函数
VoidCMYMFCTabCtrl::OnLButtonDown(UINT nFlags,Cpoint point)
{
//判断是否击中标签的关闭按钮
if(m_rectCloseButton.PtInRect(point))
{
m_bCloseButtonLButtonDown = TRUE;
}
//如果点击标签
else if(this->m_rectTabsArea.PtInRect(point))
{
m_bCloseButtonLButtonDown= FALSE;
//处理对应自己的标签弹出 (略)
}
}
之后终于我们的CMYMFCTabCtrl功能算齐全了。标签终于能关闭了。
二、多文档VS风格的CMFCTabCtrl
如果事情就这么结束了,那就不用写这篇BLOG,之后由于我们的主程序是用了VisualStudio风格样式开发的。本身支持多文档显示,那个多文档显示也用了CMFCTabCtrl控件。但是那个关闭按钮可是天生就有关闭功能的,一阵窃喜,不用写代码咯。可是客户后来提出要求,始终要留一个主View,其他View可以删除。刚听到这个需求,觉得非常简单,向上面一样如法炮制即可。可是,这个CMFCTabCtrl已经内嵌到CmainFrame中了,而且开放的接口是
EnableMDITabbedGroups和EnableMDITabs(),因此上面的方法完全行不通。
解决方法:
从源头来遏制这个问题吧,Windows的核心机制还是消息。那就对消息下手。
内嵌的CMFCTabCtrl是属于CC hildFrame的。
触发该窗体的WindowProc来截获消息吧
LRESULT CchildFrame::WindowProc(UINT message,WPARAMwParam, LPARAM lParam)
{
If(message== WM_CLOSE)
{
//判断消息的源头是哪里的,因为所有标签都能发送WM_CLOSE的
CDocument * pDoc = GetActiveDocument();
If(pDoc->GetTitle== _T(“xxxxxx”)) //以自己的Title为标记
ReturnTRUE;
}
Return CMDIChildWndEx::WindowProc(message,wParam,lParam);
}
OK了,这样再看看,是不是那个XXX的标签是不是关不掉了?