windows位圖和調(diào)色板_第1頁(yè)
windows位圖和調(diào)色板_第2頁(yè)
windows位圖和調(diào)色板_第3頁(yè)
windows位圖和調(diào)色板_第4頁(yè)
windows位圖和調(diào)色板_第5頁(yè)
已閱讀5頁(yè),還剩8頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第1章Windows位圖和調(diào)色板1.1 位圖和調(diào)色板的概念如今Windows(3.x以及95,98,NT)系列已經(jīng)成為絕大多數(shù)用戶使用的操作系統(tǒng),它比口0武功的一個(gè)重要因素是它可視化的漂亮界面。那么Windows是如何顯示圖象的呢?這就要談到位圖(bitmap)。我們知道,普通的顯示器屏幕是由許許多多點(diǎn)構(gòu)成的,我們稱之為象素。顯示時(shí)采用掃要重復(fù)上述過(guò)程幾描的方法:電子槍每次從左到右掃描一行,為每個(gè)象素著色,然后從上到下這樣掃描假設(shè)干行,就掃過(guò)了一屏。為了防止閃爍,每秒十次。例如我們常說(shuō)的屏幕分辨率為640X480,刷新頻率為70Hz,意思是說(shuō)每行要掃描640個(gè)象素素,一共有480行,每秒重復(fù)掃

2、描屏幕70次o我們稱這種顯示器為位映象設(shè)備。所謂位映象,就是指一個(gè)二維的象素矩陣,而位圖就是采用位映象方法顯示和存儲(chǔ)的圖象。舉個(gè)例子,圖1.1是一幅普通的黑白位圖,圖1.2是被放大后的圖,圖中每個(gè)方格代表了一個(gè)象素。我們可以看到:整個(gè)骷髏就是由這樣一些黑點(diǎn)和白點(diǎn)組成的。圖1.1骷髏圖1.2放大后的骷髏位圖那么,彩色圖是怎么回事呢?我們先來(lái)說(shuō)說(shuō)三元色RGB既念。我們知道,自然界中的所有顏色都可以由紅、綠、藍(lán)(R,G,B)組合而成。有的顏色含有紅色成分多一些,如深紅;有的含有紅色成分少一些,如淺紅。針對(duì)含有紅色成分的多少,可以分成0到255共256個(gè)等級(jí),0級(jí)表示不含紅色成分;255級(jí)表示含有10

3、0%勺紅色成分。同樣,綠色和藍(lán)色也被分成256級(jí)。這種分級(jí)概念稱為量化。這樣,根據(jù)紅、綠、藍(lán)各種不同的組合我們就能表示出256X256X256,約1600萬(wàn)種顏色。這么多顏色對(duì)于我們?nèi)搜蹃?lái)說(shuō)已經(jīng)足夠豐富了。表1.1常見顏色的RGBS合值顏色RGB紅25500藍(lán)02550綠r00255黃:2552550紫2550255青0255255白1255255255里八、000灰128128128你大概已經(jīng)明白了,當(dāng)一幅圖中每個(gè)象素賦予不同的RGB直時(shí),能呈現(xiàn)出五彩繽紛的顏色了,這樣就形成了彩色圖。確實(shí)是這樣的,但實(shí)際上的做法還有些差異。讓我們來(lái)看看下面的例子。有一個(gè)長(zhǎng)寬各為200個(gè)象素,顏色數(shù)為16色的

4、彩色圖,每一個(gè)象素都用RGB三個(gè)分量表示。因?yàn)槊總€(gè)分量有256個(gè)級(jí)別,要用8位(bit),即一個(gè)字節(jié)(byte)來(lái)表示,所以每個(gè)象素需要用3個(gè)字節(jié)。整個(gè)圖象要用200X200X3,約120k字節(jié),可不是一個(gè)小數(shù)目呀!假設(shè)我們用下面的方法,就能省的多。因?yàn)槭且粋€(gè)16色圖,也就是說(shuō)這幅圖中最多只有16種顏色,我們可以用一個(gè)表:表中的每一行記錄一種顏色的RGB值。這樣當(dāng)我們表示一個(gè)象素的顏色時(shí),只需要指出該顏色是在第幾行,即該顏色在表中的索引值。舉個(gè)例子,假設(shè)表的第0行為255,0,0(紅色),那么當(dāng)某個(gè)象素為紅色時(shí),只需要標(biāo)明0即可。讓我們?cè)賮?lái)計(jì)算一下:16種狀態(tài)可以用4位(bit)表示,所以一個(gè)

