【发布时间】:2010-01-17 04:34:50
【问题描述】:
我正在尝试触发与系统在“显示”系统偏好设置窗格中单击“检测显示”时相同的操作。有没有办法以编程方式做到这一点?我的目标是创建一个在登录时执行此操作的 LaunchAgent,以重置显示分辨率,以防用户弄乱它。
【问题讨论】:
标签: objective-c macos resolution iokit
我正在尝试触发与系统在“显示”系统偏好设置窗格中单击“检测显示”时相同的操作。有没有办法以编程方式做到这一点?我的目标是创建一个在登录时执行此操作的 LaunchAgent,以重置显示分辨率,以防用户弄乱它。
【问题讨论】:
标签: objective-c macos resolution iokit
由于在 OS X 10.9 Mavericks 中已弃用 CGDisplayIOServicePort 调用,因此最好通过适当的匹配调用获取 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);
}
}
【讨论】:
您将需要使用私有 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。
【讨论】:
#include <ApplicationServices/ApplicationServices.h> 行,它可以让您将CGSGetDisplayList(删除其声明)更改为CGGetOnlineDisplayList 并在Xcode 中获得代码完成。