VC2008 sp1中CTabView类的使用问题

hasia 2009-06-12 04:29:21
请问一下,在VC2008spq中,
我创建了一个SDI程序,程序View是一个CTabView类的继承类,
CTabView继承类中添加了一个表格View,一个图形View

现在发现一个问题,怎么找到获取不到表格View呢?
我试过CTabView::SetActiveView()和CTabView::GetActiveView(),取出来的表格view指针都是空的

大家谁能帮忙支个招啊?谢谢了
...全文
701 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq539929779 2009-06-20
  • 打赏
  • 举报
回复
o skyxie:
我目前程序的CTabView暂时只加入了两个View,
发现点击不同item时候,对这两个view来回切换,即Add、Remove时,
屏幕闪烁的很厉害,
不知道有什么办法解决没有?

查了MSDN,
我一时还想不出什么办法,如果是绘图,可以用memDC解决
qq539929779 2009-06-20
  • 打赏
  • 举报
回复
o skyxie:
我目前程序的CTabView暂时只加入了两个View,
发现点击不同item时候,对这两个view来回切换,即Add、Remove时,
屏幕闪烁的很厉害,
不知道有什么办法解决没有?

查了MSDN,
我一时还想不出什么办法,如果是绘图,可以用memDC解决
hasia 2009-06-19
  • 打赏
  • 举报
回复
To skyxie:
我目前程序的CTabView暂时只加入了两个View,
发现点击不同item时候,对这两个view来回切换,即Add、Remove时,
屏幕闪烁的很厉害,
不知道有什么办法解决没有?

查了MSDN,
我一时还想不出什么办法,如果是绘图,可以用memDC解决
hasia 2009-06-19
  • 打赏
  • 举报
回复
谢谢skyxie

确实是你说的那个问题,只能取到tab view中选中那个tab对应的view
太感谢了

第2个隐藏功能的问题,我正在试,弄好了一起结贴
skyxie 2009-06-17
  • 打赏
  • 举报
回复
刚才看了下CTabView的代码

1. 拿到的是tab view中选中那个tab对应的view

可以通过这样的方法拿到 CXXXTabView
CView * pView = pChildFrm->GetActiveView();
CMFCTabCtrl * pParent1 = pView->GetParent();
CXXXTabView * pTabView = pParent1->GetParent();

2.
-----------------------------
如果每次都要AddView,RemoveView,
那开销岂不是很大,有什么办法避免呢?
-----------------------------
int CTabView::AddView(CRuntimeClass* pViewClass, const CString& strViewLabel, int iIndex /*= -1*/, CCreateContext*

pContext/* = NULL*/)
确实会每次都去创建一个 pViewClass 的对象,

这样应该可以避免:

1) 第一次添加的时候 直接使用 CTabView::AddView

2) 删除Tab的时候 把被Remove的,不使用的View保存下来
BOOL bOldAutoDestory = IsAutoDestroyWindow();
AutoDestroyWindow(FALSE);
CView * m_pNotUsedView = GetTabControl().GetTabWnd(iTabIndex);
RemoveView(iTabNum);
AutoDestroyWin(bOldAutoDestory);

3)添加一个方法: (仿照的CTabView::AddView, 去掉创建view的部分)
int CXXXTabView::AddExistView(CView *pView, const CString& strViewLabel, int iIndex /*= -1*/)
{
m_wndTabs.InsertTab(pView, strViewLabel, iIndex);

int nTabs = m_wndTabs.GetTabsNum();
return nTabs - 1
}

4)第2次及以后添加的时候:
AddExistView(m_pNotUsedView, ...);

5)
CXXTabView销毁前,凡是通过2)删除的tab,需要使用4)添加进行,然后在destory,否则会内存泄露
hasia 2009-06-15
  • 打赏
  • 举报
回复
最后还想请教一下,CTabView如何隐藏某个Tab,以及动态创建Tab呢?
即选择CTreeCtrl的不同item时候,创建对应的tab,并隐藏或关闭原有的tab,
不知道CMFCTabCtrl能否实现上述功能
hasia 2009-06-15
  • 打赏
  • 举报
回复
现在发现问题不是SetAcitveView

是无法获取CMyTabView指针地址的问题。

在我的树形控件中,我发送消息给CMainFrame,
发现在处理该消息的函数CMainFrame::OnMsgViewTree中,
GetActiveView()得到CMyTabView指针与我原来创建的CMyTabView指针不一致(我是在CMyTabView::OnCreate看原始指针的),
不知道CMainFrame::GetActiveView()函数怎么出问题了,获取不到实际的CMyTabView指针?
以前在VC6中没有遇到过这种事情的


