背景:
MFC工具带有tab标签,作为导航。需要在对话框初始化时进行初始化。

一、流程简述

实现此功能需要做如下事情:

  • 创建主对话框、多个子对话框。
  • 子对话框需要设置属性:
    外观Style为Child,Boarder选None。
  • 关联tab标签控件变量(也可以直接用控件ID)。
  • 初始化,子对话框添加到tab标签上。
  • 响应点击函数,以便切换对话框。

下面先列出原始版本,分析问题,再解决问题。
本文省略MFC控件布局的说明。

二、原始版本

2.1 变量声明

namespace NSONVIF {enum PAGE_TYPE {PAGE_DISCOVER = 0,PAGE_DEVICE,PAGE_MEDIA,PAGE_IMAGING,PAGE_DEBUG,PAGE_MAX,};
}std::vector<CDialog *> m_pvPage;NSONVIF::PAGE_TYPE m_nCurTab;CDiscover m_cDlgDiscover;CDeviceService m_cDlgDevice;CMediaService m_cDlgMedia;CImagingService m_cDlgImaging;CDebugInfo m_cDlgDebug;CTabCtrl m_ctrTab;

使用m_pvPage存放子对话框指针。m_cDlg开头的变量为子对话框。m_ctrTab为Tab控件关联的类。

2.2 初始化

    m_ctrTab.InsertItem(0, "Discover");m_ctrTab.InsertItem(1, "Device");m_ctrTab.InsertItem(2, "Media");m_ctrTab.InsertItem(3, "Imaging");m_ctrTab.InsertItem(4, "Debug");m_pvPage.resize(NSONVIF::PAGE_MAX);m_cDlgDiscover.Create(IDD_DLG_DISCOVER, &m_ctrTab);m_pvPage[NSONVIF::PAGE_DISCOVER] = &m_cDlgDiscover;m_cDlgDiscover.SetOnvifProxy(&m_cProxy);m_cDlgDevice.Create(IDD_DLG_DEVICE, &m_ctrTab);m_pvPage[NSONVIF::PAGE_DEVICE] = &m_cDlgDevice;m_cDlgDevice.SetOnvifProxy(&m_cProxy);m_cDlgMedia.Create(IDD_DLG_MEDIA, &m_ctrTab);m_pvPage[NSONVIF::PAGE_MEDIA] = &m_cDlgMedia;m_cDlgMedia.SetOnvifProxy(&m_cProxy);m_cDlgImaging.Create(IDD_DLG_IMAGING, &m_ctrTab);m_pvPage[NSONVIF::PAGE_IMAGING] = &m_cDlgImaging;m_cDlgImaging.SetOnvifProxy(&m_cProxy);m_cDlgDebug.Create(IDD_DLG_DEBUG, &m_ctrTab);m_pvPage[NSONVIF::PAGE_DEBUG] = &m_cDlgDebug;m_cDlgDebug.SetOnvifProxy(&m_cProxy);CRect rc;m_ctrTab.GetClientRect(rc);rc.top += 22;rc.bottom -= 1;rc.left += 1;rc.right -= 1;for (unsigned int i = 0; i < m_pvPage.size(); i++){m_pvPage[i]->MoveWindow(&rc);}// first pagem_nCurTab = NSONVIF::PAGE_DISCOVER;m_pvPage[m_nCurTab]->ShowWindow(SW_SHOW);

2.3 响应点击事件

即添加OnTcnSelchangeTab事件并实现

void COnvifClientDlg::OnTcnSelchangeTab(NMHDR *pNMHDR, LRESULT *pResult)
{*pResult = 0;m_pvPage[m_nCurTab]->ShowWindow(SW_HIDE);m_nCurTab = static_cast<NSONVIF::PAGE_TYPE>(m_ctrTab.GetCurSel());if (m_pvPage[m_nCurTab])m_pvPage[m_nCurTab]->ShowWindow(SW_SHOW);
}

三、存在问题

原始版本的代码有点死板,不够灵动:

  • 多了控件顺序的宏定义。命名空间可删除。
  • 重复但又有差异的代码较多。如初始化代码。

四、改良版本

4.1 变量声明

    std::vector<CDialog *> m_pvPage;int m_nCurTab; // 直接用int即可CDiscover m_cDlgDiscover;CDeviceService m_cDlgDevice;CMediaService m_cDlgMedia;CImagingService m_cDlgImaging;CDebugInfo m_cDlgDebug;CTabCtrl m_ctrTab;

