如何让CMFCTabCtrl关闭按钮关闭属性页? CMFCTabCtrl控件创建在对话框窗口上使用m_wndTabs.EnableActiveTabCloseButton();显示关闭按钮但是点击关闭却没反应,该如何实现关闭功能? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 还在用VS2003,没用过 CMFCTabCtrl VS2008+SP1就有,我试过关闭不了于是又下了个VS2010,还是不行 难道只有用在frame结构才可以关闭? 哎呀,这个bug修改难度很大啊,2010也有,楼主怎么搞定的,诚心求教啊转:CMFCTabCtrl::EnableActiveTabCloseButton用于在CMFCTabCtrl的Tab页显示一个关闭按钮,看看关闭按钮怎么实现:void CMFCBaseTabCtrl::OnLButtonDown(UINT nFlags, CPoint point){ m_bWindowPosChanged = FALSE; CWnd::OnLButtonDown(nFlags, point); if (m_rectCloseButton.PtInRect(point)) { m_bTabCloseButtonPressed = TRUE; RedrawWindow(m_rectCloseButton); return ; }... void CMFCBaseTabCtrl::OnLButtonUp(UINT nFlags, CPoint point){ if (m_bTabCloseButtonPressed) { m_bTabCloseButtonPressed = FALSE; m_bTabCloseButtonHighlighted = FALSE; RedrawWindow(m_rectCloseButton); if (m_rectCloseButton.PtInRect(point)) { CWnd* pWndActive = GetActiveWnd(); if (pWndActive != NULL) { pWndActive->SendMessage(WM_CLOSE); } return ; } }...应该就这些了。在例子TabbedView中添加这个功能:int CTabbedViewView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CTabView::OnCreate(lpCreateStruct) == -1) return -1; AddView (RUNTIME_CLASS (CView1), _T( "Simple" ), 100); AddView (RUNTIME_CLASS (CView2), _T( "List" ), 101); AddView (RUNTIME_CLASS (CView3), _T( "Form" ), 102); AddView (RUNTIME_CLASS (CView4), _T( "ScrollView" ), 102); m_wndTabs.EnableActiveTabCloseButton(); return 0;}然后点击一个页面上的关闭按钮,会发现这个tab页并没有消失,而切换到其他页面,程序就中断了,问题出在:BOOL CMFCTabCtrl::SetActiveTab( int iTab){... if (m_iActiveTab != -1 && m_bHideInactiveWnd) { //-------------------- // Hide active window: //-------------------- CWnd* pWndActive = GetActiveWnd(); if (pWndActive != NULL) { pWndActive->ShowWindow(SW_HIDE); } }由于窗口已经销毁,而该Tab页仍然存在,所以m_iActiveTab就是被销毁的窗口所在页面,pWndActive是已经被销毁的窗口,自然调用其ShowWindow方法就出错了。个人感觉,他找到的错误还不全,在点击了关闭按钮后,执行:void CMFCBaseTabCtrl::OnLButtonDown(UINT nFlags, CPoint point){ m_bWindowPosChanged = FALSE; CWnd::OnLButtonDown(nFlags, point); if (m_rectCloseButton.PtInRect(point)) { m_bTabCloseButtonPressed = TRUE; //改变了这个标志位 RedrawWindow(m_rectCloseButton); return; //然后return掉 } }到这里:void CMFCTabCtrl::OnLButtonDown(UINT nFlags, CPoint point){ ... ... CMFCBaseTabCtrl::OnLButtonDown(nFlags, point); if (!m_bReadyToDetach) { CWnd* pWndTarget = FindTargetWnd(point); if (pWndTarget != NULL) { ASSERT_VALID(pWndTarget); MapWindowPoints(pWndTarget, &point, 1); pWndTarget->SendMessage(WM_LBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y)); } }}应该进入if语句,结果pWndTarget == null,进不去,这个功能就无法实现了... if (m_rectCloseButton.PtInRect(point)) { CWnd* pWndActive = GetActiveWnd(); if (pWndActive != NULL) { pWndActive->SendMessage(WM_CLOSE); } return ; } }关键代码在这里 看到 pWndActive->SendMessage(WM_CLOSE);了么?实际上就是调用了 要关闭页面的WM_CLose 消息 BOOL CMyMFCTabCtrl::OnCommand(WPARAM wParam, LPARAM lParam){ // TODO: 在此添加专用代码和/或调用基类 if ((HWND)lParam == m_btnClose.GetSafeHwnd()) { { int nTab = GetActiveTab(); if (nTab >= 0) { CWnd* pWnd = GetTabWnd (nTab); pWnd->DestroyWindow (); delete pWnd; RemoveTab(nTab); } return true; } } return CMFCTabCtrl::OnCommand(wParam, lParam);}最近怎么老有人问,这是从别的帖子里找过来的,希望有用。换工作很久了,改Android了,原来的代码都丢了。给不了更多的消息了,抱歉啊 我解决了void CMyMFCTabCtrl::OnLButtonDown(UINT nFlags, CPoint point){ // TODO: 在此添加消息处理程序代码和/或调用默认值 bool bClose = true; int nTab = GetTabFromPoint(point); if (nTab >= 0 && nTab != GetActiveTab()) bClose = false; // 切换则不关闭 // 先执行基类操作,否则会丢失窗口焦点 CMFCTabCtrl::OnLButtonDown(nFlags, point); if (bClose) CloseTab(point);}void CMyMFCTabCtrl::CloseTab(CPoint point){ if (m_rectCloseButton.PtInRect(point)) { int nTab = GetActiveTab(); if (nTab >= 0) { if (nTab > 0) SetActiveTab(nTab - 1); RemoveTab(nTab); } }} TCP WSASend发送成功 完成端口没返回结果 一个关于STL的问题 如何在外部结束下载线程,实现取消下载? 有没有办法获得DrawText()后文字的高度? 一个简单的问题,随便近来个人看看就可以了 什么是进程的地址空间 谁有《现代操作系统》英文电子版! 北京项目外包(浏览器BHO插件开发) 声明,本人以后不在网上谈论政治等话题,请不要引诱我了,谢谢~! gl studio 5.1 中文界面 仪表仿真 vector存结构体,而该结构体中又含vector 编译出错,求教育 散分,打算年假归来辞了,离开IT圈了
于是又下了个VS2010,还是不行
CMFCTabCtrl::EnableActiveTabCloseButton
用于在CMFCTabCtrl的Tab页显示一个关闭按钮,看看关闭按钮怎么实现:void CMFCBaseTabCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
m_bWindowPosChanged = FALSE;
CWnd::OnLButtonDown(nFlags, point);
if (m_rectCloseButton.PtInRect(point))
{
m_bTabCloseButtonPressed = TRUE;
RedrawWindow(m_rectCloseButton);
return ;
}
...
void CMFCBaseTabCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_bTabCloseButtonPressed)
{
m_bTabCloseButtonPressed = FALSE;
m_bTabCloseButtonHighlighted = FALSE;
RedrawWindow(m_rectCloseButton);
if (m_rectCloseButton.PtInRect(point))
{
CWnd* pWndActive = GetActiveWnd();
if (pWndActive != NULL)
{
pWndActive->SendMessage(WM_CLOSE);
}
return ;
}
}
...
应该就这些了。在例子TabbedView中添加这个功能:int CTabbedViewView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTabView::OnCreate(lpCreateStruct) == -1)
return -1;
AddView (RUNTIME_CLASS (CView1), _T( "Simple" ), 100);
AddView (RUNTIME_CLASS (CView2), _T( "List" ), 101);
AddView (RUNTIME_CLASS (CView3), _T( "Form" ), 102);
AddView (RUNTIME_CLASS (CView4), _T( "ScrollView" ), 102);
m_wndTabs.EnableActiveTabCloseButton();
return 0;
}
然后点击一个页面上的关闭按钮,会发现这个tab页并没有消失,而切换到其他页面,程序就中断了,问题出在:BOOL CMFCTabCtrl::SetActiveTab( int iTab)
{
...
if (m_iActiveTab != -1 && m_bHideInactiveWnd)
{
//--------------------
// Hide active window:
//--------------------
CWnd* pWndActive = GetActiveWnd();
if (pWndActive != NULL)
{
pWndActive->ShowWindow(SW_HIDE);
}
}
由于窗口已经销毁,而该Tab页仍然存在,所以m_iActiveTab就是被销毁的窗口所在页面,pWndActive是已经被销毁的窗口,自然调用其ShowWindow方法就出错了。
个人感觉,他找到的错误还不全,在点击了关闭按钮后,执行:
void CMFCBaseTabCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
m_bWindowPosChanged = FALSE; CWnd::OnLButtonDown(nFlags, point); if (m_rectCloseButton.PtInRect(point))
{
m_bTabCloseButtonPressed = TRUE; //改变了这个标志位
RedrawWindow(m_rectCloseButton);
return; //然后return掉
}
}到这里:void CMFCTabCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
... ...
CMFCBaseTabCtrl::OnLButtonDown(nFlags, point); if (!m_bReadyToDetach)
{
CWnd* pWndTarget = FindTargetWnd(point);
if (pWndTarget != NULL)
{
ASSERT_VALID(pWndTarget); MapWindowPoints(pWndTarget, &point, 1);
pWndTarget->SendMessage(WM_LBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
}
}
}应该进入if语句,结果pWndTarget == null,进不去,这个功能就无法实现了...
{
CWnd* pWndActive = GetActiveWnd();
if (pWndActive != NULL)
{
pWndActive->SendMessage(WM_CLOSE);
}
return ;
}
}
关键代码在这里 看到 pWndActive->SendMessage(WM_CLOSE);了么?实际上就是调用了 要关闭页面的WM_CLose 消息
{
// TODO: 在此添加专用代码和/或调用基类
if ((HWND)lParam == m_btnClose.GetSafeHwnd())
{
{
int nTab = GetActiveTab();
if (nTab >= 0)
{
CWnd* pWnd = GetTabWnd (nTab);
pWnd->DestroyWindow ();
delete pWnd;
RemoveTab(nTab);
}
return true;
}
}
return CMFCTabCtrl::OnCommand(wParam, lParam);
}最近怎么老有人问,这是从别的帖子里找过来的,希望有用。
换工作很久了,改Android了,原来的代码都丢了。给不了更多的消息了,抱歉啊
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
bool bClose = true;
int nTab = GetTabFromPoint(point);
if (nTab >= 0 && nTab != GetActiveTab())
bClose = false; // 切换则不关闭 // 先执行基类操作,否则会丢失窗口焦点
CMFCTabCtrl::OnLButtonDown(nFlags, point); if (bClose)
CloseTab(point);
}void CMyMFCTabCtrl::CloseTab(CPoint point)
{
if (m_rectCloseButton.PtInRect(point))
{
int nTab = GetActiveTab();
if (nTab >= 0)
{
if (nTab > 0)
SetActiveTab(nTab - 1);
RemoveTab(nTab);
}
}
}