如何使用MFC禁用和灰化顶级菜单项

5

我有一个对话框应用程序,想要在对话框顶部有可点击的菜单项。这些项目不显示下拉菜单,而是实际运行相关的命令。

我通过在对话框属性中设置Popup=False并分配消息ID来实现此操作,但我的问题是当没有意义让该项可点击时(取决于存储在对话框中的内部状态)无法正确地禁用该项。

我已经发现如何禁用任何弹出父菜单项,具体信息请查看 http://www.microsoft.com/msj/0299/c/c0299.aspx ,但这并不完全符合我的需求。

我还发现了如何从msdn知识库文章KB242577将菜单命令路由到对话框中。

这对子菜单项很有效,但对于顶级菜单则不行。

我目前正在使用以下函数进行禁用操作。

void CYourDlg::EnableMenuItem(UINT nCommand, BOOL bEnable)
{
   CMenu* pMenu = GetMenu();
   pMenu->EnableMenuItem(nCommand, bEnable ? 0 : MF_DISABLED | MF_GRAYED);
}

这部分功能有一些问题,如果你从应用程序中切换到其他窗口,它会显示为禁用状态,否则不会。

有没有一种方法可以通过编程方式使该区域无效?

我认为涉及到一个非客户端区域消息。

2个回答

6

我没有尝试过,但在常规窗口(非对话框)中,CWnd::DrawMenuBar 应该可以实现你想要的功能。它也可能适用于基于对话框的应用程序。

void CYourDlg::EnableMenuItem(UINT nCommand, BOOL bEnable)
{
   CMenu* pMenu = GetMenu();
   pMenu->EnableMenuItem(nCommand, bEnable ? 0 : MF_DISABLED | MF_GRAYED);
   DrawMenuBar();
}

1
我认为你的解决方案是唯一的,因为ON_UPDATE_COMMAND_UI处理程序只有在某人点击菜单时才会被激活。对于普通菜单,可能需要禁用的任何项目都只会在用户单击顶级菜单时出现,当然这会触发OnInitMenuPopup,进而触发ON_UPDATE_COMMAND_UI处理程序。 - Peter Nimmo
根据微软的说法,如果在Windows创建窗口后更改了菜单栏,请调用此函数以绘制更改后的菜单栏。 - BostonLogan

1

我认为你应该为菜单ID添加一个ON_UPDATE处理程序。这将确保在需要时启用/禁用菜单。


1
我按照KB242577的指示进行了操作,以便可以使用ON_UPDATE_COMMAND_UI,但正如我之前所说,“这对于子菜单项目来说运行良好,但对于顶级菜单则不然。”它不会在点击相关项之前更新视觉显示。 - Peter Nimmo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接