我是土石追踪器的作者,我得把几个NSWindow移到Hearthstone窗口。
我用CGWindowListCopyWindowInfo得到了Hearthstone的框架。然后,我必须移动我的窗户在一些位置相对于赫斯通。

红色箭头在对手牌上,绿色箭头在旋转按钮上,蓝色箭头在窗口左右。
我的实际屏幕设置如下:

这给了我以下的框架
// screen 1 : {x 0 y 0 w 1.440 h 900}
// screen 2 : {x 1.440 y -180 w 1.920 h 1.080}要将对手跟踪器(左帧)放置在最简单的位置(这是最简单的情况),我使用{x 0 y somepadding w 185 h hearthstoneHeight - somepadding}并得到正确的帧。
func relativeFrame(frame: NSRect) -> NSRect {
var relative = frame
relative.origin.x = NSMinX(hearthstoneFrame) + NSMinX(frame)
relative.origin.y = NSMinY(hearthstoneFrame) + NSMinY(frame)
return relative
}右跟踪器使用{x hearthstoneWidth - trackerWidth, ...}放置。
对于其他覆盖,我使用我的当前(Hearthstone)分辨率来放置它们,它们使用一个简单的数学计算它们。
x = x / 1404.0 * NSWidth(hearthstoneFrame)
y = y / 840.0 * NSHeight(hearthstoneFrame)这个效果很好。除非我用我的第二个屏幕。在这种情况下,框架似乎是正确的,但窗口的位置不是很好。
下面是使用{x 0 y 0 w hearthstoneWidth h hearthsoneHeight }调试窗口的屏幕截图。如果我比较赫特斯通的框架和我的覆盖层,它们是相同的。

完整的函数如下(我在一个“静态类”中,我只显示了相关代码)。我想我在计算中遗漏了什么,但我找不到什么。
class frameRelative {
static var hearthstoneFrame = NSZeroRect
static func findHearthstoneFrame() {
let options = CGWindowListOption(arrayLiteral: .ExcludeDesktopElements)
let windowListInfo = CGWindowListCopyWindowInfo(options, CGWindowID(0))
if let info = (windowListInfo as NSArray? as? [[String: AnyObject]])?
.filter({
!$0.filter({ $0.0 == "kCGWindowName" && $0.1 as? String == "Hearthstone" }).isEmpty
})
.first {
var rect = NSRect()
let bounds = info["kCGWindowBounds"] as! CFDictionary
CGRectMakeWithDictionaryRepresentation(bounds, &rect)
rect.size.height -= titleBarHeight // remove the 22px from the title
hearthstoneFrame = rect
}
}
static func frameRelative(frame: NSRect, _ isRelative: Bool = false) -> NSRect {
var relative = frame
var pointX = NSMinX(relative)
var pointY = NSMinY(relative)
if isRelative {
pointX = pointX / 1404.0 * NSWidth(hearthstoneFrame)
pointY = pointY / 840.0 * NSHeight(hearthstoneFrame)
}
let x: CGFloat = NSMinX(hearthstoneFrame) + pointX
let y = NSMinY(hearthstoneFrame) + pointY
relative.origin = NSMakePoint(x, y)
return relative
}
}
// somewhere here
let frame = NSMakeRect(0, 0, hearthstoneWidth, hearthstoneHeight)
let relativeFrame = SizeHelper.frameRelative(frame)
myWindow.setFrame(relativeFrame, display: true)(如有任何帮助,将不胜感激:)
发布于 2016-06-18 20:03:16
我最终解决了这个问题所以我决定贴出答案来关闭这条线..。也许有一天某人也会面临同样的问题。
解决方法是用Hearthstone窗口的max y从第一个屏幕上减去max y。
findHearthstoneFrame的最终代码是
static func findHearthstoneFrame() {
let options = CGWindowListOption(arrayLiteral: .ExcludeDesktopElements)
let windowListInfo = CGWindowListCopyWindowInfo(options, CGWindowID(0))
if let info = (windowListInfo as NSArray? as? [[String: AnyObject]])?.filter({
!$0.filter({ $0.0 == "kCGWindowName"
&& $0.1 as? String == "Hearthstone" }).isEmpty
}).first {
if let id = info["kCGWindowNumber"] as? Int {
self.windowId = CGWindowID(id)
}
var rect = NSRect()
let bounds = info["kCGWindowBounds"] as! CFDictionary
CGRectMakeWithDictionaryRepresentation(bounds, &rect)
if let screen = NSScreen.screens()?.first {
rect.origin.y = NSMaxY(screen.frame) - NSMaxY(rect)
}
self._frame = rect
}
}而frameRelative是
static let BaseWidth: CGFloat = 1440.0
static let BaseHeight: CGFloat = 922.0
var scaleX: CGFloat {
return NSWidth(_frame) / SizeHelper.BaseWidth
}
var scaleY: CGFloat {
// 22 is the height of the title bar
return (NSHeight(_frame) - 22) / SizeHelper.BaseHeight
}
func frameRelative(frame: NSRect, relative: Bool = true) -> NSRect {
var pointX = NSMinX(frame)
var pointY = NSMinY(frame)
let width = NSWidth(frame)
let height = NSHeight(frame)
if relative {
pointX = pointX * scaleX
pointY = pointY * scaleY
}
let x: CGFloat = NSMinX(self.frame) + pointX
let y: CGFloat = NSMinY(self.frame) + pointY
let relativeFrame = NSRect(x: x, y: y, width: width, height: height)
return relativeFrame
}https://stackoverflow.com/questions/36766266
复制相似问题