Humorly/windows-ui

我遇到了一个问题,就是tabctrl这个控件大佬用过么,我在单文档视图中用了这个控件,但是运行不了,我都是按照百度上做的,也没有报错,只是中断了不知道怎么看这个问题。。。

Closed this issue · 27 comments

@Qianzujin 单文档之中,m_tabctrl绑定在哪个tab控件之上?

@Qianzujin 单文档之中,m_tabctrl绑定在哪个tab控件之上?

展示view中的完整代码看看

// MFC-test-app-ver.4View.cpp : CMFCtestappver4View 类的实现
//

#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "MFC-test-app-ver.4.h"
#endif

#include "MFC-test-app-ver.4Doc.h"
#include "MFC-test-app-ver.4View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CMFCtestappver4View

IMPLEMENT_DYNCREATE(CMFCtestappver4View, CFormView)

BEGIN_MESSAGE_MAP(CMFCtestappver4View, CFormView)
ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, &CMFCtestappver4View::OnTcnSelchangeTab1)
ON_WM_CREATE()
END_MESSAGE_MAP()

// CMFCtestappver4View 构造/析构

CMFCtestappver4View::CMFCtestappver4View()
: CFormView(IDD_MFCTESTAPPVER4_FORM)
{
// TODO: 在此处添加构造代码

}

CMFCtestappver4View::~CMFCtestappver4View()
{
}

void CMFCtestappver4View::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TAB1, m_tabctrl);
}

BOOL CMFCtestappver4View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式

return CFormView::PreCreateWindow(cs);

}

void CMFCtestappver4View::OnInitialUpdate()
{

m_tabctrl.InsertItem(0, _T("页面1"));//“选项卡1”可更改,是sheet页的名字;
m_tabctrl.InsertItem(1, _T("页面2"));
m_tabctrl.InsertItem(2, _T("页面3"));

m_para1.Create(IDD_DIALOG1, &m_tabctrl);
m_para2.Create(IDD_DIALOG2, &m_tabctrl);
m_para3.Create(IDD_DIALOG3, &m_tabctrl);


CRect rs;
m_tabctrl.GetClientRect(&rs);
//调整子对话框在父窗口中的位置,可以改动数值,使子窗体的大小合适;
rs.top += 20;
rs.bottom -= 3;
rs.left += 2;
rs.right -= 2;
//设置子对话框尺寸并移动到指定位置
m_para1.MoveWindow(&rs);
m_para2.MoveWindow(&rs);
m_para3.MoveWindow(&rs);
//分别设置隐藏和显示
m_para1.ShowWindow(true);
m_para2.ShowWindow(false);
m_para3.ShowWindow(false);
//设置默认的选项卡
m_tabctrl.SetCurSel(0);



CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();

}

// CMFCtestappver4View 诊断

#ifdef _DEBUG
void CMFCtestappver4View::AssertValid() const
{
CFormView::AssertValid();
}

void CMFCtestappver4View::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}

CMFCtestappver4Doc* CMFCtestappver4View::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFCtestappver4Doc)));
return (CMFCtestappver4Doc*)m_pDocument;
}
#endif //_DEBUG

// CMFCtestappver4View 消息处理程序

void CMFCtestappver4View::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 在此添加控件通知处理程序代码
m_para1.ShowWindow(false);
m_para2.ShowWindow(false);
m_para3.ShowWindow(false);
int CurSel = m_tabctrl.GetCurSel();
switch (CurSel)
{
case 0:
m_para1.ShowWindow(true);
break;
case 1:
m_para2.ShowWindow(true);
break;
case 2:
m_para3.ShowWindow(true);
break;
}
*pResult = 0;
}

int CMFCtestappver4View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFormView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO:  在此添加您专用的创建代码



return 0;

}

BOOL CMFCtestappver4View::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
// TODO: 在此添加专用代码和/或调用基类

//添加选项卡


return CFormView::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);

}

image

中断一直执行完成后就变成这个样子了,没有上面的那个可以选择的框了
我用的是vs2015 但是应该和这个没有什么关系

image
网上的预期效果是这样的,就是按一个按钮切换一个页面这种,现在我的那个按钮没有,而且还中断

@Qianzujin 控件IDC_TAB1定义来自哪里呢,是直接定义在resource中的一个id值?

@Qianzujin 这个tab在另一个对话框上是吧

@Qianzujin 单文档中DDX_Control(pDX, IDC_TAB1, m_tabctrl); 绑定其他界面上的子控件是不合理的

@Qianzujin 在int CMFCtestappver4View::OnCreate(LPCREATESTRUCT lpCreateStruct)中调用:
m_tabctrl.Create(...),通过create方法创建这个tab,
同时去掉DDX_Control(pDX, IDC_TAB1, m_tabctrl)绑定,
之后OnInitialUpdate()中的insert应该没有问题

// MFC-test-app-ver.4View.cpp : CMFCtestappver4View 类的实现
//

#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "MFC-test-app-ver.4.h"
#endif

#include "MFC-test-app-ver.4Doc.h"
#include "MFC-test-app-ver.4View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CMFCtestappver4View

IMPLEMENT_DYNCREATE(CMFCtestappver4View, CFormView)

BEGIN_MESSAGE_MAP(CMFCtestappver4View, CFormView)
ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, &CMFCtestappver4View::OnTcnSelchangeTab1)
ON_WM_CREATE()
END_MESSAGE_MAP()

// CMFCtestappver4View 构造/析构

CMFCtestappver4View::CMFCtestappver4View()
: CFormView(IDD_MFCTESTAPPVER4_FORM)
{
// TODO: 在此处添加构造代码

}

CMFCtestappver4View::~CMFCtestappver4View()
{
}

