首页IT科技mfc添加自定义消息(MFC动态创建控件并添加消息映射)

mfc添加自定义消息(MFC动态创建控件并添加消息映射)

时间2025-06-14 05:51:32分类IT科技浏览4909
导读:指定ID 在类中...

指定ID

在类中声明并定义按钮控件的起始ID            ,以控件的类型和功能对动态控件ID进行分组                      ,每组最好定义一个自己的起始ID方便管理:

#define IDC_CONTROL_START 1000 #define IDC_BTN_START IDC_CONTROL_START+100 #define IDC_STA_START IDC_CONTROL_START+200 #define IDC_EIT_START IDC_CONTROL_START+300 #define IDC_CMB_START IDC_CONTROL_START+400

起始ID可以设置大一点      ,避免与窗体内部的控件ID重复         ,上面定义了四种控件的起始ID               。

对象指针

根据动态控件的生命周期                      ,在对应的作用域里面定义控件对象的指针          ,一般会定义在头文件里保证控件和窗体生命周期相同:

std::vector<CButton*>pBtn; std::vector<CStatic*>pSta; std::vector<CEdit*>pCet; std::vector<CComboBox*>pCmb;

注:使用vector容器便于扩充控件数量      ,需添加头文件vector                  。

建立对象

在类的OnInitDialog()函数中动态创建按钮:

int count = 3; int width = 100; int height = 50; int space = 20; pBtn.resize(count); pSta.resize(count); pCet.resize(count); pCmb.resize(count); int L, T, R, B; CWnd* pWnd = this; //可以使用其它控件作为父窗体                     ,但消息处理会很麻烦 //pWnd = GetDlgItem(IDC_STATIC_GROUP); DWORD dwStyle; CRect rect; for (size_t i = 0; i < count; i++) { L = 20 + i * (width + space); T = 20 + 0 * (height + space); dwStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_FLAT; rect = CRect(L, T, L + width, T + height); pBtn[i] = new CButton(); pBtn[i]->Create(_T("按钮"), dwStyle, rect, pWnd, IDC_BTN_START + i); T = 20 + 1 * (height + space); dwStyle = WS_CHILD | WS_VISIBLE | SS_CENTER; rect = CRect(L, T, L + width, T + height); pSta[i] = new CStatic(); pSta[i]->Create(_T("文本"), dwStyle,rect, pWnd, IDC_CONTROL_START + 200); T = 20 + 2 * (height + space); dwStyle = ES_MULTILINE | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER; rect = CRect(L, T, L + width, T + height); pCet[i] = new CEdit(); pCet[i]->Create(dwStyle,rect , pWnd, IDC_CONTROL_START + 300); pCet[i]->SetWindowText(_T("编辑")); //下拉框的高度必须设大一点              ,防止不能选中项 T = 20 + 3 * (height + space); dwStyle = WS_VISIBLE | WS_CHILD | CBS_DROPDOWNLIST | CBS_HASSTRINGS; rect = CRect(L, T, L + width, T + height + 100); pCmb[i] = new CComboBox(); pCmb[i]->Create(dwStyle, rect, pWnd, IDC_CONTROL_START + 400); pCmb[i]->AddString(_T("1")); pCmb[i]->AddString(_T("2")); pCmb[i]->AddString(_T("3")); }

上面的控件布局可以按自己的来   ,重要的是Create()函数                    ,每个控件的Create()函数不一样                  ,以最底层CWnd类的Create()函数进行说明:

virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);

参考:https://learn.microsoft.com/zh-cn/cpp/mfc/reference/cwnd-class?view=msvc-170#create

lpszClassName:指向以 null 结尾的字符串的指针,该字符串包含已注册的系统窗口类的名称;或者为预定义的系统窗口类的名称       。 lpszWindowName:指向以 null 结尾的字符串的指针                ,该字符串包含窗口显示名称;否则为 NULL                      ,表示没有窗口显示名称            。 dwStyle:窗口样式的按位组合 (OR)   , WS_POPUP 选项不是有效样式                   。 rect:窗口相对于父窗口左上角的大小和位置          。 pParentWnd:指向父窗口的指针        。 nID:窗口的 ID                    。 pContext:指向 CCreateContext 结构的指针            ,该结构用于自定义应用程序的文档视图体系结构             。

