关于使用标签视后菜单消息命令的奇怪问题(高分重谢)

zickphy 2004-02-02 10:34:40
MFC的SDI程序,重载CMainFrame类的OnCreateClient函数,使用一个标签视:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
if(!m_wndTab.Create(WS_BORDER | WS_CHILD | WS_VISIBLE | TCS_TABS | TCS_HOTTRACK,
CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST))
{
TRACE0("Failed to create TabContainer!\n");
return FALSE;
}
//m_wndTab.ModifyStyleEx(0, WS_EX_CLIENTEDGE);

m_wndTab.AddView(_T("标签页1"), pContext->m_pNewViewClass, pContext, -1);

return TRUE;
}
m_wndTab为一CTabCtrl派生类的实例:
.h文件内容为:
class CTabViewContainer : public CTabCtrl
{
DECLARE_DYNCREATE(CTabViewContainer)

public:
CTabViewContainer();
virtual ~CTabViewContainer();

BOOL AddView(LPCTSTR pszText, CRuntimeClass *pRT, CCreateContext *pContext = NULL, int nImage = -1);
void ChangeView(int nIndex);
CWnd * GetSelView(void);

protected:
DECLARE_MESSAGE_MAP()

public:
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnTcnSelchange(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnTcnSelchanging(NMHDR *pNMHDR, LRESULT *pResult);
};
.c文件内容为:
IMPLEMENT_DYNCREATE(CTabViewContainer, CTabCtrl)
CTabViewContainer::CTabViewContainer()
{
}

CTabViewContainer::~CTabViewContainer()
{
}


BEGIN_MESSAGE_MAP(CTabViewContainer, CTabCtrl)
ON_WM_SIZE()
ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnTcnSelchange)
ON_NOTIFY_REFLECT(TCN_SELCHANGING, OnTcnSelchanging)
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()



// CTabViewContainer 消息处理程序

// 添加一个视图页
BOOL CTabViewContainer::AddView(LPCTSTR pszText, CRuntimeClass *pRT, CCreateContext *pContext, int nImage)
{
int nIndex = this->GetItemCount();
CSize sz(40, 20);
this->SetItemSize(sz);

TCITEM tci;
tci.mask = TCIF_TEXT | TCIF_PARAM;
if (nImage != -1)
tci.mask |= TCIF_IMAGE;

CWnd *pView = (CWnd *)pRT->CreateObject();
pView->CreateEx(WS_EX_CLIENTEDGE, NULL, NULL, WS_CHILD | WS_VISIBLE,
CRect(0, 0, 0, 0), this, nIndex, pContext);

tci.pszText = (char *)pszText;
tci.lParam = (LPARAM)pView;
tci.iImage = nImage;

this->InsertItem(nIndex, &tci);
return TRUE;
}

// 切换视图
void CTabViewContainer::ChangeView(int nIndex)
{
ASSERT(nIndex>=0);
int nCount=GetItemCount();
ASSERT(nIndex<nCount);

int nSel=GetCurSel();
TCITEM tci;
CRect rc;
tci.mask = TCIF_PARAM;
if(nSel!=nIndex)
{
this->GetItem(nSel, &tci);
CWnd *pView = (CWnd *)tci.lParam;
pView->SetWindowPos(NULL, 0, 0, 10, 10, SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOACTIVATE);
}
this->GetItem(nIndex, &tci);
CWnd *pView = (CWnd *)tci.lParam;
this->GetClientRect(&rc);
rc.top = 24;
pView->SetWindowPos(&CWnd::wndTop, 0, 24, rc.right, rc.bottom - 24, SWP_SHOWWINDOW);
SetCurSel(nIndex);
}

// 得到当前选中的视图索引
CWnd * CTabViewContainer::GetSelView(void)
{
int nSel = GetCurSel();
TCITEM tci;
CRect rc;
tci.mask = TCIF_PARAM;
GetItem(nSel, &tci);
return ((CWnd *)tci.lParam);
}

// 改变尺寸时,需要挪动子窗口
void CTabViewContainer::OnSize(UINT nType, int cx, int cy)
{
CTabCtrl::OnSize(nType, cx, cy);
CRect rc(0, 24, cx, cy);
int nSel = this->GetCurSel();
if (nSel >= 0)
{
TCITEM tci;
tci.mask = TCIF_PARAM;
this->GetItem(nSel, &tci);
CWnd *pView = (CWnd *)tci.lParam;
pView->MoveWindow(&rc);
}
}

