如何将两个相似的MFC列表框事件处理函数合并为一个?
解决方案
可以用模板函数封装重复逻辑,把不同的枚举类型作为模板参数,结合列表框引用传递,就能解决静态类型转换的适配问题,同时完美复用两个事件里的共性代码。
步骤1:编写通用模板函数
把两个事件处理里的重复逻辑抽出来,用模板参数指定枚举类型——因为GetPersonnelForMeeting是重载函数,编译器会自动根据模板参数匹配对应的重载版本:
template <typename AssignmentEnum> void UpdatePersonnelForAssignment(CListBox& listBox) { int selectedIndex = listBox.GetCurSel(); if (selectedIndex == LB_ERR) return; // 获取选中项的文本(假设文本对应枚举值的数值或标识) CString assignmentStr; listBox.GetText(selectedIndex, assignmentStr); // 按实际转换逻辑将文本转为目标枚举类型 AssignmentEnum assignmentType = static_cast<AssignmentEnum>(_ttoi(assignmentStr)); // 调用重载的GetPersonnelForMeeting auto personnelList = GetPersonnelForMeeting(assignmentType); // 这里放两个事件处理里完全相同的后续逻辑(比如刷新人员列表UI等) // ... }
步骤2:修改原事件处理函数
原来的两个事件函数只需要简单调用模板函数,指定对应的枚举类型即可:
// OCLM列表框的选择变更事件 void CYourDialog::OnSelchangeLbAssignmentsOclm() { UpdatePersonnelForAssignment<MSAToolsLibrary::AssignmentType>(m_lbAssignmentsOCLM); } // Weekend列表框的选择变更事件 void CYourDialog::OnSelchangeLbAssignmentsWeekend() { UpdatePersonnelForAssignment<MSAToolsLibrary::WeekendAssignmentType>(m_lbAssignmentsWeekend); }
灵活适配特殊转换逻辑
如果枚举值的转换不是简单的_ttoi转数值,可以扩展模板,把转换逻辑作为参数传入,适配更复杂的场景:
template <typename AssignmentEnum, typename ConvertFunc> void UpdatePersonnelForAssignment(CListBox& listBox, ConvertFunc convert) { int selectedIndex = listBox.GetCurSel(); if (selectedIndex == LB_ERR) return; CString assignmentStr; listBox.GetText(selectedIndex, assignmentStr); // 使用传入的转换逻辑生成枚举值 AssignmentEnum assignmentType = convert(assignmentStr); auto personnelList = GetPersonnelForMeeting(assignmentType); // 通用后续逻辑 // ... }
调用时传入自定义转换逻辑:
void CYourDialog::OnSelchangeLbAssignmentsOclm() { UpdatePersonnelForAssignment<MSAToolsLibrary::AssignmentType>( m_lbAssignmentsOCLM, [](const CString& str) { // 自定义转换逻辑,比如字符串映射枚举 if (str == _T("TypeA")) return MSAToolsLibrary::AssignmentType::TypeA; else if (str == _T("TypeB")) return MSAToolsLibrary::AssignmentType::TypeB; return MSAToolsLibrary::AssignmentType::Unknown; } ); }
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

