【问题标题】:Setting the front most window using accessibility API使用辅助功能 API 设置最前面的窗口
【发布时间】:2010-01-22 01:14:49
【问题描述】:

我想将来自外部应用程序(例如 textedit)的某个窗口设置为最前面。

我可以使用 GetFrontProcess 成功获取对应用程序本身的引用,并检查它是否在最前面。如果不是,我可以使用 setFrontProcess 使其集中。

然后我可以使用辅助功能 API 检查该应用程序下的所有窗口。我正在检查某个窗口是否存在,如果存在,我将其与应用程序最前面的窗口进行比较:

//get the front window of textEditApp and store it in 'currentFrontWindow'
    AXUIElementCopyAttributeValue(textEditApp, kAXFocusedWindowAttribute, (CFTypeRef *)&currentFrontWindow);

如果我感兴趣的窗口不在最前面,我需要这样设置。我以为我可以使用 AXUIElement Set AttributeValue 来做到这一点,但我没有取得任何成功。以下是我尝试过的方法。

//set the front window of textEditApp to be desiredFrontWindow
AXUIElementSetAttributeValue(textEditApp, kAXFocusedUIElementAttribute, desiredFrontWindow);

我已检查该窗口是否存在,并且应用程序已成功“切换到”。但是为什么这行代码没有把指定的窗口拉到最前面呢?

谢谢。

【问题讨论】:

    标签: cocoa accessibility macos-carbon


    【解决方案1】:

    但是为什么这行代码没有把指定的窗口拉到最前面呢?

    因为您尝试设置只读属性。

    为了使窗口位于最前面,您需要设置窗口的适当属性。应用程序也是如此:要将应用程序置于最前面,您需要设置应用程序的相应属性。

    最前面窗口的 Cocoa/Mac OS X 名称是“主窗口”。 (例如,与该概念相关的NSApplication'sNSWindow's methods。)辅助功能使用相同的名称,因此要将单个窗口置于最前面,请将其kAXMainAttribute 的值设置为kCFBooleanTrue

    使应用程序最前面的方法类似:将其kAXFrontmostAttribute 的值设置为kCFBooleanTrue。您需要同时执行这两项操作来设置应用程序的最前面的窗口并使应用程序处于活动状态。

    据我所知,没有办法只将应用程序的单个窗口放在最前面并为其提供会话焦点。

    【讨论】:

    • 谢谢(再次)彼得 - 这很有魅力。至于应用程序,我一直在使用 setFrontProcess 而不是 kAXFrontMostAttribute - 这是一个坏主意吗?在浏览了应用程序和窗口之后,我有兴趣将某个 AXUIElementRef 带到前面(即给它键盘焦点)。我可以深入元素层以获取对它的引用,但是如何将其设置为焦点?元素是否有等效的 kAXMainAttribute ?也许我应该(还)发布另一个问题。
    【解决方案2】:

    我能够在应用程序I worked on 中完成此操作,方法是将应用程序置于最前面,然后将单个窗口置于最前面。

    首先将应用置于最前面:

    let currentPid = NSRunningApplication.currentApplication().processIdentifier
    if let pid = (the pid of the app in question) where pid != currentPid {
      NSRunningApplication(processIdentifier: pid)?.activateWithOptions(.ActivateIgnoringOtherApps)
    }
    

    然后将窗口发送到最前面:

    let window = (window AXUIElement)
    AXUIElementSetAttributeValue(window, NSAccessibilityMainAttribute, true)
    

    【讨论】:

    • 为我工作。谢谢。
    • 我认为在现代 Swift 中这看起来像 AXUIElementSetAttributeValue(window, kAXMainWindowAttribute as CFString, true as CFTypeRef)
    【解决方案3】:

    我最近发现,如果你不介意一些 Carbon,你可以使用 SetFrontProcessWithOptions 将一个窗口放在前面,如果你将 kSetFrontProcessFrontWindowOnly 作为第二个参数传递给它焦点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多