void CTabViewContainer::OnTcnSelchange(NMHDR *pNMHDR, LRESULT *pResult)
{
int nSel = this->GetCurSel();
ChangeView(nSel);
*pResult = 0;
}

void CTabViewContainer::OnTcnSelchanging(NMHDR *pNMHDR, LRESULT *pResult)
{
int nSel = this->GetCurSel();
TCITEM tci;
tci.mask = TCIF_PARAM;
this->GetItem(nSel, &tci);
CWnd *pView = (CWnd *)tci.lParam;
pView->SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOACTIVATE);
*pResult = 0;
}

问题在于使用标签视后,在Doc和View类中新添加的菜单消息处理命令是灰色的,只能在MainFrame类中添加有效。更奇怪的是在View中只要鼠标左单击一下,Doc和View类中新添加的菜单消息处理命令就有效了。
请各位高手帮忙解决这个问题,高分重谢!!解决后开贴另加分。
...全文
37 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
zickphy 2004-02-03
  • 打赏
  • 举报
回复
up
zickphy 2004-02-03
  • 打赏
  • 举报
回复
up
zickphy 2004-02-03
  • 打赏
  • 举报
回复
up
zickphy 2004-02-03
  • 打赏
  • 举报
回复
调试通过,感谢ing!!!!
不过我还是奇怪我手头相关的另一个程序,也是用了同样的一个类,但我找遍了也没有找到关于setactiveview的语句,不知道它是怎么回事就一直没有我这样的状况,好晕!
lyljp 2004-02-03
  • 打赏
  • 举报
回复
笔误
应该是:m_tabWnd.AddView(_T("标签页1"), pContext->m_pNewViewClass, pContext, -1);
lyljp 2004-02-03
  • 打赏
  • 举报
回复
我刚才试了一下,我只在CMainFrame::OnCreateClient中改动一点就好使了
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: Add your specialized code here and/or call the base class
if(!m_tabWnd.Create(WS_BORDER | WS_CHILD | WS_VISIBLE | TCS_TABS | TCS_HOTTRACK,
CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST))
{
TRACE0("Failed to create TabContainer!\n");
return FALSE;
}
m_tabWnd.AddView(_T("标签页1");

SetActiveView((CView*)m_tabWnd.GetSelView(),FALSE); /*****addition******/
return TRUE;
// return CFrameWnd::OnCreateClient(lpcs, pContext);
}
你也试试,看怎么样??
zickphy 2004-02-03
  • 打赏
  • 举报
回复
up
lzzqqq 2004-02-03
  • 打赏
  • 举报
回复
用classwizard映射消息时
从ClassInfo标签选择MessageFilter的类型
lyljp 2004-02-03
  • 打赏
  • 举报
回复
试试SetDlgCtrlID和SetActiveView
zickphy 2004-02-02
  • 打赏
  • 举报
回复
编译环境是windows2000,vc++.net2002
zickphy 2004-02-02
  • 打赏
  • 举报
回复
你跟踪一下CFrameWnd::OnCreateClient(lpcs, pContext)就知道了:
不过也是调用了CreateView(pContext, AFX_IDW_PANE_FIRST);
函数中也只是这两句:
CWnd* pView = (CWnd*)pContext->m_pNewViewClass->CreateObject();
pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,CRect(0,0,0,0), this, nID, pContext)
pView也不过是局部变量。
cattydid 2004-02-02
  • 打赏
  • 举报
回复
在CTabViewContainer类的AddView函数中加入了pView->SetFocus()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这又有什么用呢?首先pView是局部变量,连成员变量都不是
zickphy 2004-02-02
  • 打赏
  • 举报
回复
up
zickphy 2004-02-02
  • 打赏
  • 举报
回复
我在CTabViewContainer类的AddView函数中加入了pView->SetFocus();还是不行,看来好像不是输入焦点的问题吧?为什么在View类的客户区点击一下鼠标,菜单就由灰色变成有效了?
zickphy 2004-02-02
  • 打赏
  • 举报
回复
而Doc类中的命令响应,也需要视图处于激活状态下吗?我看过同样的一个使用这个TabContainer类的程序,虽然是VC6的,但里面没有找到关于激活视图状态的程序行。
flyelf 2004-02-02
  • 打赏
  • 举报
回复
在view中添加命令响应,当然需要视图处于激活状态了
zickphy 2004-02-02
  • 打赏
  • 举报
回复
up

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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