在没有 Cocoa 的情况下创建 OS X 窗口

Posted

技术标签:

【中文标题】在没有 Cocoa 的情况下创建 OS X 窗口【英文标题】:Create OS X window without Cocoa 【发布时间】:2013-08-28 23:19:19 【问题描述】:

出于好奇,我开始尝试弄清楚 Cocoa 是如何创建窗口的。我发现的所有库都以 Cocoa 为核心,我似乎在网上找不到任何东西。

我尝试使用 Carbon,但它什么也没做,只是给我一个关于未声明函数的警告。

我想我真正想要的是一种与 Quartz Compositor 交互的方式。

有什么方法可以让我看看真正的窗口创建代码吗?

【问题讨论】:

我认为可可是“真正的窗口代码”(这是公开的),不推荐使用碳。 贾斯汀迈纳斯是正确的。 Cocoa 是 OS X 的原生框架。它是“真正的代码”。 NSWindow 不是免费桥接任何东西,不公开任何核心 对象等,因为它是窗口的本机表示。像您研究过的那些包装器库保留NSWindow 那么,Objective-C 是唯一的出路吗? @Justin 是的,但你可以随时包装它。 【参考方案1】:

我没有太多细节可以告诉你,但我可以为你指明一个方向。

还有一层,即 Quartz Window Services。这就是 NSWindow 和 Carbon 的窗口管理器的基础。

它偶尔会偷看,即使在公共 API 中也是如此。你可以ask any window for its window number(和likewise in Carbon),这样你就可以使用the public Quartz Window Services API中的任何东西。但是,这并不能让您走得太远:除了截屏之外,您无能为力。

但是,如果您要使用 Quartz 创建一个窗口,它会(可能——我从未尝试过)是空白的。标题栏和背景是分开绘制的。

为此,NSWindow 为称为框架视图的视图提供了第二个视图 ivar,它可能使用了 HITheme。 (令人惊讶的数量甚至是公开的——例如,HIThemeDrawWindowFrame而且它是公开的!)窗口管理器可能会做类似的事情。

[已添加]Here's a test app that draws a window using HITheme(在常规 NSView 内)。

如您所见,它并不完美:阴影半径和标题栏高度是硬编码的。但这是一个开始,也是一个体面的示范。

快速总结:

HIThemeDrawWindowFrame 目前只绘制标题栏和红绿灯。没有标题文本(它不需要字符串,因此无法绘制),也没有窗口背景、框架轮廓或阴影。 要绘制窗口背景,请使用HIThemeSetFill 将窗口背景画笔设置为上下文的填充颜色。然后,使用HIThemeGetWindowShape 获取窗口结构区域的HIShape(注意:尽管有名称,但您需要CFRelease 从中获得的形状),然后使用HIShapeReplacePathInCGContext 将该形状设置为上下文的当前路径。然后,CGContextFillPath,照常。 如果你想在你的窗户后面有一个阴影,你需要把上面所有的东西都包裹在一个transparency layer中。特别是,如果您不这样做,红绿灯会在每个按钮后面都有自己的阴影,这看起来很奇怪。 要绘制标题文本,请使用HIThemeDrawTextBox。您应该能够使用HIThemeGetWindowShape 获取标题文本形状,但是对于 Lion,它返回一个空形状。

【讨论】:

彼得 - 你有时会吓到我 :)【参考方案2】:

Quartz Window Services API 也有一个私有部分,它定义了以下函数:

// Creating Windows
extern CGError CGSNewWindowWithOpaqueShape(CGSConnection cid, int always2, float x, float y, CGSRegionRef shape, CGSRegionRef opaqueShape, int unknown1, void *unknownPtr, int always32, CGSWindowID *outWID);
extern CGError CGSReleaseWindow(CGSConnection cid, CGSWindowID wid);
extern CGContextRef CGWindowContextCreate(CGSConnection cid, CGSWindowID wid, void *unknown);

您可以在 undocumented goodness project 找到这些以及更多记录的函数(不确定是否在此处记录了整个私有 API)。

【讨论】:

以上是关于在没有 Cocoa 的情况下创建 OS X 窗口的主要内容,如果未能解决你的问题,请参考以下文章

Cocoa 应用程序中的 OpenCV(OS X 应用程序)

在 OS X 中打开并创建窗口

使用Cocoa以编程方式创建复选框

在 Mac OS X 上列出钥匙串中的条目

OS X Cocoa:基于 NSDocument 的应用程序未保存

在 Xcode 5.0.1 中创建 OS X Cocoa App Web 视图