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.

 
     
    