5、象素要用半個(gè)字節(jié)。整個(gè)圖象要用200X200X0.5,約20k字節(jié),再加上表占用的字節(jié)為3X16=48字節(jié).整個(gè)占用的字節(jié)數(shù)約為前面的1/6,省很多吧?這弓RGB的表,就是我們常說(shuō)的調(diào)色板(Palette),另一種叫法是顏色查找表LUT(LookUpTable),似乎更確切一些。Windows位圖中便用到了調(diào)色板技術(shù)。其實(shí)不光是Windows位圖,許多圖象文件格式如pcx、tif、gif等都用到了。所以很好地掌握調(diào)色板的概念是非常有用的。有一種圖,它的顏色數(shù)高達(dá)256X256X256種,也就是說(shuō)包含我們上述提到的RGB顏色表示方法中所有的顏色,這種圖叫做真彩色圖(truecolor)。真彩色圖

6、并不是說(shuō)一幅圖包含了所有的顏色,而是說(shuō)它具有顯示所有顏色的才能,即最多可以包含所有的顏色。表示真彩色圖時(shí),每個(gè)象素直接用RGB三個(gè)分量字節(jié)表示,而不采用調(diào)色板技術(shù)。原因很明顯:假設(shè)用調(diào)色板,表示一個(gè)象素也要用24位,這是因?yàn)槊糠N顏色的索引要用24位(因?yàn)榭偣灿?24種顏色,即調(diào)色板有224行),和直接用R,G,B三個(gè)分量表示用的字節(jié)數(shù)一樣,不但沒有任何廉價(jià),還要加上一個(gè)256X256X256X3個(gè)字節(jié)的大調(diào)色板。所以真彩色圖直接用RGB三個(gè)分量表示,它又叫做24位色圖。1.2 bmp文件格式介紹完位圖和調(diào)色板的概念,下面就讓我們來(lái)看一看Windows的位圖文件(.bmp文件)的格式是什么樣子的

7、。bmp文件大體上分成四個(gè)局部,如圖1.3所示。位圖文件頭BITMAPFILEHEADER位圖信息頭BITMAPINFOHEADER調(diào)色板Palette實(shí)際的位圖數(shù)據(jù)ImageData圖1.3Windows位圖文件構(gòu)造示意圖第一局部為位圖文件頭BITMAPFILEHEADER是一個(gè)構(gòu)造,其定義如下:typedefstructtagBITMAPFILEHEADERWORDbfType;DWORDbfSize;WORDbfReserved1;WORDbfReserved2;DWORDbfOffBits;BITMAPFILEHEADER這個(gè)構(gòu)造的長(zhǎng)度是固定的,為14個(gè)字節(jié)(WOR函無(wú)符號(hào)16位整數(shù),

8、DWORD;無(wú)符號(hào)32位整數(shù)),各個(gè)域的說(shuō)明如下:bfType:指定文件類型,必須是0x424D,即字符串“BM,也就是說(shuō)所有.bmp文件的頭兩個(gè)字節(jié)都是“BM。BfSize:指定文件大小,包括這14個(gè)字節(jié)。bfReserved1,bfReserved2:為保存字,不用考慮bfOffBits:為從文件頭到實(shí)際的位圖數(shù)據(jù)的偏移字節(jié)數(shù),即圖1.3中前三個(gè)局部的長(zhǎng)度之和。第二局部為位圖信息頭BITMAPINFOHEADE他是一個(gè)構(gòu)造,其定義如下:typedefstructtagBITMAPINFOHEADERDWORDbiSize;LONGbiWidth;LONGbiHeight;WORDbiPla

9、nes;WORDbiBitCountDWORDbiCompression;DWORDbiSizeImage;LONGbiXPelsPerMeter;LONGbiYPelsPerMeter;DWORDbiClrUsed;DWORDbiClrImportant;BITMAPINFOHEADER這個(gè)構(gòu)造的長(zhǎng)度是固定的,為40個(gè)字節(jié)(LONG為32位整數(shù)),各個(gè)域的說(shuō)明如下:biSize:指定這個(gè)構(gòu)造白長(zhǎng)度,為40。BiWidth:指定圖象的寬度,單位是象素。BiHeight:指定圖象的高度,單位是象素。BiPlanes:必須是1,不用考慮。biBitCount:指定表示顏色時(shí)要用到的位數(shù),常用的值為

