2011-05-30 23 views
19

के माध्यम से विंडो नंबर प्राप्त करना मैं एक ऐसे एप्लिकेशन पर काम कर रहा हूं जो स्क्रीन पर तीसरे पक्ष के अनुप्रयोगों की खिड़कियां चलाता है।ओएसएक्स एक्सेसिबिलिटी एपीआई

सभी वर्तमान में खुले खिड़कियों के एक सिंहावलोकन प्राप्त करने के लिए, मैं

CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID); 

का उपयोग यह हर खुली खिड़की को परिभाषित करने शब्दकोशों की एक सरणी देता है। यहाँ एक अनुकरणीय शब्दकोश लौटे है:

{ 
    kCGWindowAlpha = 1; 
    kCGWindowBounds =   { 
     Height = 442; 
     Width = 475; 
     X = 3123; 
     Y = "-118"; 
    }; 
    kCGWindowIsOnscreen = 1; 
    kCGWindowLayer = 0; 
    kCGWindowMemoryUsage = 907184; 
    kCGWindowName = Untitled; 
    kCGWindowNumber = 7328; 
    kCGWindowOwnerName = TextEdit; 
    kCGWindowOwnerPID = 20706; 
    kCGWindowSharingState = 1; 
    kCGWindowStoreType = 2; 
    kCGWindowWorkspace = 3; 
}, 

शब्दकोश अच्छा अन्यत्र इस्तेमाल जानकारी से भरा है, लेकिन किसी आसान तरीका उद्देश्य यह है कि खिड़कियों की स्थिति को संशोधित करने के लिए इस्तेमाल किया जा सकता है का अभाव है। विंडो को विंडो नंबर द्वारा स्पष्ट रूप से पहचाना जाता है।

मैं अब खिड़की के आवेदन के लिए एक पहुँच वस्तु बनाने के लिए पीआईडी ​​(kCGWindowOwnerPID) का उपयोग कर रहा:

AXUIElementRef app = AXUIElementCreateApplication(pid); 

सभी खिड़कियां आवेदन AXUIElementCopyAttributeValues ​​का उपयोग कर खोल दिया है की एक सूची को पुन: प्राप्त इसके बाद:

NSArray *result; 

AXUIElementCopyAttributeValues(
           (AXUIElementRef) app, 
           kAXWindowsAttribute, 
           0, 
           99999, 
           (CFArrayRef *) &result 
           ); 

यह काम करता है और AXUIElements की एक सरणी देता है। यह वह जगह है जहां मैं फंस गया हूं। किसी एक्सेसिबिलिटी ऑब्जेक्ट की विंडो संख्या पुनर्प्राप्त करने के लिए कोई एपीआई कॉल नहीं लगता है। वहाँ किसी भी तरह से या तो

क) का पता लगाएं तक पहुँच वस्तु की खिड़की संख्या (अंततः सरणी पर पुनरावृति और सही विंडो)

या

ख को खोजने के लिए) अन्यथा स्पष्ट रूप से एक खिड़की में वर्णित से मेल है AXUIElementCopyAttributeValues ​​द्वारा लौटाई गई एक्सेसिबिलिटी ऑब्जेक्ट्स पर CGWindowListCopyWindowInfo द्वारा वापस सरणी?

उत्तर

21

हमने इस कार्य के लिए एक समर्पित अभिगम्यता डेवलपर को भर्ती करना समाप्त कर दिया।

यह पता चला है कि अनियंत्रित एपीआई (हमारे मामले में कोई नहीं) का उपयोग किए बिना ऐसा करने का कोई तरीका नहीं है।

लूप अनुप्रयोग के सभी खुले विंडो के ऊपर:

सौभाग्य से, वहाँ एक व्यावहारिक समाधान नहीं है।

AXUIElementCopyAttributeValue(target, kAXPositionAttribute, CFTypeRef*)&posValue); 
AXUIElementCopyAttributeValue(target, kAXSizeAttribute, (CFTypeRef*)&sizeValue); 
AXUIElementCopyAttributeValue(target, kAXTitleAttribute, (CFTypeRef*)&titleValue); 

इसके बाद, वास्तविक CGPoint और CGSize मूल्यों में स्थिति और आकार में परिवर्तित:

AXValueGetValue(posValue, kAXValueCGPointType, &point); 
AXValueGetValue(sizeValue, kAXValueCGSizeType, &size); 

मूल्यों वस्तु द्वारा लौटाए के खिलाफ आकार, स्थिति और शीर्षक की तुलना उनकी स्थिति, आकार और शीर्षक प्राप्त करें CGWindowListCopyWindowInfo() में। यदि वे मेल खाते हैं, तो आप सुरक्षित रूप से यह उस विंडो को देख सकते हैं जिसे आप ढूंढ रहे थे और इसे काम करने के लिए पहले से ही खुली एक्सएआईआईएलमेंट (target) का उपयोग करें।

सभी खुली खिड़कियों के माध्यम से लूपिंग के लिए ओवरहेड ओएसएक्स पर नगण्य साबित होता है। एक ही समय में कितनी खिड़कियां खुली हैं इस पर एक बहुत कम टोपी है।

इसके अलावा, यह 100% सटीक नहीं है (यह संभव है कि 2 खिड़कियों की एक ही स्थिति, आकार और शीर्षक हो), हमें वास्तविक उपयोग में किसी भी स्थिति का सामना नहीं हुआ है जहां यह अब तक होता है।

+9

उन लोगों के लिए जो अनियंत्रित एपीआई का उपयोग कर सकते हैं, यह कैसे किया जाएगा? – Samuel

8

खिड़की के लिए दिए गए एएक्स ऑब्जेक्ट के लिए सीजी विंडो नंबर प्राप्त करने के लिए एक निजी कार्य है: _AXUIElementGetWindow। एसओ चर्चा में अधिक जानकारी Uniquely identify active window on OS X ऐसा लगता है कि 100% संभावना के साथ कार्य करने के लिए कोई सार्वजनिक एपीआई नहीं है। शीर्षक और फ्रेम (जैसा उपरोक्त उत्तर में वर्णित है) द्वारा विंडोज़ की पहचान 99.9% मामलों में काम करेगी।