首页 > 其他分享 >MFC动态创建控件并处理消息

MFC动态创建控件并处理消息

时间:2022-11-20 20:57:18浏览次数:71  
标签:控件 MFC 动态创建 ID START WS 响应函数 IDC

目录

指定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() 函数,后面有时间再研究。

标签:控件,MFC,动态创建,ID,START,WS,响应函数,IDC
From: https://www.cnblogs.com/timefiles/p/16909479.html

相关文章

  • MFC插入对话框
    方法一:  方法二:         添加后的对话框:         ......
  • SAP UI5 SmartTable 控件本地运行时进行 Excel 导出的单步调试
    点击SmartTable控件生成的表格控件的ExporttoExcel时,遇到如下错误消息:Thefollowingerrorhasoccurredduringexport:Unexpectedserverresponse:SmartT......
  • MFC模态与非模态对话框
              ......
  • C# 自定义控件 UserControl 绑定
    主界面<Windowx:Class="MyWPFSimple2.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.mic......
  • WPF自定义控件之消息提示
    创建消息提示控件internalclassMessage:ContentControl{publicintTime{get;set;}[Bindable(true)]publicMessageTypeMes......
  • 【WPF】ComboBox控件
    ComboBox控件属性IsTextSearchEnabled="True":自动补充数据IsTextSearchCaseSensitive=true;自动补充数据,区分大小写IsDropDownOpen="True":combobox自动打开下拉框......
  • Android 使用ui控件 【文本显示控件,按钮控件】
    目录注意事项创建控件监控按钮按下修改文本展示控件的内容注意事项1创建控件后一定要设置控件id2控件的修改必须在主线程中创建控件在清单文件中创建控件,我是通过可......
  • 配置实现-编辑详述控件
     编辑详述控件是组合控件,根据配置的控件集合及展现方式生成相应的展示或编辑控件,可用于以下场景:1、详述展现页面2、编辑页面3、查询列表的查询条件4、导出Excel时选择导出......
  • 配置实现-列表控件
    列表控件仿照GridView制作,可以绑定DataTable和对象列表:1、    支持点击标题重新排序、标题合并、行分组合并及行相同数据列合并2、    支持标题列改变宽度,固定列表......
  • python笔记76-types.FunctionType 动态创建函数
    前言types.FunctionType创建函数有2种方式:从已有函数的基础上,创建一个新函数从一个compile构建的函数对象上,创建一个新函数FunctionType使用FunctionType可以用......