10、1(黑白二色圖),4(16色圖),8(256色),24(真彩色圖)(新的.bmp格式支持32位色,這里就不做討論了)。BiCompression:指定位圖是否壓縮,有效的值為BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS(者B是一些Windows定義好的常量)。要說(shuō)明的是,Windows位圖可以采用RLE4,和RLE8的壓縮格式,但用的不多。我們今后所討論的只有第一種不壓縮的情況,即biCompression為BIRGB的情況。BiSizeImage:指定實(shí)際的位圖數(shù)據(jù)占用的字節(jié)數(shù),其實(shí)也可以從以下的公式中計(jì)算出來(lái):biSizeImage=biWidth'xbi

11、Height要注意的是:上述公式中的biWidth'必須是4的整倍數(shù)(所以不是biWidth,而是biWidth',表示大于或等于biWidth的,最接近4的整倍數(shù)。舉個(gè)例子,假設(shè)biWidth=240,那么biWidth'=240;假設(shè)biWidth=241,biWidth'=244)。假設(shè)biCompression為BI_RGB那么該項(xiàng)可能為零biXPelsPerMeter:指定目的設(shè)備的程度分辨率,單位是每米的象素個(gè)數(shù),關(guān)于分辨率的概念,我們將在第4章詳細(xì)介紹。BiYPelsPerMeter:指定目的設(shè)備的垂直分辨率,單位同上。BiClrUsed:指定本圖

12、象實(shí)際用到的顏色數(shù),假設(shè)該值為零,那么用到的顏色數(shù)為biBitCount2。BiClrlmportant:指定本圖象中重要的顏色數(shù),假設(shè)該值為零,那么認(rèn)為所有的顏色都是重要的。第三局部為調(diào)色板Palette,當(dāng)然,這里是對(duì)那些需要調(diào)色板的位圖文件而言的。有些位圖,如真彩色圖,前面已經(jīng)講過(guò),是不需要調(diào)色板的,BITMAPINFOHEADE需直接是位圖數(shù)據(jù)。調(diào)色板實(shí)際上是一個(gè)數(shù)組,共有biClrUsed個(gè)元素(假設(shè)該值為零,那么有2biBitCount個(gè)元素)。數(shù)組中每個(gè)元素的類型是一個(gè)RGBQUAD造,占4個(gè)字節(jié),其定義如下:typedefstructtagRGBQUADBYTErgbBlue;

13、/該顏色的藍(lán)色分量BYTErgbGreen;/該顏色的綠色分量BYTErgbRed;/該顏色的紅色分量BYTErgbReserved;/保存值RGBQUAD第四局部就是實(shí)際的圖象數(shù)據(jù)了。對(duì)于用到調(diào)色板的位圖,圖象數(shù)據(jù)就是該象素顏在調(diào)色板中的索引值。對(duì)于真彩色圖,圖象數(shù)據(jù)就是實(shí)際的RGB值。下面針對(duì)2色、16色、256色位圖和真彩色位圖分別介紹。對(duì)于2色位圖,用1位就可以表示該象素的顏色(一般0表示黑,1表示白),所以一個(gè)字節(jié)可以表示8個(gè)象素。對(duì)于16色位圖,用4位可以表示一個(gè)象素的顏色,所以一個(gè)字節(jié)可以表示2個(gè)象素。對(duì)于256色位圖,一個(gè)字節(jié)剛好可以表示1個(gè)象素。對(duì)于真彩色圖,三個(gè)字節(jié)才能表示

14、1個(gè)象素,哇,好費(fèi)空間呀!沒方法,誰(shuí)叫你想讓圖的顏色顯得更亮麗呢,有得必有失嘛。要注意兩點(diǎn):(1)每一行的字節(jié)數(shù)必須是4的整倍數(shù),假設(shè)不是,那么需要補(bǔ)齊。這在前面介紹biSizeImage時(shí)已經(jīng)提到了。(2)一般來(lái)說(shuō),BM件的數(shù)據(jù)從下到上,從左到右的。也就是說(shuō),從文件中最先讀到的是圖象最下面一行的左邊第一個(gè)象素,然后是左邊第二個(gè)象素接下來(lái)是倒數(shù)第二行左邊第一個(gè)象素,左邊第二個(gè)象素依次類推,最后得到的是最上面一行的最右一個(gè)象素。好了,終于介紹完bmp文件構(gòu)造了,是不是覺得頭有些大?別著急,對(duì)照著下面的程序,你就會(huì)很清楚了(我最愛看源程序了,呵呵)。1.3顯示一個(gè)bmp文件的C程序下面的函數(shù)Loa

