在不使用Cocoa的情况下创建OS X窗口

3

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

我尝试使用Carbon,但它除了给我一个有关未声明函数的警告外什么也没做。

我想我真正需要的是一种与Quartz Compositor进行接口的方法。

有没有办法让我看看“真正”的窗口创建代码?


4
我认为可可是“真正的窗口代码”(公开的),Carbon已被弃用。 - Justin Meiners
1
Justin Meiners 是正确的。Cocoa 是 OS X 的本地框架。它是“真正的代码”。NSWindow 与任何东西都不是无缝桥接的,也不会暴露任何核心<任何>对象,因为它是窗口的本地表示。像你研究过的包装器库一样,保持一个 NSWindow - Tommy
那么,Objective-C 是唯一的选择吗? - Justin
@Justin 是的,但你总是可以将其包装起来。 - Justin Meiners
2个回答

11
我没有太多详细信息可以提供给您,但我可能能够指出一个方向。
有一个下一级,即Quartz Window Services。这是NSWindow和Carbon Window Manager都基于的东西。
即使在公共API中,它偶尔也会露面。你可以询问任何窗口其窗口编号(以及在Carbon中同样),有了它,你就可以使用公共Quartz Window Services API中的任何内容。不过,除了截屏之外,你无法做太多事情。
如果您要使用Quartz创建窗口,它将(可能-我从未尝试过)是空白的。标题栏和背景是分别绘制的。
为了实现这一点,NSWindow有一个名为frame view的第二个视图ivar,它可能使用HITheme。(令人惊讶的是,其中相当大一部分是公开的——例如,有一个HIThemeDrawWindowFrame!而且它是公开的!)窗口管理器可能会做类似的事情。
[添加] 这里有一个使用HITheme绘制窗口的测试应用程序(在常规NSView内部)。

Screenshot of the real window containing the fake window.

作为您可以看到的,它并不完美:其中阴影半径和标题栏高度是硬编码的。但这是一个开始,并且已经是一个不错的演示。
快速总结:
  • HIThemeDrawWindowFrame 目前只绘制标题栏和红黄绿按钮。没有标题文本(它不接受字符串,因此无法绘制),也没有窗口背景、框架轮廓或阴影。
  • 要绘制窗口背景,请使用 HIThemeSetFill 将窗口背景画刷设置为上下文的填充颜色。然后,使用 HIThemeGetWindowShape 获取窗口结构区域的 HIShape(注意:尽管名称如此,但您需要从中释放形状),然后使用 HIShapeReplacePathInCGContext 将该形状设置为当前路径。然后像平常一样使用 CGContextFillPath
  • 如果您想在窗口后面绘制阴影,则需要将上述所有内容包装在 透明层 中。特别是如果不这样做,红黄绿按钮会在每个按钮后面获得自己的阴影,看起来非常奇怪。
  • 要绘制标题文本,请使用 HIThemeDrawTextBox。您应该能够使用 HIThemeGetWindowShape 获取标题文本形状,但是,从 Lion 开始,它返回一个空形状。

1
彼得 - 有时候你让我感到害怕 :) - Abizern

1
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);

你可以在未记录的好处项目中找到这些以及更多功能的文档(不确定整个私有API是否都在此处记录)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接