【问题标题】:Programmatically trigger "detect displays."以编程方式触发“检测显示”。
【发布时间】:2010-01-17 04:34:50
【问题描述】:

我正在尝试触发与系统在“显示”系统偏好设置窗格中单击“检测显示”时相同的操作。有没有办法以编程方式做到这一点?我的目标是创建一个在登录时执行此操作的 LaunchAgent,以重置显示分辨率,以防用户弄乱它。

【问题讨论】:

    标签: objective-c macos resolution iokit


    【解决方案1】:

    由于在 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);
        }
    }
    

    【讨论】:

      【解决方案2】:

      您将需要使用私有 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 &lt;ApplicationServices/ApplicationServices.h&gt; 行,它可以让您将CGSGetDisplayList(删除其声明)更改为CGGetOnlineDisplayList 并在Xcode 中获得代码完成。
      • 好的,太好了。我没有任何外部显示器可供测试,并且不确定是否可以使用 CGGetOnlineDisplayList 代替 CGSGetDisplayList。我知道 CGSGetDisplayList 会返回所有显示,无论它们是否在线(它在我的 MacBook Pro 上返回 4 个显示),而 CGGetOnlineDisplayList 只返回一个。如果它与 CGGetOnlineDisplayList 一起使用,那么最好避免使用私有 API ;)
      猜你喜欢
      • 2013-02-13
      • 2017-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-30
      相关资源
      最近更新 更多