15、dBmpFile,其功能是從一個(gè).bmp文件中讀取數(shù)據(jù)(包括BITMAPINFOHEADE砌色板和實(shí)際圖象數(shù)據(jù)),將其存儲(chǔ)在一個(gè)全局內(nèi)存句柄hImgData中,這個(gè)hImgData將在以后的圖象處理程序中用到。同時(shí)填寫一個(gè)類型為HBITMAP勺全局變量hBitmap和一個(gè)類型為HPALETTE勺全局變量hPalette。這兩個(gè)變量將在處理WM_PAINT肖息時(shí)用到,用來(lái)顯示位圖。該函數(shù)的兩個(gè)參數(shù)分別是用來(lái)顯示位圖的窗口句柄,和.bmp文件名(全途徑)。當(dāng)函數(shù)成功時(shí),返回TRUE否那么返回FALSEBITMAPFILEHEADERbf;BITMAPINFOHEADERbi;BOOLLoadBmp

16、File(HWNDhWnd,char*BmpFileName)HFILEhf;/指向BITMAPINFOHEADER造的指針LPBITMAPINFOHEADERlpImgData;LOGPALETTE調(diào)色板構(gòu)造的指針LPRGBQUADRGBQUAD造的指針HPALETTEe;/用來(lái)保存設(shè)備中原來(lái)的調(diào)色板HDChDc;/設(shè)備句柄HLOCAL/存儲(chǔ)調(diào)色板的局部?jī)?nèi)存句柄DWORDtes;/每一行的字節(jié)數(shù)DWORDe;/實(shí)際的圖象數(shù)據(jù)占用的字節(jié)數(shù)/實(shí)際用到的顏色數(shù),即調(diào)色板數(shù)組中的顏色個(gè)數(shù)文件句柄*pPal; / 指向邏輯lpRGB; / 指 向hPrevPaletthPal;LineByImgSiz

17、NumColDWORDors;DWORDi;if(hf=_lopen(BmpFileName,OF_READ)=HFILE_ERROR)MessageBox(hWnd,"Filec:test.bmpnotfound!","ErrorMessage",MB_OK|MB_ICONEXCLAMATION);returnFALSE;/翻開文件錯(cuò)誤,返回/將BITMAPFILEHEADER造從文件中讀出,填寫到bf中_lread(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER);將BITMAPINFOHEADER造從文件中讀出,

18、填寫到bi中_lread(hf,(LPSTR)&bi,sizeof(BITMAPINFOHEADER);/我們定義了一個(gè)宏#defineWIDTHBYTES(i)(i+31)/32*4)上面曾經(jīng)/提到過(guò),每一行的字節(jié)數(shù)必須是4的整倍數(shù),只要調(diào)用就能完成這一換算。舉一個(gè)例/子,對(duì)于2色圖,假設(shè)圖象寬是31,那么每一行需要31位存儲(chǔ),合3個(gè)/字節(jié)加7位,因?yàn)樽止?jié)數(shù)必須是4的整倍數(shù),所以應(yīng)該是4,而此時(shí)的/biWidth=31,biBitCount=1,WIDTHBYTES(31*1)=4,和我們?cè)O(shè)想的一樣。/再舉一個(gè)256色的例子,假設(shè)圖象寬是31,那么每一行需要31個(gè)字節(jié)存/儲(chǔ),因?yàn)樽止?jié)

19、數(shù)必須是4的整倍數(shù),所以應(yīng)該是32,而此時(shí)的/biWidth=31,biBitCount=8,WIDTHBYTES(31*8)=32,我們?cè)O(shè)想的一樣。你可/以多舉幾個(gè)例子來(lái)驗(yàn)證一下/LineBytes為每一行的字節(jié)數(shù)/ImgSize為實(shí)際的圖象數(shù)據(jù)占用的字節(jié)數(shù)ImgSize=(DWORD)LineBytes*bi.biHeight;/NumColors為實(shí)際用到的顏色數(shù),即調(diào)色板數(shù)組中的顏色個(gè)數(shù)if(bi.biClrUsed!=0)/假設(shè)bi.biClrUsed不為零,即為實(shí)際用到的顏色數(shù)NumColors=(DWORD)bi.biClrUsed;else/否那么,用到的顏色數(shù)為2biBitC

