分享
 
 
 

检测屏幕分辨率和颜色深度

王朝c/c++·作者佚名  2006-01-06
窄屏简体版  字體: |||超大  

南京海军指挥学院 黄向明  

---- 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位,你可通过测试发现,一般绿色成分多一些。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有