另外,我也试了MSDN里面的TabbedView例子,结果也是一样的
通过一个菜单,在CMainFrame也是获取CTabView有问题,指针不一致


void CViewTree::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码

CMainFrame *pMainFrm = (CMainFrame *)AfxGetMainWnd();
CMyTabView *pView = (CMyTabView *)pMainFrm->GetActiveView(); ----------->问题:pView指针地址与创建的时候的CMyTabView指针地址不一致

HTREEITEM itemSel = GetSelectedItem();
if (itemSel != NULL)
{
int nIndex;
nIndex = GetItemData(itemSel);

::SendMessage(AfxGetMainWnd()->m_hWnd, WM_VIEWTREEITEM, ITEM_CHANGED, nIndex);
//::SendMessage(pView->m_hWnd, WM_VIEWTREEITEM, ITEM_CHANGED, nIndex); ---------->直接发送给CMyTabView也不行,接收不到消息
}

*pResult = 0;
}


LRESULT CMainFrame::OnMsgViewTree(WPARAM wp, LPARAM lp)
{
MSG_TREEITEM msgType = (MSG_TREEITEM)wp;
int nIndex = (int)lp;
TREEITEM_DATA *pItemData;
CMyTabView *pView = (CMyTabView *)GetActiveView();
ASSERT_VALID(pView); -------------------->问题:pView虽然有效,但是其指针地址与创建的时候的CMyTabView指针地址不一致
CViewGridCtrl *pViewGrid;

switch(msgType)
{
case ITEM_CHANGED:
pItemData = m_vectNodeData.at(nIndex);

pView->SetActiveView(0);

//pViewGrid = (CViewGridCtrl *)pView->GetActiveView();
pViewGrid = dynamic_cast<CViewGridCtrl *>(pView->GetActiveView());
ASSERT_VALID(pViewGrid); -------------------->出错点:由于pView指针地址不一致,导致pViewGrid无效,弹出错误
pViewGrid->InitGrid(pItemData->gridType);
pViewGrid->Invalidate();

break;

default:
break;
}


return 0;
}
hasia 2009-06-15
  • 打赏
  • 举报
回复
我试了一下MSDN的TabbedView sample,
也有类似问题
奇怪了

//随便添加的一个测试菜单
void CMainFrame::OnTestTaboperate()
{
// TODO: 在此添加命令处理程序代码

//CChildFrame *pChildFrm = (CChildFrame *)MDIGetActive();
CChildFrame *pChildFrm = (CChildFrame *)GetActiveFrame();
ASSERT(pChildFrm->IsKindOf(RUNTIME_CLASS(CChildFrame)));
CTabbedViewView *pViewTab = (CTabbedViewView *)pChildFrm->GetActiveView();
ASSERT(pViewTab->IsKindOf(RUNTIME_CLASS(CTabbedViewView))); ------------------------->这里出错了

ASSERT(pViewTab->SetActiveView(1) == FALSE);
CView2 *pView2 = (CView2 *)pViewTab->GetActiveView();
}
逸萌 2009-06-15
  • 打赏
  • 举报
回复
up
hasia 2009-06-15
  • 打赏
  • 举报
回复
To skyxie:
你先看看这里 pView->IsKindOf(RUNTIME_CLASS(CMyTabView)) 是否为真
怀疑你拿到的根本就不是 CMyTabView 否则地址应该是一样的
==============

1.
还真的是FALSE,
ASSERT(pView->IsKindOf(RUNTIME_CLASS(CMyTabView)));真的出问题了
奇怪了,这个问题在什么地方呢?
以前用VC6都是用CMyTabView *pView = (CMyTabView *)pMainFrm->GetActiveView(); 获取View的,
从没有出现问题啊?

另外,我的CMyTabView生成的时候,向导没办法选择CTabView,
我是先生成CView,然后将所有CView改成CTabView了
我对照了MSDN的TabbedView sample,和它的CTabView子类差不多

不知道问题是不是出现在这里了?

2.
如果每次都要AddView,RemoveView,
那开销有点大,有什么办法避免呢?
skyxie 2009-06-15
  • 打赏
  • 举报
回复
CMyTabView *pView = (CMyTabView *)pMainFrm->GetActiveView(); ----------->问题:pView指针地址与创建的时候的CMyTabView指针地址不一致
---
你先看看这里 pView->IsKindOf(RUNTIME_CLASS(CMyTabView)) 是否为真
怀疑你拿到的根本就不是 CMyTabView 否则地址应该是一样的
skyxie 2009-06-13
  • 打赏
  • 举报
回复
估计是你 SetActiveView 的地方不对

在 CXXView::OnInitialUpdate中 或者 菜单处理函数中 SetActiveView()
然后用的时候应该就能 GetActiveView 了

16,550

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