当前位置: 首页 > 图文教程 > 开发语言 > VC++ > MFC 应用程序中的菜单提示信息
| C++ Q&A 专栏...
Joakim Fagerli 多美妙的想法。Figure 1 的效果胜过千言万语。他展示了一个我写的菜单提示信息小程序——MenuTips,它实现了任何 MFC 应用程序均可复用的菜单提示信息。具备菜单提示信息特性真的很棒,因为它又排除了一个状态栏存在的理由。即便没有状态栏,你依然能够知晓每一个命令是做什么用的。更重要的是,提示信息 显示在每个菜单项旁边很更显眼。在当今的巨型显示器面前,很多用户甚至根本就意识不到出现在状态条上的菜单提示信息——它离人们的视线太远了。![]() Figure 1 菜单提示信息 我在类 CMenuTipManager 里面实现了菜单提示。如果你想在自己的应用程序中使用菜单提示功能,只需要在主窗口类中添加一个 CMenuTipManager对象,然后在 创建框架的时候调用 Install 即可: //in CMainFrame::OnCreate(...)m_menuTipManager.Install(this);需要做的就这么多。现在当用户将鼠标停留在某个菜单项上面超过一秒钟,菜单提示信息管理器就会将对应的命令提示显示成一条提示信息,如 Figure 1 所示。CMenuTipManager 从你的程序的串表中获取提示信息,那也是 MFC 寻找状态栏提示信息的地方。 CMenuTipManager 使用了我闻名于世的子类化窗口类 CSubClassWnd 来捕获发往主窗口的 WM_MENUSELECT 消息。当用户在主菜单、系统菜单甚至上下文菜单中选中不同的的菜单项时,Windows 都会像 宿主窗口发送一个 WM_MENUSELECT 消息。如果你想提供反馈信息或者做其它自己你想做的事,此时便是最佳时机。MFC 的 CFrameWnd::OnMenuSelect 处理 WM_MENUSELECT 消息以便在状态栏上显示命令提示信息。CMenuTipManager 捕获同样的消息来显示菜单提示信息,Figure 2 展示了相关的代码。 总体上来说,CMenuTipManager 还是非常容易理解的,但是在 Windows 中还是有几点需要注意。首先是工具提示信息本身:有人曾指出过如何使用 Windows 标准的工具提示信息么?我在 2000 年 9 月和 2001 年 6 月的专栏中使用的是 CPopupText 类。CPopupText 非常简单,甚至一个知道如何敲分号的 VB 专家都能够实现它。 你只需要实例化一个 CPopupText 对象,调用 Create 和 SetWindowText,然后 CPopupText::ShowDelayed 就会在指定的时间里显示提示信息了。CPopupText::Cancel 负责删除提示信息。唯一的难点是使 CPopupText 看起来和标准的工具提示信息一样。为了实现这一目的,CPopupText 使用了菜单字体并且调用 GetSystemColor(COLOR_INFOBK) 得到包含工具提示颜色的系统颜色。 具体细节请参考本文附带的源代码。 对于 CMenuTipManager 而言,最复杂的部分是如何放置提示信息,以便恰好与高亮菜单项的右面对齐。这个问题基本思路是先得到菜单的位置,然后进行一系列的算术运算将所有的菜单项高度加起来,直到达到了被选中的菜单项。但是怎样才能得到菜单的位置呢?这可不是一个简单的问题。你也许猜到了,菜单本身也是一个窗口,但是没有 API 可以用来得到它的句柄,那怎么办呢?我曾经多次提到,在 Windows 中总会有解决办法,你决不会被困住的。 CMenuTipManager 有一个静态的辅助函数 CMenuTipManager::GetRunningMenuWnd,它返回当前正在运行的菜单窗口。鉴于这个函数的使用频率非常高,我将其设定为公有。但这个函数是如何工作的呢?你也许考虑调用 WindowFromPoint 来得到位于鼠标下面的窗口。多数情况下这种方法能够达到目的,但是不要忽略一种情况:用户可能会通过键盘而非鼠标来调用 |