65.9K
CodeProject 正在变化。 阅读更多。
Home

可分离菜单

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.50/5 (8投票s)

2003年12月1日

CPOL

3分钟阅读

viewsIcon

96162

downloadIcon

2906

了解如何在您的程序中实现可分离菜单

引言

微软在一些 Office 版本中引入了一个新功能:可撕下并用作工具栏的弹出菜单。对于用户来说,这是一种很好的方式,可以将重要功能直接放在应用程序工作区上,而无需每次都打开菜单。

尝试实现此功能导致了很多问题。最容易的是绘制菜单,使其看起来可以撕下。接下来是如何获取鼠标移动和按钮按下,这让我很长时间停止了这项工作。在 2003 年 11 月的 MSDN 杂志上,Paul DiLascia 写了一些代码来显示菜单提示。有了这段代码,实现它就很容易了。

幕后

新的类 CMenuTearOffManager 具有可撕菜单所需的所有功能。它基本上将弹出菜单映射到工具栏并处理 GUI 部分。使用 Paul DiLascia 的 CSubclassWnd 类,CMenuTearOffManager 对每个新的弹出菜单做出反应,并检查(和修改)它,以防它有可撕项目。然后计算并绘制“标题”。让我们看看它内部是如何工作的:首先,每当打开一个新的弹出菜单(WM_INITMENUPOPUP)时,它会遍历所有项目并将它们与将菜单项分配给工具栏的内部映射进行比较。如果找到该项目,则将其转换为 ownerdrawn 项目。对于该项目,WM_MEASUREITEM 计算“标题”的高度,WM_DRAWITEM 绘制标题。这就是棘手的部分:在绘制过程中,会创建一个新窗口,该窗口位于菜单项之上,以便可以捕获鼠标移动;每次选择不同的菜单项时,该窗口都会变得不可见。新窗口未处于活动状态(这将导致菜单关闭),因此鼠标移动由 WM_NCHITTEST 捕获。移动鼠标并按下鼠标左键会关闭窗口并将消息转发到工具栏控件 - 就这样!

Using the Code

首先,将 CMenuTearOffManager 类添加到 CMainFrame。在您的 CMainFrame::OnCreate() 中,使用如下代码添加所有可撕工具栏

if (!m_wndToolBarTearOff1.CreateEx(this, TBSTYLE_FLAT, WS_CHILD 
    |WS_VISIBLE| CBRS_TOP
    | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
    !m_wndToolBarTearOff1.LoadToolBar(IDR_TEAROFF1))
{
  TRACE0("Unable to create toolbar 1\n");
  return -1;
}
m_wndToolBarTearOff1.EnableDocking(CBRS_ALIGN_ANY);
ShowControlBar(&m_wndToolBarTearOff1, FALSE, FALSE);

(代码的最后一行导致工具栏最初不可见。)

然后,在您希望用作可撕菜单的每个弹出的顶部插入一个新菜单项(这里:ID_TEAROFFDEMO_TEAROFF2)。另外,为弹出菜单插入显示的新的工具栏。无需在工具栏上使用相同的命令。

创建所有工具栏后,使用这些行来安装该类并将其连接到菜单项

m_menuTOManager.Install(this, this);
m_menuTOManager.AddTearOff(ID_TEAROFFDEMO_TEAROFF1, &m_wndToolBarTearOff1);
m_menuTOManager.AddTearOff(ID_TEAROFFDEMO_TEAROFF2, &m_wndToolBarTearOff2);
...

这会将“virtual”菜单项 ID_TEAROFFDEMO_TEAROFF2 连接到工具栏 m_wndToolBarTearOff2。其余的都是自动完成的。

请参阅示例了解如何使用它。所有注释都用英文编写,只有资源是德语。

限制

此类与您从例如 Microsoft Office 和其他一些限制中了解到的“原始”实现有一些差异

  • 可撕标题的不同绘制
  • 撕下工具栏后菜单立即关闭
  • Office 产品允许在拖动期间再次停靠弹出窗口
  • (尚未)不适用于上下文菜单
  • 未对 ownerdrawn 菜单进行测试,但它应该有效

致谢

Paul DiLascia 感谢他的子类和菜单提示管理器,这极大地帮助了该类的开发!

历史

  • 2003 年 11 月 30 日:初始发布

许可证

欢迎在您的任何项目中使用此类或修改它!请在源代码中保留我的署名。

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.