檢測(cè)屏幕分辨率與顏色深度
發(fā)表時(shí)間:2024-06-06 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]南京海軍指揮學(xué)院 黃向明 ---- Windows API函數(shù)GetDeviceCaps()可提供廣泛的關(guān)于設(shè)備背景的信息,其中包括屏幕分辨率和顏色深度。GUI程序設(shè)計(jì)允許將圖形元素作為抽象的對(duì)象,不管硬件設(shè)備的情況及用戶設(shè)置的選擇。這對(duì)大多數(shù)情況,比如典型的窗口畫面和設(shè)備無(wú)關(guān)位圖操作都能滿足...
南京海軍指揮學(xué)院 黃向明
---- Windows API函數(shù)GetDeviceCaps()可提供廣泛的關(guān)于設(shè)備背景的信息,其中包括屏幕分辨率和顏色深度。GUI程序設(shè)計(jì)允許將圖形元素作為抽象的對(duì)象,不管硬件設(shè)備的情況及用戶設(shè)置的選擇。這對(duì)大多數(shù)情況,比如典型的窗口畫面和設(shè)備無(wú)關(guān)位圖操作都能滿足。但是在某些特殊情況下將受到限制,程序員需要其它方法來(lái)獲得相關(guān)設(shè)備的實(shí)際情況信息。本文就介紹一獲取屏幕分辨率和顏色深度的應(yīng)用程序。
---- 一、GetDeviceCaps()的功能
---- API函數(shù)GetDeviceCaps()可用來(lái)獲取設(shè)備的很多信息,它也就成為應(yīng)用和設(shè)備驅(qū)動(dòng)程序的網(wǎng)關(guān)。下列為它在wingdi.h中的原型:int GetDeviceCaps(HDC hdc,int nIndex);
---- 第一項(xiàng)參數(shù)是與檢測(cè)設(shè)備有關(guān)的設(shè)備背景,第二個(gè)參數(shù)表示檢測(cè)值。函數(shù)的具體功能在Win32SDK文件中有詳細(xì)介紹,本文集中介紹二個(gè)與顯示設(shè)備最相關(guān)的特性:分辨率(水平和垂直)和能顯示的不同顏色數(shù)。這些值能分別由HORZRES,VERTRES和BITSPIXEL返回給GetDeviceCaps()的第二個(gè)參數(shù)。BITSPIXEL返回描述一個(gè)像素顏色需要的位數(shù),要確定實(shí)際顏色數(shù)只要計(jì)算以2作為冪的返回值的指數(shù)。
---- 下列給出的C代碼就是檢測(cè)屏幕分辨率和顏色深度:
/* 屏幕dc初始化*/
HDC screenDC;
int colorBits, xRes, yRes;
screenDC = CreateDC("DISPLAY", NULL, NULL, NULL);
/* 檢索設(shè)備 */
colorBits = GetDeviceCaps(screenDC, BITSPIXEL);
xRes = GetDeviceCaps(screenDC, HORZRES);
yRes = GetDeviceCaps(screenDC, VERTRES);
/* 清除 */
DeleteDC(dc);
---- 從上述代碼看好象很簡(jiǎn)單,而且這在大多數(shù)情況下是可行的,但當(dāng)在32K彩色模式時(shí)就不行了,在這種情況下GetDeviceCaps()返回16而不是期望的15(2^15是32,768)。另外,32K和64K顏色之間的區(qū)別(兩者也作為"高-顏色方式")不大,當(dāng)用15bit設(shè)備顯示64K顏色位圖時(shí)Windows應(yīng)用抖動(dòng)算法實(shí)現(xiàn)。那么,怎么能檢測(cè)32K顏色情況和將它與64K情況區(qū)別開?
---- 二、開發(fā)SetPixel()函數(shù)功能
---- API函數(shù)比SetPixel(),以指定RGB顏色設(shè)置像素在設(shè)備背景上,還返回RGB值,而如果匹配不好的話,此返回的可能不是我們需要的顏色值。雖然,這一特性看上去沒(méi)什么用處,但你可用它解決GetDeviceCaps()對(duì)15位顏色模式返回16位問(wèn)題。如果用提供的RGB值設(shè)置一像素的顏色,并比較其返回的COLORREF,就能確定設(shè)備是否支持那種顏色。將上述算法放入一循環(huán)中,使RGB組合不斷改變,設(shè)備既是視頻卡,計(jì)算比較值為真的次數(shù)有多少。
---- 顯然,用上述方法要對(duì)SetPixel()調(diào)用2^24次在時(shí)間上是不合理的,其實(shí)并不需要在所有可能的值之中重復(fù),分別比較每個(gè)顏色組合(先紅色,然后綠色,然后藍(lán)色)也可產(chǎn)生相同的結(jié)果,并且迭代次數(shù)可減少到255次。
---- GetScrResolution()僅僅是對(duì)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()調(diào)用GetDeviceCaps(BITSPIXEL),但是,當(dāng)API返回16時(shí),它使用 GetScrRGBBitsPerPixel()來(lái)依次計(jì)算紅色、綠色和藍(lán)色組合。如果他們都等于32,API返回代碼16顯然是不正確的,而實(shí)際上因是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()通過(guò)255次循環(huán)測(cè)
試設(shè)備支持的紅、綠色和藍(lán)色值。
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;
/* 有時(shí)goto語(yǔ)句是處理出錯(cuò)的一種很簡(jiǎn)便的方法 */
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;
}
/* 計(jì)算紅、綠和藍(lán)匹配情況 */
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;
}
---- 可見(jiàn)GetScrRGBBitsPerPixel()不僅是解決本問(wèn)題的核心,而且還可得到正使用的紅色、綠色和藍(lán)色各自的位數(shù)。例如,當(dāng)有16位顏色時(shí),哪一個(gè)顏色獲得6位,而不是另二個(gè)的5位,你可通過(guò)測(cè)試發(fā)現(xiàn),一般綠色成分多一些。