2010-01-17 80 views
2

I ’ m嘗試觸發系統在單擊時所做的相同操作「在「中檢測顯示」顯示」系統首選項窗格。有沒有辦法做到這一點編程?我的目標是創建一個LaunchAgent,在登錄時執行此操作,以便在用戶弄亂它時重置顯示分辨率。以編程方式觸發「檢測顯示」。

回答

3

您將需要使用專用的CoreGraphics例程來獲取所有顯示(包括非活動顯示)的列表,然後請求重新掃描總線。試試這樣:

#include <IOKit/IOKitLib.h> 
#include <IOKit/IOTypes.h> 

CGDisplayErr CGSGetDisplayList(CGDisplayCount maxDisplays, 
            CGDirectDisplayID * onlineDspys, 
            CGDisplayCount * dspyCnt); 
static void DetectDisplays() 
{ 
CGDirectDisplayID displays[8]; 
    CGDisplayCount dspCount = 0; 

if (CGSGetDisplayList(8, displays, &dspCount) == noErr) 
{ 
    for(int i = 0; i < dspCount; i++) 
    { 
    io_service_t service = CGDisplayIOServicePort(displays[i]); 
    if (service) 
    IOServiceRequestProbe(service, kIOFBUserRequestProbe); 
    } 
} 
} 

並鏈接到ApplicationServices和IOKit。

+0

對不起我花了這麼長的迴應,我必須到達我可以測試的地方。它的工作,但我建議一些變化。首先,添加'#include '行,它允許您將'CGSGetDisplayList'(刪除其聲明)更改爲'CGGetOnlineDisplayList'並在Xcode中獲得代碼完成。 – 2010-01-20 15:25:09

+0

好,太好了。我沒有任何外部顯示器要測試,並且不確定是否可以使用CGGetOnlineDisplayList而不是CGSGetDisplayList。我知道CGSGetDisplayList返回所有顯示是否在線(它在我的MacBook Pro上返回4個顯示),而CGGetOnlineDisplayList只返回一個。 如果它與CGGetOnlineDisplayList一起使用,那麼最好避免使用私有API;) – 2010-01-20 17:39:53

4

由於CGDisplayIOServicePort呼叫已經在OS X 10.9小牛被棄用,它可能是更好的通過適當的匹配調用像這樣獲得IOFramebuffer的服務:

void triggerDetectDisplays() 
{ 
    // loop over all IOFramebuffer services 
    CFMutableDictionaryRef matchingDict = IOServiceMatching("IOFramebuffer"); 

    mach_port_t masterPort; 
    IOMasterPort(MACH_PORT_NULL, &masterPort); 
    io_iterator_t serviceIterator; 
    IOServiceGetMatchingServices(masterPort, matchingDict, &serviceIterator); 

    io_service_t obj = IOIteratorNext(serviceIterator); 
    while (obj) 
    { 
     kern_return_t kr = IOServiceRequestProbe(obj, 0); 
     obj = IOIteratorNext(serviceIterator); 
    } 
}