ToB企服应用市场:ToB评测及商务社交产业平台

标题: MFC动态创建控件并添加消息映射 [打印本页]

作者: tsx81428    时间: 2022-11-20 22:14
标题: MFC动态创建控件并添加消息映射
目录

指定ID

在类中声明并定义按钮控件的起始ID,以控件的类型和功能对动态控件ID进行分组,每组最好定义一个自己的起始ID方便管理:
  1. #define IDC_CONTROL_START   1000
  2. #define IDC_BTN_START       IDC_CONTROL_START+100
  3. #define IDC_STA_START       IDC_CONTROL_START+200
  4. #define IDC_EIT_START       IDC_CONTROL_START+300
  5. #define IDC_CMB_START       IDC_CONTROL_START+400
复制代码
起始ID可以设置大一点,避免与窗体内部的控件ID重复,上面定义了四种控件的起始ID。
对象指针

根据动态控件的生命周期,在对应的作用域里面定义控件对象的指针,一般会定义在头文件里保证控件和窗体生命周期相同:
  1. std::vector<CButton*>pBtn;
  2. std::vector<CStatic*>pSta;
  3. std::vector<CEdit*>pCet;
  4. std::vector<CComboBox*>pCmb;
复制代码
注:使用vector容器便于扩充控件数量,需添加头文件vector
建立对象

在类的OnInitDialog()函数中动态创建按钮:
  1. int count = 3;
  2. int width = 100;
  3. int height = 50;
  4. int space = 20;
  5. pBtn.resize(count);
  6. pSta.resize(count);
  7. pCet.resize(count);
  8. pCmb.resize(count);
  9. int L, T, R, B;
  10. CWnd* pWnd = this;
  11. //可以使用其它控件作为父窗体,但消息处理会很麻烦
  12. //pWnd = GetDlgItem(IDC_STATIC_GROUP);
  13. DWORD dwStyle;
  14. CRect rect;
  15. for (size_t i = 0; i < count; i++)
  16. {
  17.         L = 20 + i * (width + space);
  18.         T = 20 + 0 * (height + space);
  19.         dwStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_FLAT;
  20.         rect = CRect(L, T, L + width, T + height);
  21.         pBtn[i] = new CButton();
  22.         pBtn[i]->Create(_T("按钮"), dwStyle, rect, pWnd, IDC_BTN_START + i);
  23.         T = 20 + 1 * (height + space);
  24.         dwStyle = WS_CHILD | WS_VISIBLE | SS_CENTER;
  25.         rect = CRect(L, T, L + width, T + height);
  26.         pSta[i] = new CStatic();
  27.         pSta[i]->Create(_T("文本"), dwStyle,rect, pWnd, IDC_CONTROL_START + 200);
  28.         T = 20 + 2 * (height + space);
  29.         dwStyle = ES_MULTILINE | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER;
  30.         rect = CRect(L, T, L + width, T + height);
  31.         pCet[i] = new CEdit();
  32.         pCet[i]->Create(dwStyle,rect , pWnd, IDC_CONTROL_START + 300);
  33.         pCet[i]->SetWindowText(_T("编辑"));
  34.         //下拉框的高度必须设大一点,防止不能选中项
  35.         T = 20 + 3 * (height + space);
  36.         dwStyle = WS_VISIBLE | WS_CHILD | CBS_DROPDOWNLIST | CBS_HASSTRINGS;
  37.         rect = CRect(L, T, L + width, T + height + 100);
  38.         pCmb[i] = new CComboBox();
  39.         pCmb[i]->Create(dwStyle, rect, pWnd, IDC_CONTROL_START + 400);
  40.         pCmb[i]->AddString(_T("1"));
  41.         pCmb[i]->AddString(_T("2"));
  42.         pCmb[i]->AddString(_T("3"));
  43. }
复制代码
上面的控件布局可以按自己的来,重要的是Create()函数,每个控件的Create()函数不一样,以最底层CWnd类的Create()函数进行说明:
  1. virtual BOOL Create(LPCTSTR lpszClassName,
  2.         LPCTSTR lpszWindowName, DWORD dwStyle,
  3.         const RECT& rect,
  4.         CWnd* pParentWnd, UINT nID,
  5.         CCreateContext* pContext = NULL);
复制代码
参考:https://learn.microsoft.com/zh-cn/cpp/mfc/reference/cwnd-class?view=msvc-170#create
lpszClassName、lpszWindowName、pContext这三个参数不确定的情况下,可以传入NULL。
其它控件的Create()函数参考 MFC 类 中的控件类
运行效果如下图:

控件样式

如果给定 WS_VISIBLE 样式,Windows发送按钮控件所需的所有信息激活和显示按钮,还可以将以下 窗口样式 应用于控件:
每种控件还有自己的样式,详细内容见 MFC使用的样式
消息映射

一个MFC的消息响应函数在程序中有以下三部分:
关于消息映射的更多内容参考 消息映射(MFC)
按钮单击

可以使用常规方法,根据ID为按钮绑定单击的消息响应函数:
  1. ON_BN_CLICKED(IDC_BTN_START + 0, &CMFCApplication1Dlg::OnBtnClik)
复制代码
如果生成的按钮比较多,一个个处理会很麻烦,需要使用批量绑定,批量绑定按钮单击消息响应函数的步骤:
  1. afx_msg void OnBtnClick(UINT uID);
复制代码
注:OnBtnClick函数的参数nID代表响应函数对应按钮控件的ID号,单个按钮可不设参数。
  1. ON_COMMAND_RANGE(IDC_BTN_START + 0, IDC_BTN_START + 3, &CMFCApplication1Dlg::OnBtnClik)
复制代码
注:在函数实现文件中的消息映射部分(BEGIN_MESSAGE_MAP与END_MESSAGE_MAP之间)定义按钮控件与其消息响应函数之间的映射关系。
  1. void CMFCApplication1Dlg::OnBtnClik(UINT uID)
  2. {
  3.         int id = uID -IDC_BTN_START;
  4.         CString str;
  5.         str.Format("当前ID %d", id);
  6.         int result = MessageBox(str, TEXT("确认"), MB_YESNO);
  7. }
复制代码
组合框选中

使用ON_CBN_SELCHANGE消息:
  1. ON_CBN_SELCHANGE(IDC_CMB_START, &CMFCApplication1Dlg::OnSelComChange)
复制代码
声明消息响应函数:
  1. afx_msg void OnSelComChange();
复制代码
实现消息响应函数:
  1. void CMFCApplication1Dlg::OnSelComChange()//选择下拉框某一列的时候得到响应
  2. {
  3.         for (size_t i = 0; i < pCmb.size(); i++)
  4.         {
  5.                 if (pCmb[i]==GetFocus())
  6.                 {
  7.                         CString str(_T(""));//获取当前下拉框的值
  8.                         pCmb[i]->GetLBText(pCmb[i]->GetCurSel(), str);//获取CComBox下拉框当前选中的值                       
  9.                         MessageBox(str, TEXT("确认"), MB_OK);
  10.                 }
  11.         }       
  12. }
复制代码
疑问:明明对一个控件ID映射了消息响应函数,但后面的组合框控件都能进入OnSelComChange() 函数,后面有时间再研究。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4