设置和显示显示分辨率-源码

发布于 2022-10-15 04:05:13 字数 27234 浏览 18 评论 0

设置和显示显示分辨率-源码

下面是一个设置和显示当前系统显示设备和分辨率的源码
如果有兴趣,大家给测试一下各自的环境下,它工作的情况。

几个概念:
Display: 每个当前连接到系统中的显示器
Main Display: 当前的主显示设备
Mode: 是每个显示设备和系统之间连接后,系统自动生成的管理它的一个内存对象,分辨率是其中的一个部分,每个显示设备可能有好多mode,这些mode组成一个列表。

编译步骤
   首先要安装了xcode开发环境,把下面的源码复制到一个文本编辑器中,比如TextEdit,然后使用文本方式保存,比如该源码的文件命是screenresolution.m,保存在你的Desktop上。再编译:在Terminal里面输入命令:
cd ~/Desktop
c++ screenresolution.m -framework ApplicationServices -o screenresolution -arch i386

这样就在你的Desktop上生成了一个交screenresolution的程序.

具体使用,在Termianl里面运行:

  • 获得帮助:~/Desktop/screenresolution -h
  • 获得当前显示器的个数:~/Desktop/screenresolution -a
  • 当前主显示器的分辨率:~/Desktop/screenresolution
  • 获得当前第2个显示器的分辨率:~/Desktop/screenresolution 2
  • 获得主显示器支持的分辨率列表:~/Desktop/screenresolution -l
  • 获得第2个显示器支持的分辨率列表:~/Desktop/screenresolution -l 2
  • 设置当前主显示器的分辨率为800x600:~/Desktop/screenresolution -s 800 600
  • 设置第2个显示器的分辨率为800x600:~/Desktop/screenresolution -s 2 800 600

注意:
这个版本是为OS X 10.6以上版本做的. 在10.6系统上编译成功并运行成功;没有在10.5上编译过;10.6编译成功的执行命令,也没有在10.5系统上运行过-应该是无法运行的-谁有条件给测试一下。因为10.6把好多10.5里面的底层函数都改了。

已知的:

  • 没有考虑两个显示器mirro的状态
  • 设置分辨率尽量使用系统列出的所支持的分辨率,否则设置可能不成功。

其它的:

