新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> We choose to study algorithmic problems,  not because they are easy,  but because they are hard.
    [返回] 计算机科学论坛计算机理论与工程『 算法理论与分析 』 → 检测屏幕分辨率和颜色深度 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 4925 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 检测屏幕分辨率和颜色深度 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     葛靖青001 美女呀,离线,快来找我吧!水瓶座1984-2-14
      
      
      等级:大三(研究MFC有点眉目了!)
      文章:168
      积分:595
      门派:XML.ORG.CN
      注册:2010/11/2

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给葛靖青001发送一个短消息 把葛靖青001加入好友 查看葛靖青001的个人资料 搜索葛靖青001在『 算法理论与分析 』的所有贴子 点击这里发送电邮给葛靖青001 引用回复这个贴子 回复这个贴子 查看葛靖青001的博客楼主
    发贴心情 检测屏幕分辨率和颜色深度

    【转自互联网,如需引用请联系原作者】

    南京海军指挥学院 黄向明  

    ---- Windows API函数GetDeviceCaps()可提供广泛的关于设备背景的信息,其中包括屏幕分辨率和颜色深度。GUI程序设计允许将图形元素作为抽象的对象,不管硬件设备的情况及用户设置的选择。这对大多数情况,比如典型的窗口画面和设备无关位图操作都能满足。但是在某些特殊情况下将受到限制,程序员需要其它方法来获得相关设备的实际情况信息。本文就介绍一获取屏幕分辨率和颜色深度的应用程序。

    ---- 一、GetDeviceCaps()的功能

    ---- API函数GetDeviceCaps()可用来获取设备的很多信息,它也就成为应用和设备驱动程序的网关。下列为它在wingdi.h中的原型:int GetDeviceCaps(HDC hdc,int nIndex);

    ---- 第一项参数是与检测设备有关的设备背景,第二个参数表示检测值。函数的具体功能在Win32SDK文件中有详细介绍,本文集中介绍二个与显示设备最相关的特性:分辨率(水平和垂直)和能显示的不同颜色数。这些值能分别由HORZRES,VERTRES和BITSPIXEL返回给GetDeviceCaps()的第二个参数。BITSPIXEL返回描述一个像素颜色需要的位数,要确定实际颜色数只要计算以2作为幂的返回值的指数。

    ---- 下列给出的C代码就是检测屏幕分辨率和颜色深度:

    /* 屏幕dc初始化*/
    HDC screenDC;
    int colorBits, xRes, yRes;
    screenDC = CreateDC("DISPLAY", NULL, NULL, NULL);
    /* 检索设备 */
    colorBits = GetDeviceCaps(screenDC, BITSPIXEL);
    xRes = GetDeviceCaps(screenDC, HORZRES);
    yRes = GetDeviceCaps(screenDC, VERTRES);
    /* 清除 */
    DeleteDC(dc);

    ---- 从上述代码看好象很简单,而且这在大多数情况下是可行的,但当在32K彩色模式时就不行了,在这种情况下GetDeviceCaps()返回16而不是期望的15(2^15是32,768)。另外,32K和64K颜色之间的区别(两者也作为"高-颜色方式")不大,当用15bit设备显示64K颜色位图时Windows应用抖动算法实现。那么,怎么能检测32K颜色情况和将它与64K情况区别开?
    ---- 二、开发SetPixel()函数功能

    ---- API函数比SetPixel(),以指定RGB颜色设置像素在设备背景上,还返回RGB值,而如果匹配不好的话,此返回的可能不是我们需要的颜色值。虽然,这一特性看上去没什么用处,但你可用它解决GetDeviceCaps()对15位颜色模式返回16位问题。如果用提供的RGB值设置一像素的颜色,并比较其返回的COLORREF,就能确定设备是否支持那种颜色。将上述算法放入一循环中,使RGB组合不断改变,设备既是视频卡,计算比较值为真的次数有多少。

    ---- 显然,用上述方法要对SetPixel()调用2^24次在时间上是不合理的,其实并不需要在所有可能的值之中重复,分别比较每个颜色组合(先红色,然后绿色,然后蓝色)也可产生相同的结果,并且迭代次数可减少到255次。

    ---- GetScrResolution()仅仅是对GetDeviceCaps(HORZRES)和GetDeviceCaps(VERTRES)的接连处理:

    BOOL GetScrResolution(WORD* pWidth, WORD* pHeight)
    {
    HDC screenDC;
    screenDC = CreateDC("DISPLAY", NULL, NULL, NULL);
    if (!screenDC)
      return FALSE;

    *pWidth = GetDeviceCaps(screenDC, HORZRES);
    *pHeight = GetDeviceCaps(screenDC, VERTRES);

    DeleteDC(screenDC);
    return TRUE;
    }

    ---- GetScrColorDepth()调用GetDeviceCaps(BITSPIXEL),但是,当API返回16时,它使用 GetScrRGBBitsPerPixel()来依次计算红色、绿色和蓝色组合。如果他们都等于32,API返回代码16显然是不正确的,而实际上因是15。
    BYTE GetScrColorDepth()
    {
    HDC screenDC;
    BYTE numOfBits;

    screenDC = CreateDC("DISPLAY", NULL, NULL, NULL);
    if (!screenDC)
      return 0;
    numOfBits = GetDeviceCaps(screenDC, BITSPIXEL);
    DeleteDC(screenDC);

    if (numOfBits == 16)
      {
           // 是否为64K色,或32K
      WORD red, green, blue;
      GetScrRGBBitsPerPixel(&red, &green, &blue);
      if (red == 32 && green == 32 && blue == 32)
                  // 32*32*32 = 2^15 色
       numOfBits = 15;
    }

    return numOfBits;
    }

    GetScrRGBBitsPerPixel()通过255次循环测
    试设备支持的红、绿色和蓝色值。

    BOOL GetScrRGBBitsPerPixel(WORD* pRedBits,
                               WORD* pGreenBits,
                               WORD* pBlueBits)
    {
    BOOL isError = FALSE;
    HDC screenDC, memDC;
    HBITMAP bmp = NULL;
    HBITMAP bmpOld = NULL;

    *pRedBits = *pGreenBits = *pBlueBits = 1;

    screenDC = CreateDC("DISPLAY", NULL,
      NULL, NULL);
    memDC = CreateCompatibleDC(NULL);
    bmp = CreateCompatibleBitmap(screenDC, 1, 1);
    isError = screenDC && memDC && bmp;
    if (!isError)
      goto CleanUp;
      /* 有时goto语句是处理出错的一种很简便的方法 */
    bmpOld = (HBITMAP)SelectObject(memDC, bmp);

    {
      COLORREF oldColor;
      COLORREF curColor = RGB(255, 255, 255);
      int n;
      for (n = 255; n >= 0; --n)
      {
       oldColor = curColor;
       curColor = SetPixel(memDC,
       0, 0, RGB(n, n, n));
       isError = curColor;
       if (isError == CLR_INVALID)
       {
        isError = TRUE;
        goto CleanUp;
       }
       /* 计算红、绿和蓝匹配情况 */
       if (GetRvalue(curColor)
       < GetRvalue(oldColor))
        ++(*pRedBits);
       if (GetGvalue(curColor)
       < GetGvalue(oldColor))
        ++(*pGreenBits);
       if (GetBvalue(curColor)
      < GetBvalue(oldColor))
        ++(*pBlueBits);
      }
    }
    CleanUp:
      if (bmpOld)
       DeleteObject(bmpOld);
      if (bmp)
       DeleteObject(bmp);
      if (isError)
       *pRedBits = *pGreenBits
      = *pBlueBits = 0;
      if (screenDC)
       DeleteDC(screenDC);
      if (memDC)
       DeleteDC(memDC);

      return !isError;
    }


    ---- 可见GetScrRGBBitsPerPixel()不仅是解决本问题的核心,而且还可得到正使用的红色、绿色和蓝色各自的位数。例如,当有16位颜色时,哪一个颜色获得6位,而不是另二个的5位,你可通过测试发现,一般绿色成分多一些。


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    ---人之所以能,是相信能!!

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2010/11/16 11:59:00
     
     GoogleAdSense水瓶座1984-2-14
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 算法理论与分析 』的所有贴子 点击这里发送电邮给Google AdSense 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/23 15:18:25

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    66.406ms