void CMFCtestappver4View::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//DDX_Control(pDX, IDC_TAB1, m_tabctrl);
}

BOOL CMFCtestappver4View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式

return CFormView::PreCreateWindow(cs);

}

void CMFCtestappver4View::OnInitialUpdate()
{

m_tabctrl.InsertItem(0, _T("页面1"));//“选项卡1”可更改,是sheet页的名字;
m_tabctrl.InsertItem(1, _T("页面2"));
m_tabctrl.InsertItem(2, _T("页面3"));




CRect rs;
m_tabctrl.GetClientRect(&rs);
//调整子对话框在父窗口中的位置,可以改动数值,使子窗体的大小合适;
rs.top += 20;
rs.bottom -= 3;
rs.left += 2;
rs.right -= 2;
//设置子对话框尺寸并移动到指定位置
m_para1.MoveWindow(&rs);
m_para2.MoveWindow(&rs);
m_para3.MoveWindow(&rs);
//分别设置隐藏和显示
m_para1.ShowWindow(true);
m_para2.ShowWindow(false);
m_para3.ShowWindow(false);
//设置默认的选项卡
m_tabctrl.SetCurSel(0);



CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();

}

// CMFCtestappver4View 诊断

#ifdef _DEBUG
void CMFCtestappver4View::AssertValid() const
{
CFormView::AssertValid();
}

void CMFCtestappver4View::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}

CMFCtestappver4Doc* CMFCtestappver4View::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFCtestappver4Doc)));
return (CMFCtestappver4Doc*)m_pDocument;
}
#endif //_DEBUG

// CMFCtestappver4View 消息处理程序

void CMFCtestappver4View::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 在此添加控件通知处理程序代码
m_para1.ShowWindow(false);
m_para2.ShowWindow(false);
m_para3.ShowWindow(false);
int CurSel = m_tabctrl.GetCurSel();
switch (CurSel)
{
case 0:
m_para1.ShowWindow(true);
break;
case 1:
m_para2.ShowWindow(true);
break;
case 2:
m_para3.ShowWindow(true);
break;
}
*pResult = 0;
}

int CMFCtestappver4View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFormView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO:  在此添加您专用的创建代码
m_para1.Create(IDD_DIALOG1, &m_tabctrl);
m_para2.Create(IDD_DIALOG2, &m_tabctrl);
m_para3.Create(IDD_DIALOG3, &m_tabctrl);


return 0;

}

BOOL CMFCtestappver4View::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
// TODO: 在此添加专用代码和/或调用基类

//添加选项卡


return CFormView::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);

}

这样吗? 但是我还是没有运行成功 还是中断了

int CMFCtestappver4View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFormView::OnCreate(lpCreateStruct) == -1)
return -1;
// 构建tabctrl
RECT rect(0, 0, 500, 500);
m_tabctrl.Create(TCS_TABS | TCS_FIXEDWIDTH | WS_CHILD | WS_VISIBLE,
rect, this, IDC_MYTAB);

// TODO: 在此添加您专用的创建代码
m_para1.Create(IDD_DIALOG1, &m_tabctrl);
m_para2.Create(IDD_DIALOG2, &m_tabctrl);
m_para3.Create(IDD_DIALOG3, &m_tabctrl);

return 0;
}

@Qianzujin 定义一下IDC_MYTAB的值 = 10001啥的都行

妙啊!

妙啊!

大佬
请问COwnerDrawTabList这个控件咋用的?

不能直接替换CTabCtrl

请问能否在demo中演示一下?

大佬 请问COwnerDrawTabList这个控件咋用的?

不能直接替换CTabCtrl

请问能否在demo中演示一下?

不能直接替换CTabCtrl,COwnerDrawTabList是基于CStatic实现的,只提供了上面的tab条,没有提供Tab的子页面。
子页面需要tab条的选择来主动触发显示那个界面
具体代码参照上面的贴图

zgrwq commented
zgrwq commented

大佬 请问COwnerDrawTabList这个控件咋用的?
不能直接替换CTabCtrl
请问能否在demo中演示一下?

不能直接替换CTabCtrl,COwnerDrawTabList是基于CStatic实现的,只提供了上面的tab条,没有提供Tab的子页面。 子页面需要tab条的选择来主动触发显示那个界面 具体代码参照上面的贴图

替换tab条的话 tabctrl控件怎么融合进这个 COwnerDrawTabList 没搞懂 我的不是单文档窗 是对话框

大佬 请问COwnerDrawTabList这个控件咋用的?
不能直接替换CTabCtrl
请问能否在demo中演示一下?

不能直接替换CTabCtrl,COwnerDrawTabList是基于CStatic实现的,只提供了上面的tab条,没有提供Tab的子页面。 子页面需要tab条的选择来主动触发显示那个界面 具体代码参照上面的贴图

替换tab条的话 tabctrl控件怎么融合进这个 COwnerDrawTabList 没搞懂 我的不是单文档窗 是对话框

例如在对话框中创建3个子窗口,默认有一个可见,另两个不可见,tab上有3个页面,点击到哪个tab让其对应的子窗口显示就行

大佬 请问COwnerDrawTabList这个控件咋用的?
不能直接替换CTabCtrl
请问能否在demo中演示一下?

不能直接替换CTabCtrl,COwnerDrawTabList是基于CStatic实现的,只提供了上面的tab条,没有提供Tab的子页面。 子页面需要tab条的选择来主动触发显示那个界面 具体代码参照上面的贴图

替换tab条的话 tabctrl控件怎么融合进这个 COwnerDrawTabList 没搞懂 我的不是单文档窗 是对话框

例如在对话框中创建3个子窗口,默认有一个可见,另两个不可见,tab上有3个页面,点击到哪个tab让其对应的子窗口显示就行

了解了 感谢