• MFC 常用控件


    目录

    一、控件的交互方式

    二、CButton/CheckBox/RadioButton

    三、EditControl

    四、ListBox

    五、ComBox

    六、Progress/Timer

    七、PictureController

    八、ListControl

    九、Tree


    一、控件的交互方式

    得到控件的类的对象,就可以通过这个对象来操作类

    CWnd* GetDlgItem(int nID) const;

    添加变量-值/对象

    这两个都是在父窗口类中进行添加的

    • 添加变量,就可以获得控件的值,会在构造函数初始化,并且关联绑定,与UpdateData配合使用
    • 添加控件,就可以通过对象来操作控件,会进行关联绑定

    响应控件事件

    这些都是交互控件的方式都是要在父窗口类中进行比较好

    二、CButton/CheckBox/RadioButton

    这个三个控件类的父类都是CButton

    单选框处理

    一般主要是为了获得单选框选择的内容,所以要为单选框添加变量-值

    多个单选框要注意Group这个属性,在第一个要勾选上。

    一般会添加一个 int 型变量,多个对话框,值是按照TAB(CTRL+D)顺序从低到高从0开始加1

    构造函数中初始化为 -1

    在这个函数中完成关联绑定

    对于单选框值的处理可以使用 switch 进行处理

    多选框处理

    使用BOOL数组处理对话框

    关联与初始化

    按钮处理

    按钮的话,一般是响应消息;或者控制按钮禁用,通过使用disabled属性

    IsWindowEnabled():判断当前窗口是否可点;

    EnableWindow():设置当前窗口是否可点

    需求:点击确定后,会弹出选择结果,之后另外一个按钮由不可点切换到可点的状态。

    思路:响应按钮控件消息

    1. void CMFCCommonItemDlg::OnBnClickedBtnResult()
    2. {
    3. // TODO: 在此添加控件通知处理程序代码
    4. UpdateData();
    5. if (m_sex == -1)
    6. {
    7. MessageBox(_T("请选择性别"), _T("性别确实"), MB_OK | MB_ICONEXCLAMATION);
    8. return;
    9. }
    10. CString strMsg = CString(_T("您的性别是: ")) + ((m_sex == 0) ? _T("男") : _T("女")) + _T("\n");
    11. CString strFav = _T("");
    12. CString Favs[3] = { _T("足球"),_T("篮球"),_T("瑜伽") };
    13. for (int i = 0; i < 3; i++)
    14. {
    15. if (m_fav[i])
    16. {
    17. strFav += Favs[i];
    18. }
    19. }
    20. if (strFav.GetLength() > 0)
    21. {
    22. strMsg += _T("您的爱好是:") + strFav;
    23. }
    24. else
    25. {
    26. strMsg += _T("您没有任何爱好! ");
    27. }
    28. MessageBox(strMsg, _T("结果展示"));
    29. CWnd* pTestBtn = GetDlgItem(IDC_BUTTON3);
    30. if (pTestBtn->IsWindowEnabled() == FALSE)
    31. {
    32. pTestBtn->EnableWindow(TRUE);
    33. }
    34. else
    35. {
    36. pTestBtn->EnableWindow(FALSE);
    37. }
    38. }

    三、EditControl

    编辑框需要关注以下这个控件的属性,属性栏中点击属性看看下面的解释就明白了

    diabled与onlyread一摸一样,就是文字是否灰色,后者还可选中,两者均不可编辑

    想要实现编辑框多行文本,启动多行属性后,确定按钮会自动截胡Enter回车键,需要启用wantreturn,来让编辑款响应这个消息

    Tapstop,就是按下tab键是否可以停到编辑框中

    1. // 获得文本框控件
    2. CEdit* edit = (CEdit*)GetDlgItem(IDC_EDIT1);
    3. // 获取文本
    4. edit->GetWindowText(text);
    5. // 设置文本
    6. edit->SetWindowText(_T(""));
    7. //文本发生改变
    8. ON_EN_CHANGE(IDC_EDIT_TEXT, &CMFCCommonItemDlg::OnEnChangeEditText)

    遇到了一个很难绷的bug,偷个懒给编辑框使用默认的ID,resource.h文件中未出现错误,但是在父窗口类添加控制变量是关联错误,最后发现是VS2019把这个IDC_EDIT解析到IDC_FAMALE上

    四、ListBox

    列表的属性可以在VS上看看,都有说明,一般默认即可,选择这个属性一定要选上多行(血的教训)

    一般处理方式:要获取选中内容,需要一个控件变量

    给列表添加控件变量-控件类型,通过这个对象可以拿到对象的选择数据

    构造函数初始化列表

    处理列表选择

    1. void CMFCCommonItemDlg::OnBnClickedBtnTest()
    2. {
    3. // TODO: 在此添加控件通知处理程序代码
    4. // TODO: 在此添加控件通知处理程序代码
    5. // TODO: 在此添加控件通知处理程序代码
    6. CString strText;
    7. // 获取选择总数
    8. int total = m_company.GetSelCount();
    9. if (total == 0)
    10. {
    11. MessageBox(_T("没有选中任何公司"));
    12. return;
    13. }
    14. else
    15. {
    16. // 堆上开辟数组
    17. int* index = new int[total];
    18. strText += _T("你选中了");
    19. TCHAR buf[32] = _T("");
    20. //total 转换的整数值
    21. //buf 存储转换结果的缓冲区指针
    22. //32 是缓冲区的大小
    23. //10 表示使用十进制进行转换。
    24. _itow_s(total, buf, 32, 10);
    25. strText += buf;
    26. strText += _T("个公司\n");
    27. //用于获取选择的项目或条目保存到index
    28. m_company.GetSelItems(total, index);
    29. CString strTemp;
    30. for (int i = 0; i < total; i++)
    31. {
    32. m_company.GetText(index[i], strTemp);
    33. strText += strTemp + _T("");
    34. }
    35. delete[] index;
    36. MessageBox(strText);
    37. }
    38. }

    五、ComBox

    下拉列表由两部分组成,一部分是编辑框,一部分是单选;

    当下拉列表属性类型为:Simple时,就没有编辑框的功能;DROWLIST时,有编辑框的功能。

    可以在Data中编辑下拉列表的内容,;隔开

    其他属性一般默认即可

    给两个编辑框添加控件变量用来获取控件的选择内容和编辑框内容

    1. void CMFCCommonItemDlg::OnBnClickedBtnTestDroplist()
    2. {
    3. // TODO: 在此添加控件通知处理程序代码
    4. int cur = m_Simple.GetCurSel();
    5. if (cur == -1)
    6. {
    7. TRACE("%s(%d):当前没有选中任何列\n", __FILE__, __LINE__);
    8. }
    9. else
    10. {
    11. TRACE("%s(%d):当前没有选中第%d列\n", __FILE__, __LINE__, cur + 1);
    12. CString tmp;
    13. m_Simple.GetLBText(cur, tmp);
    14. MessageBox(tmp);
    15. }
    16. cur = m_listDrop.GetCurSel();
    17. CString tmp;
    18. if (cur == -1)
    19. {
    20. TRACE("%s(%d):当前没有选中任何列\n", __FILE__, __LINE__);
    21. m_listDrop.GetEditSel(); // 获取下拉列表编辑框的字符数量
    22. m_listDrop.GetWindowText(tmp); // 获取编辑框内容
    23. MessageBox(tmp);
    24. }
    25. else
    26. {
    27. TRACE("%s(%d):当前没有选中第%d列\n", __FILE__, __LINE__, cur + 1);
    28. m_listDrop.GetLBText(cur, tmp);
    29. MessageBox(tmp);
    30. }
    31. }

    六、Progress/Timer

    进度条的属性没什么值得关注的,一般使用默认即可,

    进度条类的常用方法

    1. // 设置进度条的范围是 0~10000
    2. m_progress.SetRange(0, 10000);// SetRange32();可设置范围更大
    3. // 获取当前进度
    4. int pos = m_progress.GetPos();
    5. // 设置当前进度
    6. m_progress.SetPos(pos + 500);
    7. // 获取进度条最大值,最小值
    8. int low, upper;
    9. m_progress.GetRange(low, upper);

    一般使用方式:

    给父窗口类添加一个进度条对象变量,再在父窗口类中增加一个成员变量来管理进度值,在初始化函数中初始化为0,同时设置进度条

    配合定时器使用,设置两个定时器,处理消息WM_TINER

    1. void CMFCCommonItemDlg::OnTimer(UINT_PTR nIDEvent)
    2. {
    3. // TODO: 在此添加消息处理程序代码和/或调用默认值
    4. static int count = 0;
    5. if (nIDEvent == 99)
    6. {
    7. m_progress.SetPos(m_progress_pos);
    8. }
    9. else if (nIDEvent == 10)
    10. {
    11. TRACE("%s(%d):%s %d\n", __FILE__, __LINE__, __FUNCTION__, GetTickCount());
    12. int low, upper;
    13. m_progress.GetRange(low, upper);
    14. if (m_progress_pos >= upper)
    15. {
    16. KillTimer(10);
    17. }
    18. else
    19. {
    20. m_progress_pos += 10;
    21. }
    22. }
    23. CDialogEx::OnTimer(nIDEvent);
    24. }

    第一个定时器作用是更新定时器,第二个是增加进度。

    七、PictureController

    想要加载图片资源,需要先在对话框的属性 ACCEPT FILE中选为 TRUE

    要处理对话框的 WM_DROPFILES 消息;PictureController要选择对应的图片属性

    位图要选择BITMAP,图标要选择ICON类型

    给PictureController添加控件变量

    1. void CMFCCommonItemDlg::OnDropFiles(HDROP hDropInfo)
    2. {
    3. // 得到拖曳进入对话框文件数量
    4. int count = DragQueryFile(hDropInfo, -1, NULL, 0);
    5. TCHAR sPath[MAX_PATH];
    6. char mbsPath[MAX_PATH * 2];
    7. for (int i = 0; i < count; i++)
    8. {
    9. memset(sPath, 0, sizeof(sPath));
    10. memset(mbsPath, 0, sizeof(mbsPath));
    11. // 获取文件名
    12. DragQueryFile(hDropInfo, i, sPath, MAX_PATH);
    13. size_t total = 0;
    14. wcstombs_s(&total, mbsPath, sizeof(mbsPath), sPath, MAX_PATH);
    15. TRACE("%s(%d):%s %s\n", __FILE__, __LINE__, __FUNCTION__, mbsPath);
    16. if (CString(sPath).Find(_T(".ico")))
    17. {
    18. HICON hIcon = (HICON)LoadImage(AfxGetInstanceHandle(), sPath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);
    19. m_picture.SetIcon(hIcon);
    20. }
    21. }
    22. // 重回,显示图片
    23. InvalidateRect(NULL);
    24. CDialogEx::OnDropFiles(hDropInfo);
    25. }

    DragQueryFile 是一个 Windows API 函数,通常用于检索拖放操作中的文件信息。它可以获取拖放操作中被拖动的文件的文件名或者文件数量等信息。

    这个函数的原型如下:

    1. UINT DragQueryFile(
    2. HDROP hDrop,
    3. UINT iFile,
    4. LPTSTR lpszFile,
    5. UINT cch
    6. );

    参数说明:

    • hDrop:标识拖放操作的句柄。
    • iFile:要检索的文件的索引,从零开始计数。
    • lpszFile:用于接收文件名的缓冲区。
    • cch:缓冲区的大小,以字符为单位。

    DragQueryFile 函数可以通过指定的索引值 iFile 来依次获取拖放操作中所涉及的文件名。当 iFile 为 0xFFFFFFFF 时,它将返回拖放操作中包含的文件数量。

    使用 DragQueryFile 函数,你可以方便地在拖放操作结束后获取拖放的文件信息,从而进行相应的处理和操作。

    这行代码使用了 wcstombs_s 函数来将宽字符字符串转换为多字节字符字符串。让我详细解释一下每个参数的作用:

    • &total:这是一个指向 size_t 类型的变量的指针,用来存储成功转换的字符数(不包括终止的空字符)。在函数调用后,total 会被设为转换后的字符数。
    • mbsPath:这是目标多字节字符缓冲区的指针,用来存储转换后的多字节字符串。
    • sizeof(mbsPath):这是目标缓冲区的大小,表示可以存储的最大字符数。
    • sPath:这是源宽字符字符串的指针,需要进行转换的原始字符串。
    • MAX_PATH:这是源宽字符字符串的最大长度。

    HICON hIcon = (HICON)LoadImage(AfxGetInstanceHandle(), sPath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);

    这行代码使用了 LoadImage 函数来加载图标文件,并将加载后的图标句柄存储在 hIcon 变量中。让我逐个解释每个参数的含义:

    • AfxGetInstanceHandle():这是 MFC 框架提供的函数,用于获取当前实例的模块句柄。
    • sPath:这是包含图标文件路径的字符串,指定要加载的图标文件的完整路径。
    • IMAGE_ICON:这个参数指定了要加载的是一个图标而不是位图。
    • 0 和 0:这两个参数分别表示期望的图标的宽度和高度。由于我们使用了 LR_DEFAULTSIZE 标志,这里的宽度和高度参数可以被忽略。
    • LR_LOADFROMFILE | LR_DEFAULTSIZE:这是加载图标的一组标志,LR_LOADFROMFILE 表示从文件加载图标,LR_DEFAULTSIZE 表示使用默认的图标尺寸。

    综合起来,这行代码的作用是从指定的文件路径加载图标,并将加载后的图标句柄存储在 hIcon 变量中。加载后的图标可以用于后续的显示或其他操作。

    AfxGetInstanceHandle 是一个 MFC(Microsoft Foundation Class)框架提供的函数,它用于获取当前实例的模块句柄。在 MFC 应用程序中,每个窗口或对话框都属于一个实例,而 AfxGetInstanceHandle 可以用来获取当前实例的模块句柄。

    模块句柄是操作系统中用来标识模块(如可执行文件或动态链接库)的唯一标识符。在 Windows 程序中,模块句柄可以用于加载资源、注册类、处理消息等操作。

    在这个特定的代码片段中,AfxGetInstanceHandle() 被用作 LoadImage 函数的第一个参数,以指示从哪个模块中加载图标文件。通过使用 AfxGetInstanceHandle,可以确保从当前应用程序实例的模块中加载图标文件。

    八、ListControl

    ListControl 属性中VIEW一般使用LIST,或者REPORT;始终显示选中内容设置为TRUE;单选可以设置选择,单选/多选,给一个控件变量

    初始化在OnInitDialog中

    1. // 设置背景颜色
    2. m_listData.SetBkColor(RGB(128, 255, 64));
    3. // 设置文本背景颜色
    4. m_listData.SetTextBkColor(RGB(128, 255, 64));
    5. // 插入列 LVCFMT_LEFT 文本左对齐
    6. m_listData.InsertColumn(0, _T("CHECK"), LVCFMT_LEFT, 200);
    7. m_listData.InsertColumn(1, _T("IP"), LVCFMT_LEFT, 140);
    8. m_listData.InsertColumn(2, _T("ID"), LVCFMT_LEFT, 240);
    9. m_listData.InsertColumn(3, _T("序号"), LVCFMT_LEFT, 50);
    10. // "DWORD" 是 Windows API 中定义的一种数据类型,代表双字(Double Word),即 32 位的无符号整数。
    11. // GetExtendedStyle 函数来获取列表视图控件(List View Control)的扩展样式
    12. DWORD extStyle = m_listData.GetExtendedStyle();
    13. // LVS_EX_FULLROWSELECT 表示在列表视图控件中选中整行而不是仅选中单元格。
    14. extStyle |= LVS_EX_FULLROWSELECT;
    15. // LVS_EX_GRIDLINES 表示在列表视图控件中显示网格线。
    16. extStyle |= LVS_EX_GRIDLINES;
    17. // LVS_EX_CHECKBOXES 表示在列表视图控件中显示复选框。
    18. extStyle |= LVS_EX_CHECKBOXES;
    19. // 设置拓展样式
    20. m_listData.SetExtendedStyle(extStyle);
    21. m_listData.InsertItem(0, CString("FALSE")); // 序号
    22. m_listData.SetItemText(0, 1, _T("192.168.0.1")); // IP
    23. m_listData.SetItemText(0, 2, _T("283749283747298")); // ID
    24. m_listData.SetItemText(0, 3, _T("0")); // CKECK
    25. m_listData.InsertItem(1, CString("TRUE"));
    26. m_listData.SetItemText(1, 1, _T("192.168.0.1")); // IP
    27. m_listData.SetItemText(1, 2, _T("283749283747298")); // ID
    28. m_listData.SetItemText(1, 3, _T("0")); // CKECK

    处理

    1. void CMFCCommonItemDlg::OnBnClickedBtnList()
    2. {
    3. // TODO: 在此添加控件通知处理程序代码
    4. // 获取选中了多少行
    5. int lineCount = m_listData.GetItemCount();
    6. // 获取列表视图的头部控件
    7. CHeaderCtrl* pHeader = m_listData.GetHeaderCtrl();
    8. // 从头部控件中获取列的数量
    9. int coloumnCount = pHeader->GetItemCount();
    10. // 获取每一个文本
    11. // 遍历行
    12. for (int i = 0; i < lineCount; i++)
    13. {
    14. // 当前行是否被选中
    15. if (m_listData.GetCheck(i))
    16. {
    17. TRACE("%s(%d):%s %s\n", __FILE__, __LINE__, __FUNCTION__, "选中");
    18. }
    19. else
    20. {
    21. TRACE("%s(%d):%s %s\n", __FILE__, __LINE__, __FUNCTION__, "未选中");
    22. }
    23. // 遍历列
    24. for (int j = 0; j < coloumnCount; j++)
    25. {
    26. CString temp = m_listData.GetItemText(i, j);
    27. char text[256];
    28. memset(text, 0, sizeof(text));
    29. size_t total;
    30. // 控件中往往是宽字节编码
    31. wcstombs_s(&total, text, sizeof(text), temp, temp.GetLength());
    32. TRACE("%s(%d):%s %s\n", __FILE__, __LINE__, __FUNCTION__, text);
    33. }
    34. }
    35. }

    九、Tree

    属性没什么值得关注的,默认的即可

    一般会使用一个图片类存储图,CImageList 是 MFC 中用来管理图像列表的类,它可以用于存储和管理一系列的图标或位图,并提供了方便的方法来对这些图像进行操作。一般来说,CImageList 对象通常用于在界面控件中显示图标,比如在树形控件、列表控件或工具栏中。

    初始化

    1. m_icons.Create(IDC_TREE_TEST, 32, 3, 0);
    2. m_tree.SetImageList(&m_icons, TVSIL_NORMAL);
    3. HTREEITEM hRoot = m_tree.InsertItem(_T("root"), 0, 1);
    4. HTREEITEM hLeaf1 = m_tree.InsertItem(_T("leaf"), 2, 1, hRoot);
    5. m_tree.InsertItem(_T("sub"), 2, 1, hLeaf1);
    6. HTREEITEM hLeaf2 = m_tree.InsertItem(_T("leaf"), 2, 1, hRoot);
    7. m_tree.InsertItem(_T("sub"), 2, 1, hLeaf2);

    CImageList::Create 方法用于创建一个图像列表,并且可以从资源中加载位图来初始化这个图像列表。下面是这个方法的参数含义:

    • nBitmapID:指定了包含图像资源的位图资源的 ID。
    • cx:指定了图像的宽度(以像素为单位)。
    • nGrow:指定了当图像列表中的图像数量超过当前分配的空间时,图像列表应该如何增长的标志。这通常设置为零,表示不进行增长。
    • crMask:指定了透明色的颜色值,用于创建具有透明效果的图像列表。当图像中包含此颜色值时,它会被视为透明部分。

    m_tree.SetImageList(&m_icons, TVSIL_NORMAL);

    这行代码将图像列表对象 m_icons 关联到树形控件 m_tree 上。具体来说,SetImageList 方法的参数含义如下:

    • 第一个参数 &m_icons 是指向图像列表对象的指针,表示要关联的图像列表。
    • 第二个参数 TVSIL_NORMAL 表示把图像列表应用到树形控件的普通状态图标上。

    通过这个操作,树形控件就可以使用图像列表中的图标来显示节点的图标了。

    处理 

    1. void CMFCCommonItemDlg::OnTvnSelchangedTreeTest(NMHDR* pNMHDR, LRESULT* pResult)
    2. {
    3. LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
    4. // TODO: 在此添加控件通知处理程序代码
    5. // 获取了树形控件中选中项的数量
    6. UINT nCount = m_tree.GetSelectedCount();
    7. if (nCount > 0)
    8. {
    9. // GetSelectedItem 函数获取当前选中项的句柄 hSelect
    10. HTREEITEM hSelect = m_tree.GetSelectedItem();
    11. // 使用 GetItemText 函数获取选中项的文本内容
    12. CString strText = m_tree.GetItemText(hSelect);
    13. char sText[256] = "";
    14. size_t total;
    15. wcstombs_s(&total, sText, sizeof(sText), strText, strText.GetLength());
    16. TRACE("%s(%d):%s %s\n", __FILE__, __LINE__, __FUNCTION__, sText);
    17. }
    18. *pResult = 0;
    19. }

  • 相关阅读:
    Go语言 context包源码学习
    基于SpringBoot的在线试题库系统设计与实现
    MasterAlign相机参数设置-曝光时间调节
    【C++干货基地】深度理解C++中的高效内存管理方式 new & delete
    绍兴市越城区人大常委会主任徐荻一行莅临迪捷软件调研指导
    民安智库(第三方市场调研公司)哪家残疾人服务满意度调研公司比较专业
    Win11 22000.1041 RP预览版发布:带来两大功能更新
    腾讯mini项目-【指标监控服务重构】2023-08-29
    京准、ntp校时服务器(GPS北斗卫星校时器)技术方案
    部署ZFile在线网盘
  • 原文地址:https://blog.csdn.net/qq_61553520/article/details/134295891