2010-01-17 55 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); 
    } 
}