20、ount。switch(bi.biBitCount)case1:NumColors=2;break;case4:NumColors=16;break;case8:NumColors=256;break;case24:NumColors=0;/對(duì)于真彩色圖,沒用到調(diào)色板break;default:/不處理其它的顏色數(shù),認(rèn)為出錯(cuò)。MessageBox(hWnd,"Invalidcolornumbers!","ErrorMessage",MB_OK|MB_ICONEXCLAMATION);_lclose(hf);returnFALSE;/關(guān)閉文件,返回FALS

21、Eif(bf.bfOffBits!=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)/計(jì)算出的偏移量與實(shí)際偏移量不符,一定是顏色數(shù)出錯(cuò)MessageBox(hWnd,"Invalidcolornumbers!","ErrorMessage",MB_OK|MB_ICONEXCLAMATION);_lclose(hf);returnFALSE;/關(guān)閉文件,返回FALSEbf.bfSize=sizeof(BITMAPFILEHEADER)+si

22、zeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;/分配內(nèi)存,大小為BITMAPINFOHEADER造長(zhǎng)度加調(diào)色板+實(shí)際位圖if(hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize)=NULL)/分配內(nèi)存錯(cuò)誤MessageBox(hWnd,"Errorallocmemory!","ErrorMessage",MB_OK|MB_ICONEXCLAMATION);

23、_lclose(hf);returnFALSE;/關(guān)閉文件,返回FALSE/指針lpImgData指向該內(nèi)存區(qū)lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);/文件指針重新定位到BITMAPINFOHEADER始處_llseek(hf,sizeof(BITMAPFILEHEADER),SEEK_SET);/將文件內(nèi)容讀入lpImgData_hread(hf,(char*)lpImgData,(long)sizeof(BITMAPINFOHEADER)+(long)NumColors*sizeof(RGBQUAD)+ImgSize);_lcl

24、ose(hf);/關(guān)閉文件if(NumColors!=0)/NumColors不為零,說(shuō)明用到了調(diào)色板/為邏輯調(diào)色板分配局部?jī)?nèi)存,大小為邏輯調(diào)色板構(gòu)造長(zhǎng)度加/NumColors個(gè)PALETTENTRYhPal=LocalAlloc(LHND,sizeof(LOGPALETTE)+NumColors*sizeof(PALETTEENTRY);/指針pPal指向該內(nèi)存區(qū)pPal=(LOGPALETTE*)LocalLock(hPal);/填寫邏輯調(diào)色板構(gòu)造的頭pPal->palNumEntries=NumColors;pPal->palVersion=0x300;/lpRGB指向的是調(diào)

25、色板開始的位置lpRGB=(LPRGBQUAD)(LPSTR)lpImgData+(DWORD)sizeof(BITMAPINFOHEADER);/填寫每一項(xiàng)for(i=0;i<NumColors;i+)pPal->palPalEntryi.peRed=lpRGB->rgbRed;pPal->palPalEntryi.peGreen=lpRGB->rgbGreen;pPal->palPalEntryi.peBlue=lpRGB->rgbBlue;pPal->palPalEntryi.peFlags=(BYTE)0;lpRGB+;/指針移到下一項(xiàng)/

26、產(chǎn)生邏輯調(diào)色板,hPalette是一個(gè)全局變量hPalette=CreatePalette(pPal);/釋放局部?jī)?nèi)存LocalUnlock(hPal);LocalFree(hPal);/獲得設(shè)備上下文句柄hDc=GetDC(hWnd);if(hPalette)/假設(shè)剛剛產(chǎn)生了邏輯調(diào)色板/將新的邏輯調(diào)色板選入DC將舊的邏輯調(diào)色板句柄保存在/hPrevPalettehPrevPalette=SelectPalette(hDc,hPalette,FALSE);RealizePalette(hDc);/產(chǎn)生位圖句柄hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEA

