有没有更简单的方法来确定 none 的菜单项设置为 MF_CHECKED
Is there an easier way to determine that none of the menu items are set to MF_CHECKED
我的代码本身运行正常,我想知道是否有更简单的方法来确定是否至少有一个菜单项 checked.
上下文
CMFCMenuButton
正在使用该菜单,如下所示:
行为
菜单本质上是一组已选中 菜单项,用户可以根据需要切换。然后应用程序根据这些菜单项的状态执行一些操作。基本的东西。
目前我有这段代码片段(工作正常):
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]);
}
我只是想知道是否有更快的方法来查看 none 的菜单项是否已设置为 MF_CHECKED
?因为如果可以检测到该条件,我可以一起绕过 GetPublisher
代码并将它们添加到列表中。
我意识到我可以在 returns bool
的专用函数中重复我现有的 if
语句并这样做,但是有更简单的方法吗?
更新
菜单项的资源 ID 值是连续的,如下所示:
#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
但是菜单中途确实有一个分隔符。
宏问题
我想我会在一个测试项目上尝试宏观的想法。我在头文件中插入了这个宏:
#define PROCESSFILTER(id, cond) \
if (m_menuExtraPublisherFilter.GetMenuState(id, MF_BYCOMMAND) == MF_CHECKED) \
{ \
bNoExtraPublisherFilter = false; \
if (cond) \
bAdd = true; \
}
我将 m_menuExtraPublisherFilter
添加为 CDiialogEx
的 CMenu
成员变量。然后我创建了虚拟资源 ID ID_TEST
只是使用了一个标准条件,因为我无法访问演示中的工具库。在 OnInitDialog
我试过:
PROCESSFILTER(ID_TEST, 5 > 4);
但是它崩溃了。为什么?
根据评论中的建议,我最终创建了一个宏,并将其添加到头文件中:
#define PROCESSFILTER(id, cond) \
if (m_menuExtraPublisherFilter.GetMenuState(id, MF_BYCOMMAND) == MF_CHECKED) \
{ \
bNoExtraPublisherFilter = false; \
if (cond) \
bAdd = true; \
}
我将源代码简化为:
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;
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_UNBAPTISED_PUBLISHER, eServing == MSAToolsLibrary::Serving_UnbaptisedPublisher);
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_PUBLISHER, eServing == MSAToolsLibrary::Serving_Publisher);
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_REGULAR_PIONEER, eServing == MSAToolsLibrary::Serving_RegularPioneer);
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_OTHER, eServing == MSAToolsLibrary::Serving_Other);
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_NOT_APPOINTED, eAppointed == MSAToolsLibrary::Appointed_NotAppointed);
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_MINISTERIAL_SERVANT, eAppointed == MSAToolsLibrary::Appointed_MinisterialServant);
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_ELDER, eAppointed == MSAToolsLibrary::Appointed_Elder);
if(bNoExtraPublisherFilter)
{
// None of the menu items were checked
bAdd = true;
}
if(bAdd)
m_lbPublishers.AddString(aryStrNames[i]);
}
我必须确保的一件事是 CSplitButton
菜单是在执行宏之前构建的。否则,由于菜单具有无效句柄而引发异常。
我的代码本身运行正常,我想知道是否有更简单的方法来确定是否至少有一个菜单项 checked.
上下文
CMFCMenuButton
正在使用该菜单,如下所示:
行为
菜单本质上是一组已选中 菜单项,用户可以根据需要切换。然后应用程序根据这些菜单项的状态执行一些操作。基本的东西。
目前我有这段代码片段(工作正常):
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]);
}
我只是想知道是否有更快的方法来查看 none 的菜单项是否已设置为 MF_CHECKED
?因为如果可以检测到该条件,我可以一起绕过 GetPublisher
代码并将它们添加到列表中。
我意识到我可以在 returns bool
的专用函数中重复我现有的 if
语句并这样做,但是有更简单的方法吗?
更新
菜单项的资源 ID 值是连续的,如下所示:
#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
但是菜单中途确实有一个分隔符。
宏问题
我想我会在一个测试项目上尝试宏观的想法。我在头文件中插入了这个宏:
#define PROCESSFILTER(id, cond) \
if (m_menuExtraPublisherFilter.GetMenuState(id, MF_BYCOMMAND) == MF_CHECKED) \
{ \
bNoExtraPublisherFilter = false; \
if (cond) \
bAdd = true; \
}
我将 m_menuExtraPublisherFilter
添加为 CDiialogEx
的 CMenu
成员变量。然后我创建了虚拟资源 ID ID_TEST
只是使用了一个标准条件,因为我无法访问演示中的工具库。在 OnInitDialog
我试过:
PROCESSFILTER(ID_TEST, 5 > 4);
但是它崩溃了。为什么?
根据评论中的建议,我最终创建了一个宏,并将其添加到头文件中:
#define PROCESSFILTER(id, cond) \
if (m_menuExtraPublisherFilter.GetMenuState(id, MF_BYCOMMAND) == MF_CHECKED) \
{ \
bNoExtraPublisherFilter = false; \
if (cond) \
bAdd = true; \
}
我将源代码简化为:
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;
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_UNBAPTISED_PUBLISHER, eServing == MSAToolsLibrary::Serving_UnbaptisedPublisher);
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_PUBLISHER, eServing == MSAToolsLibrary::Serving_Publisher);
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_REGULAR_PIONEER, eServing == MSAToolsLibrary::Serving_RegularPioneer);
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_OTHER, eServing == MSAToolsLibrary::Serving_Other);
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_NOT_APPOINTED, eAppointed == MSAToolsLibrary::Appointed_NotAppointed);
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_MINISTERIAL_SERVANT, eAppointed == MSAToolsLibrary::Appointed_MinisterialServant);
PROCESSFILTER(ID_PUBLISHERS_DATABASE_EXTRA_FILTER_ELDER, eAppointed == MSAToolsLibrary::Appointed_Elder);
if(bNoExtraPublisherFilter)
{
// None of the menu items were checked
bAdd = true;
}
if(bAdd)
m_lbPublishers.AddString(aryStrNames[i]);
}
我必须确保的一件事是 CSplitButton
菜单是在执行宏之前构建的。否则,由于菜单具有无效句柄而引发异常。