• MFC基础-选项卡控件



    模块功能

    添加当前模块大概功能的描述,希望不要把所有接口文档写在一个文件中,至少按模块分类。
    创建选项卡控件

    • 创建主对话框和三个子窗口,其中 主对话框添加tab控件,子对话框设置无边框、类型为子窗口,并更改id
    • 三个子窗口分别绑定类,主窗口绑定一个变量
    • 主窗口绑定三个tab标签
    • 初始化子窗口
    • 缩放子窗口
    • 通过选项卡显示子窗口
    • 通过选项卡切换窗口

    选项卡控件的创建过程

    创建一个主对话框,和三个子对话框

    主对话框添加一个tab控件,

    子对话框设置无边框,风格为子窗口,并更改ID

    三个子窗口分别绑定一个类

    image.png

    主对话框绑定一个变量

    image.png

    变量绑定三个子对话框
    BOOL CMyDlg::OnInitDialog()
    {
    	// 如果这个地方没有编写这句话,数据就不会在初始化的时候进行绑定
    	CDialogEx::OnInitDialog();
    
    	// 初始化选项卡的选项名称和数量
    	m_TablCtrl.InsertItem(0, L"第一项");
    	m_TablCtrl.InsertItem(1, L"第二项");
    	m_TablCtrl.InsertItem(2, L"第三项");
    
    	// 为选项卡的每一项初始化对应的的窗口,Create 函数必须传入父类指针
    	m_TabWnd[0] = new CSubDialog1;
    	m_TabWnd[0]->Create(IDD_SUB_DIALOG1, &m_TablCtrl);
    	m_TabWnd[1] = new CSubDialog2;
    	m_TabWnd[1]->Create(IDD_SUB_DIALOG2, &m_TablCtrl);
    	m_TabWnd[2] = new CSubDialog3;
    	m_TabWnd[2]->Create(IDD_SUB_DIALOG3, &m_TablCtrl);
    
    	// 以选项爱看为基准,重新移动窗口的位置
    	CRect TabRect = { 0 };
    	m_TablCtrl.GetClientRect(TabRect);
    	TabRect.DeflateRect(4, 26, 6, 6);
    	for (int i = 0; i < 3; ++i)
    		m_TabWnd[i]->MoveWindow(TabRect);
    
    	// 默认显示第一项
    	ShowTabWindow(0);
    
    	return TRUE;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    初始化子窗口

    在函数声明中 ,创建一个CDialog类型的指针对象,在cpp中实现窗口初始化

    class CMyDlg : public CDialogEx
    {
      public:
        CDialogEx* m_TabWnd[3] = { 0 };
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    BOOL CMyDlg::OnInitDialog()
    {
    	// 如果这个地方没有编写这句话,数据就不会在初始化的时候进行绑定
    	CDialogEx::OnInitDialog();
    
    	// 为选项卡的每一项初始化对应的的窗口,Create 函数必须传入父类指针
    	m_TabWnd[0] = new CSubDialog1;
    	m_TabWnd[0]->Create(IDD_SUB_DIALOG1, &m_TablCtrl);
    	m_TabWnd[1] = new CSubDialog2;
    	m_TabWnd[1]->Create(IDD_SUB_DIALOG2, &m_TablCtrl);
    	m_TabWnd[2] = new CSubDialog3;
    	m_TabWnd[2]->Create(IDD_SUB_DIALOG3, &m_TablCtrl);
    
    	return TRUE;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    缩放子窗口位置,使其显示选项卡
    BOOL CMyDlg::OnInitDialog()
    {
    	// 如果这个地方没有编写这句话,数据就不会在初始化的时候进行绑定
    	CDialogEx::OnInitDialog();
    
    	// 以选项卡为基准,重新移动窗口的位置
    	CRect TabRect = { 0 };
    	m_TablCtrl.GetClientRect(TabRect);
    	TabRect.DeflateRect(4, 26, 6, 6);
    	for (int i = 0; i < 3; ++i)
    		m_TabWnd[i]->MoveWindow(TabRect);
    
    	return TRUE;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    显示窗口
    // 用于显示指定的窗口
    void CMyDlg::ShowTabWindow(int index)
    {
    	for (int i = 0; i < 3; ++i)
    	{
    		m_TabWnd[i]->ShowWindow(i == index ? SW_SHOWNORMAL : SW_HIDE);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    切换窗口

    在主对话框 属性 添加 事件处理程序,在函数中根据选项卡切换子对话框

    
    void CMyDlg::OnTcnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
    {
    	//获得当前索引号,返回值为Int型
    	ShowTabWindow(m_TablCtrl.GetCurSel());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    cpp中代码实现

    
    // CMyDlg.cpp: 实现文件
    //
    
    #include "pch.h"
    #include "framework.h"
    #include "CMyWinApp.h"
    #include "CMyDlg.h"
    #include "afxdialogex.h"
    #include "CSubDialog1.h"
    #include "CSubDialog2.h"
    #include "CSubDialog3.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    // CMyDlg 对话框
    
    
    // 将资源 ID 硬编码传入了父类的构造函数中,绑定了资源
    CMyDlg::CMyDlg(CWnd* pParent /*=nullptr*/)
    	: CDialogEx(IDD_DIALOG1, pParent) { }
    
    
    // 如果用户调用了 UpdateData 函数就会间接的进行数据交换,用户每绑定一个变量
    //	到控件,该函数中就会多出一行代码用于支持数据交换。[在响应父类 OnInitDialog
    //	消息的时候,这个函数也会被自动调用一次]
    void CMyDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialogEx::DoDataExchange(pDX);
    	DDX_Control(pDX, IDC_TAB1, m_TablCtrl);
    }
    
    
    // 在这两个宏的中间,编写相应消息对应的宏
    BEGIN_MESSAGE_MAP(CMyDlg, CDialogEx)
    	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, &CMyDlg::OnTcnSelchangeTab1)
    END_MESSAGE_MAP()
    
    
    // 响应对话框的创建消息
    BOOL CMyDlg::OnInitDialog()
    {
    	// 如果这个地方没有编写这句话,数据就不会在初始化的时候进行绑定
    	CDialogEx::OnInitDialog();
    
    	// 初始化选项卡的选项名称和数量
    	m_TablCtrl.InsertItem(0, L"第一项");
    	m_TablCtrl.InsertItem(1, L"第二项");
    	m_TablCtrl.InsertItem(2, L"第三项");
    
    	// 为选项卡的每一项初始化对应的的窗口,Create 函数必须传入父类指针
    	m_TabWnd[0] = new CSubDialog1;
    	m_TabWnd[0]->Create(IDD_SUB_DIALOG1, &m_TablCtrl);
    	m_TabWnd[1] = new CSubDialog2;
    	m_TabWnd[1]->Create(IDD_SUB_DIALOG2, &m_TablCtrl);
    	m_TabWnd[2] = new CSubDialog3;
    	m_TabWnd[2]->Create(IDD_SUB_DIALOG3, &m_TablCtrl);
    
    	// 以选项爱看为基准,重新移动窗口的位置
    	CRect TabRect = { 0 };
    	m_TablCtrl.GetClientRect(TabRect);
    	TabRect.DeflateRect(4, 26, 6, 6);
    	for (int i = 0; i < 3; ++i)
    		m_TabWnd[i]->MoveWindow(TabRect);
    
    	// 默认显示第一项
    	ShowTabWindow(0);
    
    	return TRUE;
    }
    
    // 用于显示指定的窗口
    void CMyDlg::ShowTabWindow(int index)
    {
    	for (int i = 0; i < 3; ++i)
    	{
    		m_TabWnd[i]->ShowWindow(i == index ? SW_SHOWNORMAL : SW_HIDE);
    	}
    }
    
    
    void CMyDlg::OnTcnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
    {
        //获得当前索引号,返回值为Int型
    	ShowTabWindow(m_TablCtrl.GetCurSel());
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    .h中代码实现

    
    // CMyDlg.h: 头文件
    //
    
    #pragma once
    
    
    // CMyDlg 对话框
    class CMyDlg : public CDialogEx
    {
    
    public:
    	// 构造函数要求传入的参数是指向父类对象的指针(不是句柄)
    	CMyDlg(CWnd* pParent = nullptr);
    
    // 和 [类向导] 相关,如果删除了这一行,那么类向导功能会不完整
    #ifdef AFX_DESIGN_TIME
    	enum { IDD = IDD_DIALOG1 };
    #endif
    
    protected:
    	// 支持变量和控件之间的数据交换
    	virtual void DoDataExchange(CDataExchange* pDX) override;
    
    
    protected:
    	// 这是一个虚函数,用于响应对话框的创建消息
    	virtual BOOL OnInitDialog() override;
    
    	// 用于显示指定的窗口
    	void ShowTabWindow(int index);
    
    	// 消息映射宏用于支持消息和对应函数的响应
    	DECLARE_MESSAGE_MAP()
    public:
    	CTabCtrl m_TablCtrl;
    	CDialogEx* m_TabWnd[3] = { 0 };
    	afx_msg void OnTcnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult);
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    结果展示

    5.gif

  • 相关阅读:
    Redis查询,设置超时时间
    Flink / Scala - ProcessFunction 之间共用缓存测试
    公众号模板消息
    使用js对象简单模拟虚拟dom的渲染
    Linux 环境Skywalking部署Elasticsearch
    SpringBoot读取配置文件的三种方法
    随机化算法
    【Android】settings命令幕后-----cmd命令
    less基本用法
    pdf格式转成jpg图片,pdf格式如何转jpg
  • 原文地址:https://blog.csdn.net/mengxj168/article/details/126884182