27、DER)lpImgData,(LONG)CBM_INIT,(LPSTR)lpImgData+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),(LPBITMAPINFO)lpImgData,DIB_RGB_COLORS);/將原來(lái)的調(diào)色板(假設(shè)有的話)選入設(shè)備上下文句柄if(hPalette&&hPrevPalette)SelectPalette(hDc,hPrevPalette,FALSE);RealizePalette(hDc);ReleaseDC(hWnd,hDc);釋放設(shè)備上下文GlobalUnlock(hlmgDat

28、a);解鎖內(nèi)存區(qū)returnTRUE;/成功返回對(duì)上面的程序要說(shuō)明兩點(diǎn):對(duì)于需要調(diào)色板的圖,要想正確地顯示,必須根據(jù)bmp文件,產(chǎn)生邏輯調(diào)色板。產(chǎn)生的方法是:為邏輯調(diào)色板指針?lè)峙鋬?nèi)存,大小為邏輯調(diào)色板構(gòu)造(LOGPALETT張度加NumColors個(gè)PALETTENTRY/J(調(diào)色板的每一項(xiàng)都是一個(gè)PALETTEENTRY造);填寫邏輯調(diào)色板構(gòu)造的頭pPal->palNumEntries=NumColors;pPal->palVersion=0x300;從文件中讀取調(diào)色板的RGB直,填寫到每一項(xiàng)中;產(chǎn)生邏輯調(diào)色板:hPalette=CreatePalette(pPal)。(2)產(chǎn)生

29、位圖(BITMAP)句柄,該項(xiàng)工作由函數(shù)CreateDIBitmap來(lái)完成。hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpImgData,(LONG)CBM_INIT,(LPSTR)lpImgData+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),(LPBITMAPINFO)lpImgData,DIB_RGB_COLORS);CreateDIBitmap的作用是產(chǎn)生一個(gè)和Windows設(shè)備無(wú)關(guān)的位圖。該函數(shù)的第一項(xiàng)參數(shù)為設(shè)備上下文句柄。假設(shè)位圖用到了調(diào)色板,要在調(diào)用CreateDIBit

30、map之前將邏輯調(diào)色板選入該設(shè)備上下文中,產(chǎn)生hBitmap后,再把原調(diào)色板選入該設(shè)備上下文中,并釋放該上下文;第二項(xiàng)為指向BITMAPINFOHEADER指針;第三項(xiàng)就用常量CBM_INI,不用考慮;第四項(xiàng)為指向調(diào)色板的指針;第五項(xiàng)為指向BITMAPINFO包才BITMAPINFOHEADER,色板,及實(shí)際的圖象數(shù)據(jù))的指針;第六項(xiàng)就用常量DIB_RGB_COLOR杯用考慮。上面提到了設(shè)備上下文,相信編過(guò)Windows程序的讀者對(duì)它并不陌生,這里再簡(jiǎn)單介紹一下。Windows操作系統(tǒng)統(tǒng)一管理著諸如顯示,打印等操作,將它們看作是一個(gè)個(gè)的設(shè)備,每一個(gè)設(shè)備都有一個(gè)復(fù)雜的數(shù)據(jù)構(gòu)造來(lái)維護(hù)。所謂設(shè)備上下

31、文就是指這個(gè)數(shù)據(jù)構(gòu)造。然而,我們不能直接和這些設(shè)備上下文打交道,只能通過(guò)引用標(biāo)識(shí)它的句柄(實(shí)際上是一個(gè)整數(shù)),讓W(xué)indows去做相應(yīng)的處理。產(chǎn)生的邏輯調(diào)色板句柄hPalette和位圖句柄hBitmap要在處理WM_PAIN稍息時(shí)使用,這樣才能在屏幕上顯示出來(lái),處理過(guò)程如下面的程序。StaticHDChDC,hMemDC;PAINTSTRUCTps;caseWM_PAINT:hDC=BeginPaint(hwnd,&ps);獲得屏幕設(shè)備上下文if(hBitmap)/hBitmap一開始是NULL當(dāng)不為NULL時(shí)表示有圖hMemDC=CreateCompatibleDC(hDC);建立一

