0

我正在开发的应用程序需要能够否决菜单栏点击。有很多方法可以在单击菜单时收到通知(主要是NSMenu通知和NSMenu委托),但据我所知,它们都不会让您拒绝该操作。

我一直在考虑的解决方案是使用无边框透明窗口,并将其覆盖在菜单栏上。通过将窗口级别设置为足够高的值(NSStatusWindowLevel在本例中),它可以有效地定位和绘制在菜单栏上方,捕获原本会转到它的鼠标事件。这样,我就有了我想要的东西。

该解决方案的问题在于它还掩盖了状态栏的事件(右对齐的全局菜单项),我不需要或不想否决这些事件。要解决这个问题,我需要能够分辨状态栏的跨度或菜单栏的跨度,但我发现两者都没有明显的方法。NSApp.mainMenu.size返回主菜单的大小,就好像它在弹出菜单中一样,这显然不是我需要的。

有没有更好的方法来屏蔽菜单栏的事件,或者有没有办法找到它的宽度,不包括状态栏?

这可能听起来很肮脏,而且确实如此。我正在为旧平台的应用程序级模拟器做这件事,当用户单击菜单栏时,应用程序负责显示菜单,因此当这种情况发生时,它几乎可以做任何它想做的事情。

4

1 回答 1

1

菜单栏的宽度很简单:就是菜单栏屏幕的宽度。这包括所有应用程序的菜单:

菜单栏的屏幕截图,一直穿过屏幕,包括菜单。

那是来自Layers,所以我认为你不能在你的应用程序中做得更好。

所以,你将不得不减去状态栏。

使用 Quartz Window Services,这很容易。

首先,在主菜单窗口级别上创建一个无边框、不透明、背景清晰的空窗口,然后将其排序回来——即在真正的主菜单后面。

然后,获取窗口的窗口编号,并将其传递给函数CGWindowListCreate指定您希望所有窗口都位于另一个窗口之上。

为了获得额外的稳健性(只是为了确保不包含光标或其他内容),请在相反的方向执行相同的操作:在同一窗口级别创建第二个窗口,将其排序在前面(在菜单和状态栏的前面),并创建该窗口后面的窗口列表。

两个数组中的窗口是菜单栏和所有状态项。宽度与主菜单屏幕([NSScreen screens][0])相同的是菜单栏;将所有状态项的矩形合并在一起,并将菜单栏的矩形剪切到状态项矩形的原点。

请注意,所有这些都假设菜单栏和状态项以某种方式组织,这可能会在任何操作系统更新中发生变化。

于 2013-04-28T01:39:42.030 回答