【问题标题】:Mac style menus on Windows, system wideWindows 上的 Mac 风格菜单,系统范围
【发布时间】:2010-03-05 11:56:41
【问题描述】:

我是 Mac 用户和 Windows 用户(曾经我曾经是 Amiga 用户)。我更喜欢 Mac(和 Amiga)采用(/took)的屏幕顶部菜单栏方法,我想为 Windows 编写一些可以提供此功能(并且可以工作)的东西与现有的应用程序)。

我知道这有点雄心勃勃,尤其是因为它只是一个从头开始的项目类型,而且由于家庭不断壮大,我的空闲时间几乎为零。几年前我研究了一下,得出的结论是这非常困难,但那是在 StackOverflow 之前;)

我认为我需要做这样的事情才能达到预期的结果:

  • 创建将成为位于所有其他窗口顶部的自定义菜单栏的应用程序。自定义菜单必须提供所有功能来替换标准 Win32 窗口内菜单。没关系,它只是一个行为类似于菜单栏的应用程序。

  • 它将不断枚举窗口以查找正在创建/销毁的窗口。它将枚举子窗口集合以查找菜单栏。

  • 它将构建一个菜单来表示窗口中的菜单选项。

  • 它将隐藏窗口中的菜单栏并将所有直接子窗口向上移动相应的像素量。它也会缩短窗口高度。

  • 它将捕获应用程序发送到其菜单的所有消息,以相应地调整自定义菜单。

  • 它会不断地轮询当前活动的窗口,因此它可以在必要时切换菜单。

  • 当点击菜单时,它会使用真正的菜单子控件的 hwnd 向窗口发布消息。

就是这样!容易吧?不,可能不会。

我非常感谢 Win32 专家提供的关于从哪里开始、想法、陷阱以及关于是否可能的想法的任何建议。我白天不是 Win32 C++ 程序员,但我已经做了一些工作,我不介意通过 MSDN 平台 SDK 文档挖掘我的方式......

(我还有另一个想法,在多显示器设置中为每个屏幕创建一个任务栏并显示桌面的活动窗口——但我认为我可以在托管代码中做到这一点,并为自己节省大量工作)。

【问题讨论】:

  • 还有很多其他可行的事情,为什么您要尝试并浪费时间尝试这样做,由于 MDI 应用程序的设计方式,这几乎是不可能的。 Windows 就是不支持这种东西。

标签: windows user-interface winapi desktop


【解决方案1】:

顶部的 Mac 菜单和 Windows 方法之间的真正区别不仅仅在于菜单:- 它是如何使用菜单来破解打开的 MDI 应用程序的。

在 Windows 中,MDI 应用程序(例如 dev studio 和 office)将其所有文档窗口都托管在应用程序框架窗口中。在 Mac 上,没有针对每个应用程序的框架窗口,所有文档窗口都与来自其他应用程序的所有其他文档窗口共享桌面。

缺乏对传统 MDI 应用程序进行深度改造以将其文档窗口显示并放到桌面上的能力,无论多么崇高,获得桌面菜单的尝试似乎都注定是一种没有实际用途或实用性的新奇事物.

考虑到所有因素,我对 Mac 和 Windows(以及 Linux)上的窗口管理器的当前状态感到相当沮丧:浏览器中的选项卡式分页之类的东西实际上是应用程序开发人员的绝望行为,他们没有得到这些东西作为标准窗口管理器的一部分 - 我相信标签确实属于其中。为什么 notepad++ 应该有一组选项卡、chrome、firefox 和 Internet Explorer(是的,我知道运行所有 4 个),以及开发工作室的停靠视图、各种绘图程序。

它只是对现代多文档界面应该是什么样子的不同解释的混乱。

【讨论】:

  • ...您对现代 MDI 界面的想法是...?
  • 带有可停靠标签的东西。像 chrome,但由窗口管理器管理。它似乎是每个人都在尝试做的。
  • 我不明白为什么 MDI 应用程序不适合将其菜单重新定位到屏幕顶部,但也许我遗漏了一些东西——例如,如果您查看 Visual Studio ,您会注意到一次只能看到一个菜单,并且它位于 MDI 容器窗口的顶部。为什么不将它放在屏幕顶部而不是窗口顶部?我想要这样做的原因只是为了让鼠标更容易点击菜单栏,而不是改变 MDI/SDI 应用程序的工作方式。
【解决方案2】:

典型窗口上的菜单栏是窗口非客户区的一部分。当 WndProc 收到 WM_NCPAINT 消息并将其传递给 DefWindowProc 时绘制它,这是 User32.dll 的一部分 - 核心窗口管理器代码。

在同一消息中绘制的其他内容?标题、窗口边框、最小/最大/关闭框。这些都是在处理单个消息时绘制的。因此,为了隐藏应用程序的菜单,您必须接管此消息的处理,这意味着 更改 user32.dll 的行为。隐藏菜单意味着您将负责绘制所有的非客户区。

所有这些元素的外观 - 标题、边框等都会随着 Windows 的每个主要版本而变化。所以你也必须追逐它。

这只是这个想法的十几个无法克服的问题中的一个。甚至微软也可能无法做到这一点,他们可以访问 user32.dll 的源代码!

在屏幕顶部为每个应用程序回显菜单将是一件容易得多的工作,即使这也是一项几乎不可能完成的工作。当菜单弹出时,与应用程序有很多交互,在此期间可以(并且经常)更改菜单。 非常应用程序在菜单项被绘制之前更改它们的状态是很常见的。因此,您不仅要复制菜单的外观,还要复制它们与应用程序的整个消息流交互。

你要做的是一次完成十几个不可能的工作,如果你尝试一下,你可能会学到很多东西,但你永远不会让它发挥作用。

【讨论】:

  • 这是一个很好的答案,谢谢。我将调查 WM_NCPAINT,因为我很想知道那里发生了什么,但正如你所说,我无法重绘所有非客户区,这确实使我的任务有些不可能。感谢您的反馈。
猜你喜欢
  • 2021-04-24
  • 2016-12-19
  • 1970-01-01
  • 2015-12-28
  • 2012-10-21
  • 1970-01-01
  • 1970-01-01
  • 2022-10-24
  • 2016-04-24
相关资源
最近更新 更多