My code in itself is working OK and I am wondering if there is a simpler way to determine if at least one of my menu items are checked.
Context
The menu is being used by a CMFCMenuButton
and looks like this:
Behaviour
The menu is essentially a set of checked menu items which the user can toggle as needed. The application then performs some actions based on the state of these menu items. Basic stuff.
At the moment I have this code snippet (working fine):
MSAToolsLibrary::IPublisherPtr pPublisher = nullptr;
if (theApp.MSAToolsInterface().GetPublisher(aryStrNames[i], pPublisher))
{
bool bAdd = false;
MSAToolsLibrary::Serving eServing;
MSAToolsLibrary::Appointed eAppointed;
pPublisher->get_ServingAs(&eServing);
pPublisher->get_AppointedAs(&eAppointed);
bool bNoExtraPublisherFilter = true;
if (m_menuExtraPublisherFilter.GetMenuState(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_UNBAPTISED_PUBLISHER, MF_BYCOMMAND) == MF_CHECKED)
{
bNoExtraPublisherFilter = false;
if (eServing == MSAToolsLibrary::Serving_UnbaptisedPublisher)
bAdd = true;
}
if (m_menuExtraPublisherFilter.GetMenuState(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_PUBLISHER, MF_BYCOMMAND) == MF_CHECKED)
{
bNoExtraPublisherFilter = false;
if (eServing == MSAToolsLibrary::Serving_Publisher)
bAdd = true;
}
if (m_menuExtraPublisherFilter.GetMenuState(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_REGULAR_PIONEER, MF_BYCOMMAND) == MF_CHECKED)
{
bNoExtraPublisherFilter = false;
if (eServing == MSAToolsLibrary::Serving_RegularPioneer)
bAdd = true;
}
if (m_menuExtraPublisherFilter.GetMenuState(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_OTHER, MF_BYCOMMAND) == MF_CHECKED)
{
bNoExtraPublisherFilter = false;
if (eServing == MSAToolsLibrary::Serving_Other)
bAdd = true;
}
if (m_menuExtraPublisherFilter.GetMenuState(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_NOT_APPOINTED, MF_BYCOMMAND) == MF_CHECKED)
{
bNoExtraPublisherFilter = false;
if (eAppointed == MSAToolsLibrary::Appointed_NotAppointed)
bAdd = true;
}
if (m_menuExtraPublisherFilter.GetMenuState(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_MINISTERIAL_SERVANT, MF_BYCOMMAND) == MF_CHECKED)
{
bNoExtraPublisherFilter = false;
if (eAppointed == MSAToolsLibrary::Appointed_MinisterialServant)
bAdd = true;
}
if (m_menuExtraPublisherFilter.GetMenuState(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_ELDER, MF_BYCOMMAND) == MF_CHECKED)
{
bNoExtraPublisherFilter = false;
if (eAppointed == MSAToolsLibrary::Appointed_Elder)
bAdd = true;
}
if(bNoExtraPublisherFilter)
{
// None of the menu items were checked
bAdd = true;
}
if(bAdd)
m_lbPublishers.AddString(aryStrNames[i]);
}
I just wondered if there is a quicker way to see if none of the menu items have been set to MF_CHECKED
? Because if that condition can be detected I could bypass the GetPublisher
code all together and just add them to the list.
I realise I can repeat my existing if
statements in a dedicated function that returns bool
and do it that way but is there an easier way?
Update
The resource ID values for the menu items are sequential, as follows:
#define ID_PUBLISHERS_DATABASE_EXTRA_FILTER_PUBLISHER 35389
#define ID_PUBLISHERS_DATABASE_EXTRA_FILTER_REGULAR_PIONEER 35390
#define ID_PUBLISHERS_DATABASE_EXTRA_FILTER_NOT_APPOINTED 35391
#define ID_PUBLISHERS_DATABASE_EXTRA_FILTER_MINISTERIAL_SERVANT 35392
#define ID_PUBLISHERS_DATABASE_EXTRA_FILTER_ELDER 35393
#define ID_PUBLISHERS_DATABASE_EXTRA_FILTER_UNBAPTISED_PUBLISHER 35394
#define ID_PUBLISHERS_DATABASE_EXTRA_FILTER_OTHER 35395
But the menu does have a separator part way through.
Issues with Macro
I thought I would try the macro idea on a test project. I inserted this macro in the header file:
#define PROCESSFILTER(id, cond) \
if (m_menuExtraPublisherFilter.GetMenuState(id, MF_BYCOMMAND) == MF_CHECKED) \
{ \
bNoExtraPublisherFilter = false; \
if (cond) \
bAdd = true; \
}
I added m_menuExtraPublisherFilter
as a CMenu
member variable of a CDiialogEx
. I then created dummy resource ID ID_TEST
just used a standard condition since I don't have access to my tools library in the demo. In OnInitDialog
I tried:
PROCESSFILTER(ID_TEST, 5 > 4);
But it crashes. Why?
Based on the suggestions in the comment I ended up creating a macro which I added to the header file:
And I simplified the source code to this:
The one thing that I had to ensure was that the
CSplitButton
menu was constructed before the macro is executed. Otherwise an exception is raised due to the menu having an invalid handle.