2016-07-24 15 views
2

我試圖確定當前的前臺應用程序是否處於全屏模式(另一個應用程序)。我廣泛搜索以找到答案,並且發現了類似的Objective-C示例,我將我能夠迅速處理的最好的東西轉換爲我的案例(我在Objective-C中真的很糟糕)。獲取空指針異常嘗試從OSX上的swift獲取當前活動窗口的邊界

Objective-C example

的問題是,我得到一個例外,因爲bounds.memory爲零。在調試器中,它將邊界上的內存指針顯示爲0x0000000000000000。我相信這是因爲一些應用程序實際上沒有窗口,因此沒有任何提供。第二個理論是應用程序有多個窗口,但有些不可見(更有可能是因爲我通過pid檢查了for-in循環)。

所以問題是我將如何識別這些未提取的窗口並跳過它們?

P.S.

這是我在StackOverflow中的第一個問題,所以如果我的問題出現問題,請告訴我。我會嘗試相應地編輯我的問題。

// Check if fullscreen application is in foreground 
func appSwitched(notification: NSNotification) 
{ 
    let pid = NSWorkspace.sharedWorkspace().frontmostApplication!.processIdentifier 
    let bounds : CGRect! = windowBounds(pid) 
    print(bounds.height.description) 
    print(bounds.width.description) 
} 

// Get bounds of specified processID window 
func windowBounds(pid : Int32) -> CGRect 
{ 
    var bounds : UnsafeMutablePointer<CGRect>! = UnsafeMutablePointer<CGRect>() 

    let windowList : CFArrayRef = CGWindowListCopyWindowInfo(CGWindowListOption.OptionOnScreenOnly, CGWindowID())! 
    for window in windowList as NSArray{ 
     let id = window.objectForKey(kCGWindowOwnerPID) as! NSNumber! 
     if(id.intValue == pid){ 
      if((window.objectForKey(kCGWindowOwnerName) as! String) != "MyAppName") 
      { 
       let success : Bool! = CGRectMakeWithDictionaryRepresentation((window.objectForKey(kCGWindowBounds) as! CFDictionary!), bounds) 
       if((success) != nil) 
       { 
        return bounds.memory 
       } 
      } else { break } 
     } 
    } 
    return CGRect() 
} 

回答

1

一般來說,你的代碼使用了太多ImplicitlyUnwrappedOptionals - CGRect!UnsafeMutablePointer<CGRect>!NSNumber!Bool!,他們都不似乎是必需的。 但不是success : Bool!可能不是你的問題的原因,所以,我把其他人放在一邊。 (這些可引起其它問題,但這樣的情況下應等問題。)

CGRectMakeWithDictionaryRepresentation簽名是如下:(從生成的報頭兩者)

public func CGRectMakeWithDictionaryRepresentation(dict: CFDictionary?, _ rect: UnsafeMutablePointer<CGRect>) -> Bool 

  • 的返回值是Bool,而不是Bool?也不是Bool!,這意味着,當分配給Bool!變量時,變量始終爲非零。您不能用(success) != nil檢查功能是否成功。

  • 第二個參數的類型是UnsafeMutablePointer<CGRect>。當C函數API聲明UnsafeMutablePointer<T>時,您應聲明類型爲T的變量,並將其作爲inout參數(前綴&)傳遞。

所以,這行代碼的:

var bounds : UnsafeMutablePointer<CGRect>! = UnsafeMutablePointer<CGRect>() 

需要改變的東西,如:

var bounds: CGRect = CGRect() 

而且這一部分:

   let success : Bool! = CGRectMakeWithDictionaryRepresentation((window.objectForKey(kCGWindowBounds) as! CFDictionary!), bounds) 
       if((success) != nil) 
       { 
        return bounds.memory 
       } 

應像這樣:

   let success = CGRectMakeWithDictionaryRepresentation((window.objectForKey(kCGWindowBounds) as! CFDictionary?), &bounds) 
       if success { 
        return bounds 
       } 
+0

非常感謝!有用!我絕對需要用C函數做更多的功課。我還不能滿足你的答案,因爲我沒有足夠的分數。 –

相關問題