源代码

  1.     /*
  2.      * screenresolution.m
  3.      *  
  4.      * Description:
  5.      *    It set/get current Online display resolutions.
  6.      *
  7.      * Author:
  8.      *    Tony Liu, Copy Right Tony Liu 2011,  All rights reserved.
  9.      *
  10.      * Version History:
  11.      *    2011-06-01: add -a option.
  12.      *    2011-06-08: Display adding flags and not display duplicate modes.
  13.      *    2011-06-09: Adding set the best fit resolution function.
  14.      *
  15.      * COMPILE:
  16.      *    c++ screenresolution.m -framework ApplicationServices -o screenresolution -arch i386
  17.      *
  18.      */  
  19.     #include <ApplicationServices/ApplicationServices.h>  
  20.     struct sLIST {  
  21.         double width, height;  
  22.         CGDisplayModeRef mode;  
  23.     };  
  24.     typedef int (*compfn)(const void*, const void*);  
  25.     void ListDisplays(uint32_t displayTotal);  
  26.     void ListDisplayAllMode (CGDirectDisplayID displayID, int index);  
  27.     void PrintUsage(const char *argv[]);  
  28.     void PrintModeParms (double width, double height, double depth, double freq, int flag);  
  29.     int GetModeParms (CGDisplayModeRef mode, double *width, double *height, double *depth, double *freq, int *flag);  
  30.     int GetDisplayParms(CGDirectDisplayID disp, double *width, double *height, double *depth, double *freq, int *flag);  
  31.     bool GetBestDisplayMod(CGDirectDisplayID display, double dwidth, double dheight);  
  32.     int modecompare(struct sLIST *elem1, struct sLIST *elem2);  
  33.     uint32_t maxDisplays = 20;  
  34.     CGDirectDisplayID onlineDisplayIDs[20];  
  35.     uint32_t displayTotal;  
  36.     char *sysFlags[]={"Unknown","Interlaced,", "Multi-Display,", "Not preset,", "Stretched,"};  
  37.     char flagString[200];  
  38.       
  39.     int main (int argc, const char * argv[])  
  40.     {  
  41.         double width, height, depth, freq;  
  42.         int flag;  
  43.         int displayNum;  
  44.         CGDirectDisplayID theDisplay;  
  45.          
  46.         // 1. Getting system info.  
  47.         if (CGGetOnlineDisplayList (maxDisplays, onlineDisplayIDs, &displayTotal) != kCGErrorSuccess) {  
  48.             printf("Error on getting online display List.");  
  49.             return -1;  
  50.         }  
  51.          
  52.         if (argc == 1) {  
  53.             CGRect screenFrame = CGDisplayBounds(kCGDirectMainDisplay);  
  54.             CGSize screenSize  = screenFrame.size;  
  55.             printf("%.0f %.0f\n", screenSize.width, screenSize.height);  
  56.             return 0;  
  57.         }  
  58.          
  59.         if (! strcmp(argv[1],"-l")) {  
  60.             if (argc == 2) {  
  61.                 ListDisplays(displayTotal);  
  62.                 return 0;  
  63.             }  
  64.             else if (argc == 3)  {  
  65.                 displayNum = atoi(argv[2]);  
  66.                 if (displayNum <= displayTotal && displayNum > 0) {  
  67.                     ListDisplayAllMode (onlineDisplayIDs[displayNum-1], 0);  
  68.                 }  
  69.             }  
  70.             return 0;  
  71.         }  
  72.          
  73.         if (! strcmp(argv[1],"-a")) {  
  74.             printf("Total online displays: %d\n", displayTotal);  
  75.             return 0;  
  76.         }  
  77.          
  78.         if ((! strcmp(argv[1],"-?")) || (! strcmp(argv[1],"-h"))) {  
  79.             PrintUsage(argv);  
  80.             return 0;  
  81.         }  
  82.         if (! strcmp(argv[1],"-s")) {  
  83.             if (argc == 4) {  
  84.                 displayNum = 1; width = atoi(argv[2]); height = atoi(argv[3]);  
  85.             }  
  86.             else if (argc == 5) {  
  87.                 displayNum = atoi(argv[2]); width = atoi(argv[3]); height = atoi(argv[4]);  
  88.             }  
  89.             if (displayNum <= displayTotal)  
  90.                 flag = GetBestDisplayMod(displayNum-1, width, height);  
  91.             return flag;  
  92.         }  
  93.         displayNum = atoi(argv[1]);  
  94.         if (displayNum <= displayTotal) {  
  95.             GetDisplayParms(onlineDisplayIDs[displayNum-1], &width, &height, &depth, &freq, &flag);  
  96.             PrintModeParms (width, height, depth, freq, flag);  
  97.             return 0;  
  98.         }  
  99.         else {  
  100.             fprintf(stderr, "ERROR: display number out of bounds; displays on this mac: %d.\n", displayTotal);  
  101.             return -1;  
  102.         }  
  103.         return 0;  
  104.     }  
  105.       
  106.     void ListDisplays(uint32_t displayTotal)  
  107.     {  
  108.         uint32_t i;  
  109.         CGDisplayModeRef mode;  
  110.         double width, height, depth, freq;  
  111.         int flag;  
  112.          
  113.         // CGDirectDisplayID mainDisplay = CGMainDisplayID();  
  114.         printf("Total Online Displays: %d\n", displayTotal);  
  115.         for (i = 0 ; i < displayTotal ;  i++ ) {  
  116.             printf ("  Display %d (id %d): ", i+1, onlineDisplayIDs[i]);  
  117.             GetDisplayParms(onlineDisplayIDs[i], &width, &height, &depth, &freq, &flag);  
  118.             if ( i = 0 )    printf(" (main) ");  
  119.             PrintModeParms (width, height, depth, freq, flag);  
  120.         }  
  121.     }  
  122.     void ListDisplayAllMode (CGDirectDisplayID displayID, int iNum)  
  123.     {  
  124.         CFArrayRef modeList;  
  125.         CGDisplayModeRef mode;  
  126.         CFIndex index, count;  
  127.         double width, height, depth, freq;  
  128.         int flag;  
  129.         double width1, height1, depth1, freq1;  
  130.         int flag1;  
  131.       
  132.         modeList = CGDisplayCopyAllDisplayModes (displayID, NULL);  
  133.         if (modeList == NULL)   return;  
  134.         count = CFArrayGetCount (modeList);  
  135.         width1=0; height1=0; depth1=0; freq1=0; flag1=0;  
  136.         if (iNum <= 0) {  
  137.             for (index = 0; index < count; index++)  
  138.             {  
  139.                 mode = (CGDisplayModeRef)CFArrayGetValueAtIndex (modeList, index);  
  140.                 GetModeParms(mode, &width, &height, &depth, &freq, &flag);  
  141.                 PrintModeParms (width, height, depth, freq, flag);  
  142.             }  
  143.         }  
  144.         else if (iNum <= count) {  
  145.             mode = (CGDisplayModeRef)CFArrayGetValueAtIndex (modeList, iNum-1);  
  146.             GetModeParms(mode, &width, &height, &depth, &freq, &flag);  
  147.             PrintModeParms (width, height, depth, freq, flag);  
  148.         }  
  149.         CFRelease(modeList);  
  150.     }  
  151.     void PrintModeParms (double width, double height, double depth, double freq, int flag)  
  152.     {  
  153.         printf ("%ld x %ld x %ld @ %ld Hz, <%d>\n", (long int)width, (long int)height, (long int)depth, (long int)freq, flag);  
  154.     }  
  155.     int GetDisplayParms(CGDirectDisplayID disp, double *width, double *height, double *depth, double *freq, int *flag)  
  156.     {  
  157.         int iReturn=0;  
  158.         CGDisplayModeRef Mode = CGDisplayCopyDisplayMode(disp);  
  159.         iReturn = GetModeParms (Mode, width, height, depth, freq, flag);  
  160.         CGDisplayModeRelease (Mode);  
  161.         return iReturn;  
  162.     }  
  163.     int GetModeParms (CGDisplayModeRef Mode, double *width, double *height, double *depth, double *freq, int *sflag)  
  164.     {  
  165.         *width = CGDisplayModeGetWidth (Mode);  
  166.         *height = CGDisplayModeGetHeight (Mode);  
  167.         *freq = CGDisplayModeGetRefreshRate (Mode);  
  168.         CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding (Mode);  
  169.         *depth = 0;  
  170.         if (pixelEncoding = NULL) return -1;  
  171.         if (pixelEncoding = CFSTR(IO32BitDirectPixels))  
  172.             *depth = 32;  
  173.         else if (pixelEncoding = CFSTR(IO16BitDirectPixels))  
  174.             *depth = 16;  
  175.         else    *depth = 8;  
  176.          
  177.         *sflag = CGDisplayModeGetIOFlags(Mode);  
  178.         CFRelease(pixelEncoding);  
  179.         return 0;  
  180.     }  
  181.     bool GetBestDisplayMod(CGDirectDisplayID display, double dwidth, double dheight)  
  182.     {  
  183.         CFArrayRef modeList;  
  184.         CGDisplayModeRef mode;  
  185.         CFIndex index, count, sindex, scount=0;  
  186.         double width, height, depth, freq;  
  187.         double width1, height1, depth1, freq1;  
  188.         int flag, flag1;  
  189.         struct sLIST mList[100];  
  190.         int ireturn=0;  
  191.       
  192.         modeList = CGDisplayCopyAllDisplayModes (display, NULL);  
  193.         if (modeList == NULL)   return;  
  194.         count = CFArrayGetCount (modeList);  
  195.         scount=0;  
  196.         for (index = 0; index < count; index++)  
  197.         {  
  198.             mode = (CGDisplayModeRef)CFArrayGetValueAtIndex (modeList, index);  
  199.             GetModeParms(mode, &width, &height, &depth, &freq, &flag);  
  200.             // printf("........ scount=%d\n", (int)scount);  
  201.             if (!((width==width1) && (height==height1) && (depth==depth1) && (freq==freq1) && (flag==flag1))) {  
  202.                 if (CGDisplayModeIsUsableForDesktopGUI(mode)) {  
  203.                     mList[scount].mode=mode; mList[scount].width=width; mList[scount].height=height;  
  204.                     width1=width; height1=height; depth1=depth; freq1=freq; flag1=flag;  
  205.                     scount++;  
  206.                 }  
  207.             }  
  208.         }  
  209.         mode=NULL;  
  210.         qsort ((void *) mList, scount, sizeof(struct sLIST), (compfn) modecompare);  
  211.         for (index=0; index<scount; index++)  
  212.         {  
  213.             if (mList[index].width >= dwidth) {  
  214.                 if (mList[index].height >= dheight) {  
  215.                     mode = mList[index].mode;  
  216.                     break;  
  217.                 }  
  218.             }  
  219.         }  
  220.          
  221.         CGDisplayConfigRef pConfigRef;  
  222.         CGConfigureOption option=kCGConfigurePermanently;  
  223.         if ((mode != NULL) && (CGBeginDisplayConfiguration(&pConfigRef) == kCGErrorSuccess)) {  
  224.             CGConfigureDisplayWithDisplayMode(pConfigRef, display, mode, NULL);  
  225.             if (CGCompleteDisplayConfiguration (pConfigRef, option) !=kCGErrorSuccess) CGCancelDisplayConfiguration (pConfigRef);     
  226.         }  
  227.         else ireturn = -1;  
  228.         CFRelease(modeList);  
  229.         return ireturn;  
  230.     }  
  231.     int modecompare(struct sLIST *elem1, struct sLIST *elem2)  
  232.     {  
  233.        if ( elem1->width < elem2->width)  
  234.           return -1;  
  235.        else if (elem1->width > elem2->width) return 1;  
  236.        if (elem1->height < elem2->height) return -1;  
  237.        else if (elem1->height > elem2->height) return 1;  
  238.        else return 0;  
  239.     }  
  240.     void PrintUsage(const char *argv[])  
  241.     {  
  242.         char *fname = strrchr(argv[0], '/')+1;  
  243.         printf("Screen Resolution v1.0, Mac OS X 10.6 or later, i386\n");  
  244.         printf("Copyright 2010 Tony Liu. All rights reserved. June 1, 2010\n");  
  245.         printf("\nUsage:");  
  246.         printf("       %s -a\n", fname);  
  247.         printf("       %s [-l] [1..9]\n", fname);  
  248.         printf("       %s -s [ 1..9 ] hor_res vert_res\n", fname);  
  249.         printf("       %s -? | -h        this help.\n\n", fname);  
  250.         printf("      -l  list resolution, depth and refresh rate\n");  
  251.         printf("    1..9  display # (default: main display)\n");  
  252.         printf("  -l 1-9  List all support for the display #\n");  
  253.         printf("      -s  Set mode.\n");  
  254.         printf(" hor_res  horizontal resolution\n");  
  255.         printf("vert_res  vertical resolution\n\n");  
  256.         printf("Examples:\n");  
  257.         printf("%s -a             get online display number\n", fname);  
  258.         printf("%s                get current main diplay resolution\n", fname);  
  259.         printf("%s 3              get current resolution of third display\n", fname);  
  260.         printf("%s -l             get resolution, bit depth and refresh rate of all displays\n", fname);  
  261.         printf("%s -l 1           get first display all supported mode\n", fname);  
  262.         printf("%s -l 1 2         get first display the second supported mode\n", fname);  
  263.         printf("%s -s 800 600     set resolution of main display to 800x600\n", fname);  
  264.         printf("%s -s 2 800 600   set resolution of secondary display to 800x600\n", fname);  
  265.     }   

复制代码

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

笑脸一如从前 2022-10-22 04:05:13

压缩了一下。
里面包括了源码scres.m和执行命令scres

春花秋月 2022-10-22 04:05:13

今天初步测试了一下,这个程序,在Lion里面工作正常

另类 2022-10-22 04:05:13

感谢分享这个程序

转瞬即逝 2022-10-22 04:05:13

本帖最后由 tonyliu2ca 于 2012-09-28 17:04 编辑

回复 1# tonyliu2ca

    It supports 10.8.x, tested.

知足的幸福 2022-10-22 04:05:13

谢谢楼主~~~~~~~

陪你搞怪i 2022-10-22 04:05:13

版本更新:
添加切换双屏幕下的扩展模式/影像模式:

注:源代码已经移植到Github, 在这里

附件中的是可执行命令文件,下载后把文件的".zip"后缀去掉,就是命令文件(有可能需要设置运行标识)。

勿忘初心 2022-10-22 04:05:13

很实用,这是个好东东

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文