Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么可以';我不能禁用/灰显菜单项吗?(MFC)_C++_Mfc_Cmenu - Fatal编程技术网

C++ 为什么可以';我不能禁用/灰显菜单项吗?(MFC)

C++ 为什么可以';我不能禁用/灰显菜单项吗?(MFC),c++,mfc,cmenu,C++,Mfc,Cmenu,我正在尝试使用CMenu::EnableMenuItem()方法禁用/灰显菜单项 我有一个CMenu*变量pMenu,它引用了对话框的顶部菜单。我可以使用pMenu->GetSubMenu(int)获取子菜单,并使用submenu->GetMenuStringA(),验证返回的子菜单/菜单项的名称。但是,EnableMenuItem()方法有问题。假设有一个文件菜单。其中有新建和打开弹出菜单和导入,关闭,以及关闭所有菜单项。New和Open具有子菜单项。(例如New->Document)使用子菜

我正在尝试使用
CMenu::EnableMenuItem()
方法禁用/灰显菜单项

我有一个
CMenu*
变量
pMenu
,它引用了对话框的顶部菜单。我可以使用
pMenu->GetSubMenu(int)
获取子菜单,并使用
submenu->GetMenuStringA()
,验证返回的子菜单/菜单项的名称。但是,
EnableMenuItem()
方法有问题。假设有一个
文件
菜单。其中有
新建
打开
弹出菜单和
导入
关闭
,以及
关闭所有
菜单项。
New
Open
具有子菜单项。(例如
New->Document
)使用
子菜单->启用项([子菜单位置/menuitem],MF_BYPOSITION | MF_灰显)我可以禁用
新建
打开
,但是
导入
关闭
全部关闭
,以及带有
新建
打开
的所有菜单项的功能失败

注意:当我说
EnableMenuItem()
失败时,我并不是说它返回-1。它返回以前的状态,但菜单不会变为禁用或灰显


EnableMenuItem()
的MSDN文档中:它声称这将适用于弹出式菜单项和标准菜单项。不过,它似乎只适用于弹出式菜单项。

MFC有另一种启用/禁用菜单项的方案,该方案正在撤消您正在执行的操作。要在MFC方案中工作,请在_UPDATE_CMD_UI上添加消息处理程序,如下所述:


ScottMcP MVP MFC声明在ON_UPDATE_命令_UI处理程序中执行菜单配置:当应用程序的用户下拉菜单时,每个菜单项都需要知道是否应显示为已启用或已禁用。菜单命令的目标通过实现ON_UPDATE_command_UI处理程序来提供此信息。对于应用程序中的每个命令用户界面对象,使用“属性”窗口为每个处理程序创建消息映射项和函数原型

当下拉菜单时,框架搜索并调用每个ON_UPDATE_COMMAND_UI处理程序,每个处理程序调用CCmdUI成员函数,如Enable和Check,然后框架适当地显示每个菜单项


这意味着您必须在自己的类中存储可以选中/取消选中的菜单项的预期状态。您必须在每个菜单元素的
ON\u COMMAND
宏附近的
ON\u命令\u UI
上放置一个
宏,该元素将引用接收CCmdUi对象的函数,您可以根据需要修改该对象。但是,当您使用MFC时,通常不会手动执行此操作,而只是使用包含菜单的窗口的属性。

问题是,我从外部应用程序执行所有这些操作。我正在使用主窗口的句柄获取它的菜单,然后使用GetSubMenu获取它的子菜单,我没有访问CCmdUI对象的权限。@Amre那么你就卡住了。您试图控制的应用程序正在通过其自己的CCmdUI对象不断重置启用/禁用状态,您所做的任何更改都将在毫秒内恢复。基本上,我试图通过此操作将oncommand消息发送到按钮。我正在尝试创建一个应用程序,可以用来测试我的应用程序的安全性,防止有人向控件发送oncommand或BNU clicked消息,并访问他们不应该访问的内容。我意识到我从未真正对此进行过更新。最后,我没有尝试启用灰显按钮或菜单项,只是在它们被禁用时调用它们。我这样做是为了这样的按钮:CWnd*selCWnd=//获取CWnd引用::SendMessage(selCWnd->m\u hWnd,WM\u LBUTTONDOWN,0,0);::发送消息(selCWnd->m_hWnd,WM_LBUTTONUP,0,0);所以我发现我可以只发送一个左键向下,然后是一个左键向上的命令,这模仿了点击它,它工作了!对于菜单项,我使用PostMessage并使用id将WM_命令msg发送到菜单项,即:PostMessage(m_HWNDSel,WM_命令,MAKEWPARAM(id,0),0);其中id是菜单项id。我可以通过获取引用菜单栏的PMenu的引用来获取这些id,然后我迭代了所有子菜单,并通过使用PMenu->GetMenuItemID()来获取菜单项id。我理解您的意思,但这并不是我真正想要做的。我没有尝试启用/禁用应用程序中的项目。我正在外部应用程序中调用所有这些方法。您肯定无法做到这一点!相反,您应该向MFC应用程序发送自定义消息,告诉它某些菜单项应该是灰色的。然后在MFC应用程序中,您将能够使用ON_UPDATE_命令_UI处理程序来启用/禁用它们。我无法想象MFC应用程序的另一种方式。如果我知道菜单项的id,有没有办法调用oncommand或Bn_clicked消息处理程序?我曾尝试使用sendmessage和postmessage传入主窗口的句柄,并使用BN_CLICKED和WM_命令,但这似乎不起作用。@Amre您无法从应用程序外部触发这些MFC事件,因为它们是由MFC框架生成的。我意识到我从未真正对此进行过更新。最后,我没有尝试启用灰显按钮或菜单项,只是在它们被禁用时调用它们。我这样做是为了这样的按钮:CWnd*selCWnd=//获取CWnd引用::SendMessage(selCWnd->m\u hWnd,WM\u LBUTTONDOWN,0,0);::SendMessage(selCWnd->m_hWnd,WM_LBUTTONUP,0,0);所以我发现我可以只发送一个左键向下,然后是一个左键向上的命令,这模仿了点击它,它工作了!