初始化

struct cDlgCtrl_t {LPCTSTR name;CDialogEx* dlg;int id;
};LPCTSTR lpName[10]; // make bigger...int i = 0;lpName[i++] = L"Discover";lpName[i++] = L"Device";lpName[i++] = L"Media";lpName[i++] = L"Imaging";lpName[i++] = L"Debug";i = 0;struct cDlgCtrl_t dlgCtrls[10]; // make bigger...dlgCtrls[i].name = lpName[i];dlgCtrls[i].dlg = &m_cDlgDiscover;dlgCtrls[i].id = IDD_DLG_DISCOVER;dlgCtrls[++i].name = lpName[i];dlgCtrls[i].dlg = &m_cDlgDevice;dlgCtrls[i].id = IDD_DLG_DEVICE;dlgCtrls[++i].name = lpName[i];dlgCtrls[i].dlg = &m_cDlgMedia;dlgCtrls[i].id = IDD_DLG_MEDIA;dlgCtrls[++i].name = lpName[i];dlgCtrls[i].dlg = &m_cDlgImaging;dlgCtrls[i].id = IDD_DLG_IMAGING;dlgCtrls[++i].name = lpName[i];dlgCtrls[i].dlg = &m_cDlgDebug;dlgCtrls[i].id = IDD_DLG_DEBUG;CRect rc;m_ctrTab.GetClientRect(rc);rc.top += 22;rc.bottom -= 1;rc.left += 1;rc.right -= 1;m_pvPage.resize(i+1);for (unsigned int i = 0; i < m_pvPage.size(); i++){m_ctrTab.InsertItem(i, dlgCtrls[i].name);dlgCtrls[i].dlg->Create(dlgCtrls[i].id, &m_ctrTab);dlgCtrls[i].dlg->SetOnvifProxy(&m_cProxy);m_pvPage[i] = dlgCtrls[i].dlg;      m_pvPage[i]->MoveWindow(&rc);}m_nCurTab = 0;m_pvPage[m_nCurTab]->ShowWindow(SW_SHOW);

4.2 响应点击事件

void COnvifClientDlg::OnTcnSelchangeTab(NMHDR *pNMHDR, LRESULT *pResult)
{*pResult = 0;m_pvPage[m_nCurTab]->ShowWindow(SW_HIDE);m_nCurTab = m_ctrTab.GetCurSel();if (m_pvPage[m_nCurTab])m_pvPage[m_nCurTab]->ShowWindow(SW_SHOW);
}

相对而言,改良后的代码更好维护。

五 切换页面

在初始化时,遍历每个子对话框,并调用 Create 创建窗口,注意,此时会调用到子对话框的OnInitDialog函数(哪怕当时没有显示出来)。
当切换 Tab 时,子对话框并不会再次初始化。因此,需要在切换响应函数 OnTcnSelchangeTab 中显示进行。示例如下:

void COnvifClientDlg::OnTcnSelchangeTab(NMHDR *pNMHDR, LRESULT *pResult)
{*pResult = 0;m_pvPage[m_nCurTab]->ShowWindow(SW_HIDE);m_nCurTab = m_ctrTab.GetCurSel();if (m_pvPage[m_nCurTab]){m_pvPage[m_nCurTab]->ShowWindow(SW_SHOW);if (m_nCurTab == 0) // 当切换到第0个子对话框时{CDiscover* dlg = (CDiscover*)m_pvPage[m_nCurTab];dlg->Reinit(); // 重新初始化}}
}

注:是否可以直接调用子对话框的 OnInitDialog 函数,未测试。

MFC笔记:初始化tab控件一点改进相关推荐

  1. Visual C++网络编程经典案例详解 第9章 实用播放器 界面初始化 tab控件初始化 InsertItem()原型

    如果启动后 没有响应歌曲 则tab控件提示用户 播放器没有歌曲要添加歌曲 否则播放歌曲 添加成员变量对话框修改变量名称为m_tab 使用CTabCtrl类对象m_tab在TAB控件中添加属性页 Ins ...

  2. MFC笔记2(控件位置调整)

    1.根据计算,使用GetClientRect(& ...)就可以调整好 2.遇到了OK和Cancel按钮通过GetDlgItem(ID..)找不到id资源号的情况,最后通过给控件绑定控件变量到 ...

  3. MFC Tab控件的使用方法

    新建一个mfc项目a 在资源视图中,对a.rc右键,添加资源,选择Dialog,新建 之后会创建一个新的窗口,为窗口添加一个static text控件,改名为tab1 对窗口属性进行设置,Border ...

  4. MFC Tab 控件使用

    1. 新建一个基于 dialog 的空 MFC 工程 2. 添加两个新的对话框作为子对话框 接下来两步,每个子对话框都要操作: 2.1 设置各子对话框属性为 "child, none&quo ...

  5. MFC中动态创建控件以及事件响应实现方法

    本文实例讲述了MFC中动态创建控件以及事件响应实现方法,分享给大家供大家参考.具体实现方法如下: 动态控件是指在需要时由Create()创建的控件,这与预先在对话框中放置的控件是不同的. 一.创建动态 ...

  6. MFC中动态创建控件以及添加事件响应

    本文实例讲述了MFC中动态创建控件以及事件响应实现方法,分享给大家供大家参考.具体实现方法如下: 动态控件是指在需要时由Create()创建的控件,这与预先在对话框中放置的控件是不同的. 一.创建动态 ...

  7. 似乎是发现了asp.net ajaxToolkit中TAB控件的一个BUG

    刚才想整理一下文章,不知道怎么搞的,一下子就没了,从新帖. 在一个项目当中,使用了asp.net ajaxToolkit中的TAB控件. 现在TAB中做布局,内容等等,没发现问题. 开始处理逻辑了,问 ...

  8. VC MFC列表视图(CListCtrl)控件

    VC MFC列表视图(CListCtrl)控件 列表视图控件 图标风格 CListCtrl类里要了解的函数 SetImageList为列表控件关联一个图像列表 InsertItem插入一项 GetSe ...

  9. tab控件的使用心得

    现在要做一个登陆系统,功能包括注册消息,修改消息,登陆等等.考虑使用tab控件来将所有功能都集中在一个对话框中实现. step1  在主对话框中拖入一个tab控件,命名随意,在ClassWizard为 ...

最新文章

  1. Django博客系统(写博客页面展示分类)
  2. asp实现301跳转的方法
  3. c++ 调用python返回指针
  4. 程序猿修仙之路--算法之直接插入排序
  5. 小程序跳转样式布局错乱_小程序 wxss 样式毁三观
  6. 花体英文字帖pdf可打印_考研政治 | 马原24个主观题答题原理!PDF可打印!
  7. Android RotateAnimation详解
  8. C# Repeater根据条件后台设置前台行背景色
  9. java权限管理与用户角色权限设计
  10. cad怎么导出jpg图片格式?
  11. uwb定位与wifi、蓝牙和RFID定位技术的区别
  12. Android面试总结系列之面试技巧
  13. 关于Visual Studio 2017安装时共享组件、工具和 SDK安装位置不能更改的问题
  14. Centos7下的LibreOffice的搭建及自动化脚本部署
  15. win7任务栏计算机怎么显示桌面,在win7任务栏添加一个显示桌面的图标按钮的方法...
  16. 明了的 —— Mysql 多表连接查询
  17. 如何成为一个成熟男人
  18. 解决django运行manage.py runscript命令时报错Try running with a higher verbosity level like: -v2 or -v3
  19. activiti学习01
  20. 《求医不如求己》1,2,3全集下载(附人体穴位图)

热门文章

  1. pycharm引用python_在Python/Pycharm中找不到引用“xxx”
  2. 一位湖北大学的学生作品,看后久久不能平静
  3. 小米12 Ultra外观设计曝光:白色陶瓷机身 后置硕大相机模组
  4. 不仅有骁龙8 Plus!摩托罗拉新旗舰还要抢首发2亿像素
  5. 快手与央视达成合作:除夕晚8点上快手看春晚
  6. 你的下一代iPhone何必是iPhone,苹果或将于2022年推出AR设备取代手机
  7. 三星Galaxy S22系列零部件开始量产:搭载骁龙898 最早1月亮相
  8. 蔡崇信将担任阿里巴巴集团第一组董事
  9. 三星Galaxy M52 5G通过认证:两个版本 搭载骁龙778G芯片
  10. Soul递交IPO招股书:腾讯为第一大股东,依然处于亏损状态