lpszClassName            、lpszWindowName                      、pContext这三个参数不确定的情况下                      ,可以传入NULL    。

其它控件的Create()函数参考 MFC 类

中的控件类

运行效果如下图:

控件样式

如果给定 WS_VISIBLE 样式      ,Windows发送按钮控件所需的所有信息激活和显示按钮         ,还可以将以下 窗口样式 应用于控件:

始终WS_CHILD 通常WS_VISIBLE 少见WS_DISABLED 对控件分组的WS_GROUP 包含控件的WS_TABSTOP 按tab键顺序

每种控件还有自己的样式                      ,详细内容见 MFC使用的样式

消息映射

一个MFC的消息响应函数在程序中有以下三部分:

函数原型:头文件中在两个AFX_MSG注释宏之间是消息响应函数原型的声明                     。 函数实现:源文件中的消息响应函数的实现代码                。 关联消息和消息响应函数的宏:在源文件AFX_MSG_MAP注释宏之间的消息映射宏          ,用来关联消息和消息响应函数。

关于消息映射的更多内容参考 消息映射(MFC)                  。

按钮单击

可以使用常规方法      ,根据ID为按钮绑定单击的消息响应函数:

ON_BN_CLICKED(IDC_BTN_START + 0, &CMFCApplication1Dlg::OnBtnClik)

如果生成的按钮比较多                     ,一个个处理会很麻烦              ,需要使用批量绑定   ,批量绑定按钮单击消息响应函数的步骤:

在对话框类的定义文件(.h文件)中声明消息响应函数OnBtnClick                   。 afx_msg void OnBtnClick(UINT uID);

注:OnBtnClick函数的参数nID代表响应函数对应按钮控件的ID号                    ,单个按钮可不设参数    。

在对话框类的函数实现文件(.cpp文件)中定义消息映射ON_COMMAND_RANGE (多个按钮)                  ,根据其输入ID分辨具体响应那个按钮               。 ON_COMMAND_RANGE(IDC_BTN_START + 0, IDC_BTN_START + 3, &CMFCApplication1Dlg::OnBtnClik)

注:在函数实现文件中的消息映射部分(BEGIN_MESSAGE_MAP与END_MESSAGE_MAP之间)定义按钮控件与其消息响应函数之间的映射关系                  。

实现消息响应函数OnBtnClick,在对话框类的函数实现文件(.cpp文件)中给出具体的按钮消息响应       。 void CMFCApplication1Dlg::OnBtnClik(UINT uID) { int id = uID -IDC_BTN_START; CString str; str.Format("当前ID %d", id); int result = MessageBox(str, TEXT("确认"), MB_YESNO); }

组合框选中

使用ON_CBN_SELCHANGE消息:

ON_CBN_SELCHANGE(IDC_CMB_START, &CMFCApplication1Dlg::OnSelComChange)

声明消息响应函数:

afx_msg void OnSelComChange();

实现消息响应函数:

void CMFCApplication1Dlg::OnSelComChange()//选择下拉框某一列的时候得到响应 { for (size_t i = 0; i < pCmb.size(); i++) { if (pCmb[i]==GetFocus()) { CString str(_T(""));//获取当前下拉框的值 pCmb[i]->GetLBText(pCmb[i]->GetCurSel(), str);//获取CComBox下拉框当前选中的值 MessageBox(str, TEXT("确认"), MB_OK); } } }

疑问:明明对一个控件ID映射了消息响应函数                ,但后面的组合框控件都能进入OnSelComChange() 函数                      ,后面有时间再研究            。

声明:本站所有文章   ,如无特殊说明或标注            ,均为本站原创发布                   。任何个人或组织                      ,在未征得本站同意时      ,禁止复制      、盗用         、采集                      、发布本站内容到任何网站          、书籍等各类媒体平台          。如若本站内容侵犯了原著者的合法权益         ,可联系我们进行处理        。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
如何制作键盘(从零开始制作【立体键盘】,画UI免写CSS,【盲打练习】的交互逻辑只用了10来行表达式!) 怎么检测是否支持win11(Win11如何查看系统是否激活?Windows11检查激活状态三种方法)