32、個(gè)內(nèi)存設(shè)備上下文if(hPalette)/有調(diào)色板/將調(diào)色板選入屏幕設(shè)備上下文SelectPalette(hDC,hPalette,FALSE);/將調(diào)色板選入內(nèi)存設(shè)備上下文SelectPalette(hMemDC,hpalette,FALSE);RealizePalette(hDC);/將位圖選入內(nèi)存設(shè)備上下文SelectObject(hMemDC,hBitmap);/顯示位圖BitBlt(hDC,0,0,bi.biWidth,bi.biHeight,hMemDC,0,0,SRCCOPY);/釋放內(nèi)存設(shè)備上下文DeleteDC(hMemDC);/釋放屏幕設(shè)備上下文EndPaint(hwnd,

33、&ps);break;在上面的程序中,我們調(diào)用CreateCompatibleDC創(chuàng)立一個(gè)內(nèi)存設(shè)備上下文。SelectObject函數(shù)將與設(shè)備無(wú)關(guān)的位圖選入內(nèi)存設(shè)備上下文中。然后我們調(diào)用BitBlt函數(shù)在內(nèi)存設(shè)備上下文和屏幕設(shè)備上下文中進(jìn)展位拷貝。由于所有操作都是在內(nèi)存中進(jìn)展,所以速度很快。BitBlt函數(shù)的參數(shù)分別為:1.目的設(shè)備上下文,在上面的程序里,為屏幕設(shè)備上下文,假設(shè)改成打印設(shè)備上下文,就不是顯示位圖,而是打??;2.目的矩形左上角點(diǎn)x坐標(biāo);3.目的矩形左上角點(diǎn)y坐標(biāo),在上面的程序中,2和3為(0,0),表示顯示在窗口的左上角;4.目的矩形的寬度;5.目的矩形的高度;6.源設(shè)備

34、上下文,在上面的程序里,為內(nèi)存設(shè)備上下文;7.源矩形左上角點(diǎn)x坐標(biāo);8.源矩形左上角點(diǎn)y坐標(biāo);9.操作方式,在這里為SRCCORY表示直接將源矩形拷貝到目的矩形。還可以是反色,擦除,做“與運(yùn)算等操作,詳細(xì)細(xì)節(jié)見VC+幫助。你可以13t著改改第2、3、4、5、7、8、9項(xiàng)參數(shù),就能體會(huì)到它們的含義了。哇,終于講完了。是不是覺得有點(diǎn)枯燥?這一章是有點(diǎn)兒枯燥,特別是當(dāng)你對(duì)Windows的編程并不清楚時(shí),就更覺得如此。不過(guò),當(dāng)一幅漂亮的bmp圖顯示在屏幕上時(shí),你還是會(huì)興奮地大叫“Yeah!,至少當(dāng)年我是這樣。在本書的附盤中包含所有的源程序,包括頭文件和資源文件和例圖。特別要注意的是,退出時(shí),別忘了釋放

35、內(nèi)存和資源,這是每個(gè)程序員應(yīng)該養(yǎng)成的習(xí)慣。這些個(gè)程序并不是很完善,例如,假設(shè)一幅圖很大,屏幕顯示不下怎么辦?你可以試著自己加上滾動(dòng)條。另外,為了節(jié)省篇幅,.bmp文件名被固定為c:test.bmp,可以自己參加翻開文件對(duì)話框,任意選擇你要顯示的文件。圖1.4為程序運(yùn)行時(shí)的畫面。圖1.4運(yùn)行時(shí)的畫面最后,再介紹一個(gè)命令行編譯的竅門。為什么要用命令行編譯呢?主要有兩個(gè)好處:第一,不用進(jìn)入IDE(集成開發(fā)環(huán)境),節(jié)省了時(shí)間,而且編譯速度也比較快;第二,對(duì)于簡(jiǎn)單的程序,不用生成工程文件.mdp或.mak,直接就能生成.exe文件,這一點(diǎn),在下面的例子中可以看到。在安裝完VisualC+時(shí),在bin目錄下會(huì)產(chǎn)生一個(gè)VCVARS32.BATC件,它的作用是在命令行編譯時(shí)設(shè)置正確的環(huán)境變量,如存放頭文件的INCLUDE目錄,存放庫(kù)文件的LIB目錄等。假設(shè)你沒找到這個(gè)批處理文件,可以參考下面的例子,自己做一個(gè)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論