I have reviewed this excellent answer but I am still confused. Ultimately I will have 10 method all behaving similar. Here is an example of three I have written already:
void CChristianLifeMinistryEditorDlg::OnSwapWithChairmanAssignment(UINT nID)
{
// We need to locate the name for this assignment
auto iter = m_mapSwapAssignments.find(nID);
if (iter != m_mapSwapAssignments.end())
{
// We found it
CChristianLifeMinistryEntry *pReplacement = m_mapSwapAssignments[nID];
CString strExistingName = _T(""), strReplacementName = _T("");
GetDlgItemText(m_iSwapAssignmentSourceID, strExistingName);
CString strPrompt = _T("");
strPrompt.Format(_T("Swap assignments:\n\n%s - %s\n%s - %s\n\nPlease confirm."),
m_pEntry->GetMeetingDateAsString(),
(LPCTSTR)strExistingName,
pReplacement->GetMeetingDateAsString(),
(LPCTSTR)pReplacement->GetChairman());
if (AfxMessageBox(strPrompt, MB_ICONQUESTION | MB_YESNO) == IDYES)
{
strReplacementName = pReplacement->GetChairman();
pReplacement->SetChairman(strExistingName);
SetDlgItemText(m_iSwapAssignmentSourceID, strReplacementName);
SetModified(true);
}
}
}
void CChristianLifeMinistryEditorDlg::OnSwapWithOpenPrayerAssignment(UINT nID)
{
// We need to locate the name for this assignment
auto iter = m_mapSwapAssignments.find(nID);
if (iter != m_mapSwapAssignments.end())
{
// We found it
CChristianLifeMinistryEntry *pReplacement = m_mapSwapAssignments[nID];
CString strExistingName = _T(""), strReplacementName = _T("");
GetDlgItemText(m_iSwapAssignmentSourceID, strExistingName);
CString strPrompt = _T("");
strPrompt.Format(_T("Swap assignments:\n\n%s - %s\n%s - %s\n\nPlease confirm."),
m_pEntry->GetMeetingDateAsString(),
(LPCTSTR)strExistingName,
pReplacement->GetMeetingDateAsString(),
(LPCTSTR)pReplacement->GetOpenPrayer());
if (AfxMessageBox(strPrompt, MB_ICONQUESTION | MB_YESNO) == IDYES)
{
strReplacementName = pReplacement->GetOpenPrayer();
pReplacement->SetOpenPrayer(strExistingName);
SetDlgItemText(m_iSwapAssignmentSourceID, strReplacementName);
SetModified(true);
}
}
}
void CChristianLifeMinistryEditorDlg::OnSwapWithClosePrayerAssignment(UINT nID)
{
// We need to locate the name for this assignment
auto iter = m_mapSwapAssignments.find(nID);
if (iter != m_mapSwapAssignments.end())
{
// We found it
CChristianLifeMinistryEntry *pReplacement = m_mapSwapAssignments[nID];
CString strExistingName = _T(""), strReplacementName = _T("");
GetDlgItemText(m_iSwapAssignmentSourceID, strExistingName);
CString strPrompt = _T("");
strPrompt.Format(_T("Swap assignments:\n\n%s - %s\n%s - %s\n\nPlease confirm."),
m_pEntry->GetMeetingDateAsString(),
(LPCTSTR)strExistingName,
pReplacement->GetMeetingDateAsString(),
(LPCTSTR)pReplacement->GetClosePrayer());
if (AfxMessageBox(strPrompt, MB_ICONQUESTION | MB_YESNO) == IDYES)
{
strReplacementName = pReplacement->GetClosePrayer();
pReplacement->SetClosePrayer(strExistingName);
SetDlgItemText(m_iSwapAssignmentSourceID, strReplacementName);
SetModified(true);
}
}
}
I want to code the code from each of those event handlers into a method.
GetChairman
SetChairman
GetOpenPrayer
SetOpenPrayer
GetClosePrayer
SetClosePrayer
I have tried this:
void CChristianLifeMinistryEditorDlg::SwapAssignments(UINT nID, CString(*GetExistingName), void(*SetReplacementName)(CString))
{
// We need to locate the name for this assignment
auto iter = m_mapSwapAssignments.find(nID);
if (iter != m_mapSwapAssignments.end())
{
// We found it
CChristianLifeMinistryEntry *pReplacement = m_mapSwapAssignments[nID];
CString strExistingName = _T(""), strReplacementName = _T("");
GetDlgItemText(m_iSwapAssignmentSourceID, strExistingName);
CString strPrompt = _T("");
strPrompt.Format(_T("Swap assignments:\n\n%s - %s\n%s - %s\n\nPlease confirm."),
m_pEntry->GetMeetingDateAsString(),
(LPCTSTR)strExistingName,
pReplacement->GetMeetingDateAsString(),
(LPCTSTR)pReplacement->(*GetExistingName));
if (AfxMessageBox(strPrompt, MB_ICONQUESTION | MB_YESNO) == IDYES)
{
strReplacementName = pReplacement->(*GetExistingName);
pReplacement->(*SetReplacementName)(strExistingName);
SetDlgItemText(m_iSwapAssignmentSourceID, strReplacementName);
SetModified(true);
}
}
}
I get build errors:
How can pass these methods as parameters?
I see this other answer that I was hoping I could use but the problem is that the method being called is a member of an object. So it won't allow it.
Current Workaround
At the moment I have implemented a couple of functions:
CString CChristianLifeMinistryEntry::GetName(SwapAssignment eAssignment)
{
switch (eAssignment)
{
case SwapAssignment::Chairman:
return GetChairman();
case SwapAssignment::Counsellor1:
return GetAuxiliaryCounsellor1();
case SwapAssignment::Counsellor2:
return GetAuxiliaryCounsellor2();
case SwapAssignment::OpenPrayer:
return GetOpenPrayer();
case SwapAssignment::Treasures1:
return GetTreasures1();
case SwapAssignment::Treasures2:
return GetTreasures2();
case SwapAssignment::Living1:
return GetLiving1();
case SwapAssignment::Living2:
return GetLiving2();
case SwapAssignment::ConductorCBS:
return GetCBSConductor();
case SwapAssignment::ReaderCBS:
return GetCBSReader();
case SwapAssignment::ClosePrayer:
return GetClosePrayer();
}
return _T("");
}
// AJT v18.1.6
void CChristianLifeMinistryEntry::SetName(CString strName, SwapAssignment eAssignment)
{
switch (eAssignment)
{
case SwapAssignment::Chairman:
SetChairman(strName);
break;
case SwapAssignment::Counsellor1:
SetAuxiliaryCounsellor1(strName);
break;
case SwapAssignment::Counsellor2:
SetAuxiliaryCounsellor2(strName);
break;
case SwapAssignment::OpenPrayer:
SetOpenPrayer(strName);
break;
case SwapAssignment::Treasures1:
SetTreasures1(strName);
break;
case SwapAssignment::Treasures2:
SetTreasures2(strName);
break;
case SwapAssignment::Living1:
SetLiving1(strName);
break;
case SwapAssignment::Living2:
SetLiving2(strName);
break;
case SwapAssignment::ConductorCBS:
SetCBSConductor(strName);
break;
case SwapAssignment::ReaderCBS:
SetCBSReader(strName);
break;
case SwapAssignment::ClosePrayer:
SetClosePrayer(strName);
break;
}
}
Then I moved the code I mentioned with a little adjustment into a new method:
// AJT v18.1.6
void CChristianLifeMinistryEditorDlg::SwapAssignments(UINT nID, SwapAssignment eAssignment)
{
// We need to locate the name for this assignment
auto iter = m_mapSwapAssignments.find(nID);
if (iter != m_mapSwapAssignments.end())
{
// We found it
CChristianLifeMinistryEntry *pReplacement = m_mapSwapAssignments[nID];
CString strExistingName = _T(""), strReplacementName = _T("");
GetDlgItemText(m_iSwapAssignmentSourceID, strExistingName);
CString strPrompt = _T("");
strPrompt.Format(_T("Swap assignments:\n\n%s - %s\n%s - %s\n\nPlease confirm."),
m_pEntry->GetMeetingDateAsString(),
(LPCTSTR)strExistingName,
pReplacement->GetMeetingDateAsString(),
(LPCTSTR)pReplacement->GetName(eAssignment));
if (AfxMessageBox(strPrompt, MB_ICONQUESTION | MB_YESNO) == IDYES)
{
strReplacementName = pReplacement->GetName(eAssignment);
pReplacement->SetName(strExistingName, eAssignment);
if (pReplacement == m_pEntry) // Swapping assignments on same meeting!
SetDlgItemText(IDC_COMBO_OCLM_CBS_READER, strExistingName);
SetDlgItemText(m_iSwapAssignmentSourceID, strReplacementName);
SetModified(true);
}
}
}
So now my 11 handlers look similar to this:
// AJT v18.1.6
void CChristianLifeMinistryEditorDlg::OnSwapWithCBSReaderAssignment(UINT nID)
{
SwapAssignments(nID, SwapAssignment::ReaderCBS);
}
It works. But I see a new comment has been added to my question with a link so I will see if I can get anywhere.