Decoding flags are not working correctly

1

I have designed some flags:

enum ImportAssignment
{
    OCLMChairman     = 0x00000001,
    OCLMOpenPrayer   = 0x00000002,
    OCLMClosePrayer  = 0x00000004,
    OCLMConductorCBS = 0x00000008,
    OCLMReaderCBS    = 0x00000016,
    PTChairman       = 0x00000032,
    PTHospitality    = 0x00000064,
    WTConductor      = 0x00000128,
    WTReader         = 0x00000256
};

In my dialog I read/write the flags from/to the registry:

void CImportOCLMAssignmentHistoryDlg::ReadSettings()
{
    m_dwImportFlags = theApp.GetNumberSetting(theApp.GetActiveScheduleSection(_T("Options")), _T("ImportFlags"), 0);
}


void CImportOCLMAssignmentHistoryDlg::SaveSettings()
{
    theApp.SetNumberSetting(theApp.GetActiveScheduleSection(_T("Options")), _T("ImportFlags"), m_dwImportFlags);
}

SetNumberSetting is basically a wrapper for GetProfileInt etc..

I then have two methods for encoding and decoding the flags into a series of BOOL variables (check boxes):

void CImportOCLMAssignmentHistoryDlg::DecodeImportFlags()
{
    m_bImportOCLMChairman = (m_dwImportFlags & ImportAssignment::OCLMChairman);
    m_bImportOCLMOpenPrayer = (m_dwImportFlags & ImportAssignment::OCLMOpenPrayer);
    m_bImportOCLMClosePrayer = (m_dwImportFlags & ImportAssignment::OCLMClosePrayer);
    m_bImportOCLMConductorCBS = (m_dwImportFlags & ImportAssignment::OCLMConductorCBS);
    m_bImportOCLMReaderCBS = (m_dwImportFlags & ImportAssignment::OCLMReaderCBS);
    m_bImportPTChairman = (m_dwImportFlags & ImportAssignment::PTChairman);
    m_bImportPTHospitality = (m_dwImportFlags & ImportAssignment::PTHospitality);
    m_bImportWTConductor = (m_dwImportFlags & ImportAssignment::WTConductor);
    m_bImportWTReader = (m_dwImportFlags & ImportAssignment::WTReader);
}


void CImportOCLMAssignmentHistoryDlg::EncodeImportFlags()
{
    m_dwImportFlags = 0; // Reset
    if (m_bImportOCLMChairman) m_dwImportFlags |= ImportAssignment::OCLMChairman;
    if (m_bImportOCLMOpenPrayer) m_dwImportFlags |= ImportAssignment::OCLMOpenPrayer;
    if (m_bImportOCLMClosePrayer) m_dwImportFlags |= ImportAssignment::OCLMClosePrayer;
    if (m_bImportOCLMConductorCBS) m_dwImportFlags |= ImportAssignment::OCLMConductorCBS;
    if (m_bImportOCLMReaderCBS) m_dwImportFlags |= ImportAssignment::OCLMReaderCBS;
    if (m_bImportPTChairman) m_dwImportFlags |= ImportAssignment::PTChairman;
    if (m_bImportPTHospitality) m_dwImportFlags |= ImportAssignment::PTHospitality;
    if (m_bImportWTConductor) m_dwImportFlags |= ImportAssignment::WTConductor;
    if (m_bImportWTReader) m_dwImportFlags |= ImportAssignment::WTReader;
}

When I first run the application the checkboxes are unticked. I then tick a couple. I close the dialog and re-open it. Always the first two are ticked.

I am supporting 64x and 32x builds.

What am I doing wrong?

c++
mfc
flags
asked on Stack Overflow Nov 19, 2016 by Andrew Truckle • edited Nov 19, 2016 by Danny_ds

1 Answer

2

On further debugging I found the solution to my problem.

I had to adjust my DecodeImportFlags method:

void CImportOCLMAssignmentHistoryDlg::DecodeImportFlags()
{
    m_bImportOCLMChairman = (m_iImportFlags & ImportAssignment::OCLMChairman) ? TRUE : FALSE;
    m_bImportOCLMOpenPrayer = (m_iImportFlags & ImportAssignment::OCLMOpenPrayer) ? TRUE : FALSE;
    m_bImportOCLMClosePrayer = (m_iImportFlags & ImportAssignment::OCLMClosePrayer) ? TRUE : FALSE;
    m_bImportOCLMConductorCBS = (m_iImportFlags & ImportAssignment::OCLMConductorCBS) ? TRUE : FALSE;
    m_bImportOCLMReaderCBS = (m_iImportFlags & ImportAssignment::OCLMReaderCBS) ? TRUE : FALSE;
    m_bImportPTChairman = (m_iImportFlags & ImportAssignment::PTChairman) ? TRUE : FALSE;
    m_bImportPTHospitality = (m_iImportFlags & ImportAssignment::PTHospitality) ? TRUE : FALSE;
    m_bImportWTConductor = (m_iImportFlags & ImportAssignment::WTConductor) ? TRUE : FALSE;
    m_bImportWTReader = (m_iImportFlags & ImportAssignment::WTReader) ? TRUE : FALSE;
}

It m_iImportFlags & ImportAssignment::XXXXX returns the actual flag value. So I needed conditional testing so that the BOOL could be set correctly.

Update: These are the ways I now declare the flags:

enum ImportAssignment
{
    /*
    OCLMChairman     = 1,
    OCLMOpenPrayer   = 2,
    OCLMClosePrayer  = 4,
    OCLMConductorCBS = 8,
    OCLMReaderCBS    = 16,
    PTChairman       = 32,
    PTHospitality    = 64,
    WTConductor      = 128,
    WTReader         = 256*/
    None             = 0,
    OCLMChairman     = 1 << 0,
    OCLMOpenPrayer   = 1 << 1,
    OCLMClosePrayer  = 1 << 2,
    OCLMConductorCBS = 1 << 3,
    OCLMReaderCBS    = 1 << 4,
    PTChairman       = 1 << 5,
    PTHospitality    = 1 << 6,
    WTConductor      = 1 << 7,
    WTReader         = 1 << 8
};
answered on Stack Overflow Nov 19, 2016 by Andrew Truckle • edited Nov 19, 2016 by Andrew Truckle

User contributions licensed under CC BY-SA 3.0