《Windows程序設計》讀書筆記------------->>設備內容之一

設備內容概述

當您想在一個圖形輸出設備(諸如屏幕或者打印機)上繪圖時,您首先必須獲得一個設備內容(或者DC)的句柄。將句柄傳回給程序時,Windows就給了您使用設備的權限。然後您在GDI函數中將這個句柄作爲一個參數,向Windows標識您想在其上進行繪圖的設備。

設備內容中包含許多確定GDI函數如何在設備上工作的目前「屬性」,這些屬性允許傳遞給GDI函數的參數只包含起始座標或者尺寸信息,而不必包含Windows在設備上顯示對象時需要的所有其它信息。例如,呼叫TextOut時,您只需要在函數中給出設備內容句柄、起始座標、文字和文字的長度。您不必指定字體、文字顏色、文字後面的背景色彩以及字符間距,因爲這些屬性都是設備內容的一部分。當您想改變這些屬性之一時,您呼叫一個可以改變設備內容中屬性的函數,以後針對該設備內容的TextOut呼叫來使用改變後的屬性。

設備內容的取得

以前有說過有很多取得設備句柄的方法,但是無論是什麼方法,在最後這些設備句柄都是要釋放的。
每次調用都需要在最後釋放它,而且不能在使用的時候釋放。

 


 

最常用的取得並釋放設備內容句柄的方法是,在處理WM_PAINT消息時,使用BeginPaint和EndPaint呼叫:

hdc = BeginPaint (hwnd, &ps) ;
        
//其它行程序
        
EndPaint (hwnd, 
&ps) ;

變量ps是型態爲PAINTSTRUCT的結構,該結構的hdc字段是BeginPaint傳回的設備內容句柄。 PAINTSTRUCT結構又包含一個名爲rcPaint的RECT(矩形)結構,rcPaint定義一個包圍窗口顯示區域無效範圍的矩形。使用從BeginPaint獲得的設備內容句柄,只能在這個區域內繪圖。BeginPaint呼叫使該區域有效。

 


 

Windows程序還可以在處理非WM_PAINT消息時取得設備內容句柄:

hdc = GetDC (hwnd) ;
        
//其它行程序
        
ReleaseDC (hwnd, hdc) ;

這個設備內容適用於窗口句柄爲hwnd的顯示區域。這些呼叫與BeginPaint和EndPaint的組合之間的基本區別是,利用從GetDC傳回的句柄可以在整個顯示區域上繪圖。當然, GetDC和ReleaseDC不使顯示區域中任何可能的無效區域變成有效。

 


 

Windows程序還可以取得適用於整個窗口(而不僅限於窗口的顯示區域)的設備內容句柄:

hdc = GetWindowDC (hwnd) ;
        
//其它行程序
        
ReleaseDC (hwnd, hdc) ;

 

這個設備內容除了顯示區域之外,還包括窗口的標題列、菜單、滾動條和框架(frame)。GetWindowDC函數很少使用,如果想嘗試用一用它,則必須攔截處理WM_NCPAINT消息,Windows使用該消息在窗口的非顯示區域上繪圖。

 


 

BeginPaint、GetDC和GetWindowDC獲得的設備內容都與視訊顯示器上的某個特定窗口相關。取得設備內容句柄的另一個更通用的函數是CreateDC:

hdc = CreateDC (pszDriver, pszDevice, pszOutput, pData) ;
        
其它行程序
        
DeleteDC (hdc) ;

 


 

例如,您可以通過下面的呼叫來取得整個屏幕的設備內容句柄:

hdc = CreateDC (TEXT ("DISPLAY"), NULL, NULL, NULL) ;

 


 

有時您只是需要取得關於某設備內容的一些信息而並不進行任何繪畫,在這種情況下,您可以使用CreateIC來取得一個「信息內容」的句柄,其參數與CreateDC函數相同,例如:

hdc = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ;

您不能用這個信息內容句柄往設備上寫東西。

 


 

使用位圖時,取得一個「內存設備內容」有時是有用的:

hdcMem = CreateCompatibleDC (hdc) ;
        
//其它行程序
        
DeleteDC (hdcMem) ;

您可以將位圖選進內存設備內容,然後使用GDI函數在位圖上繪畫。


 

前面已經提到過,metafile是一些GDI呼叫的集合,以二進制形式編碼。您可以通過取得metafile設備內容來建立metafile:

hdcMeta = CreateMetaFile (pszFilename) ;
        
//其它行程序
        
hmf 
= CloseMetaFile (hdcMeta) ;

在metafile設備內容有效期間,任何用hdcMeta所做的GDI呼叫都變成metafile的一部分而不會顯示。在呼叫CloseMetaFile之後,設備內容句柄變爲無效,函數傳回一個指向metafile(hmf)的句柄。

 


 

設備內容句柄信息的取得

設備內容信息可以通過

iValue = GetDeviceCaps (hdc, iIndex) ;

這個函數取得,和前面的SYSTEM程序裏面那個函數一樣iLndex也是一個告訴程序要返回怎麼的整數。例如,iIndex爲HORZRES時將使GetDeviceCaps傳回設備的寬度(單位爲圖素);iIndex爲VERTRES時將讓GetDeviceCaps傳回設備的高度(單位爲圖素)。

下面這個連接裏面就是那個示例程序,我用SYSTEM進行了改裝,就可以顯示我們需要的內容了。

http://dl2.csdn.net/down4/20070715/15154745822.rar

設備的大小

假定要繪製邊長爲1英寸的正方形,您(程序寫作者)或Windows(操作系統)需要知道視訊顯示上1英寸對應多少圖素。使用GetDeviceCaps函數能取得有關如視訊顯示器和打印機之類輸出設備的實際顯示大小信息。

Windows應用程序可以使用SM_CXSCREEN和SM_CYSCREEN參數從GetSystemMetrics得到圖素尺寸。從DEVCAPS1程序中您會注意到,程序可以用HORZRES(水平分辨率)和VERTRES參數從GetDeviceCaps中得到同樣的值。這裏「分辨率」指的是圖素大小而不是每度量單位的圖素數。

這些是設備大小的簡單部分,現在開始複雜的部分。

前兩個設備能力,HORZSIZE和VERTSIZE,文件中稱爲「以毫米計的實際屏幕的寬度」及「以毫米計的實際屏幕的高度」(在/Platform SDK/Graphics和Multimedia Services/GDI/Device Contexts/Device Context Reference/Device Context Functions/GetDeviceCaps中)。

在Windows的16位版本中(及在Windows NT中),Windows爲HORZSIZE和VERTSIZE使用「標準」的顯示大小。然而,從Windows 95開始,HORZSIZE和VERTSIZE值是從HORZRES、VERTRES、LOGPIXELSX和LOGPIXELSY值中衍生出來的。這是它的工作方式。

當您在「控制檯」中使用「顯示器」程序選擇顯示的圖素大小時,也可以選擇系統字體的大小。這個選項的原因是用於640×480顯示的字體在提升到1024×768或更大時字太小,而您可能想要更大的系統字體。這些系統字體大小指「顯示器」程序的「設定」頁面卷標中的「小字體」和「大字體」。所以:當您在「控制檯」的「顯示」程序上選擇小字體或大字體時,實際上是選擇了一個假定的視訊顯示分辨率,單位是每英寸的點數

在Windows程序中,您可以使用GetDeviceCaps函數取得使用者在「控制檯」的「顯示器」程序中選擇的以每英寸的點數爲單位的假定分辨率。要得到這些值(如果視訊顯示器不具有正方形圖素,在理論上這些值是不同的),可以使用索引LOGPIXELSX和LOGPIXELSY。LOGPIXELS指邏輯圖素,它的基本意思是「以每英寸的圖素數爲單位的非實際分辨率」。

用HORZSIZE和VERTSIZE索引從GetDeviceCaps得到的設備能力,在文件上稱爲「實際屏幕的寬度,單位毫米」及「實際屏幕的高度,單位毫米」。因爲這些值是從HORZRES、VERTRES、LOGPIXELSX和LOGPIXELSY值中衍生出來的,所以它們應該稱爲「邏輯寬度」和「邏輯高度」。公式是:

水平大小=25.4*水平像素/每英寸的點數
豎直大小=25.4*豎直像素/每英寸的點數

所以一般來說,程序返回的“真實大小”其實是不真實的,真正可以的方法是讓用戶自己填入顯示器的大小。

關於色彩

這一節書上說的內容基本是針對以前的,和我們關係不太大,爲了實用的角度,就不說了,直接記錄怎麼設定顏色。

我們知道一般的顏色是使用紅(RED)綠(GREEN)藍(BLUE)三種顏色組成的,而一般的每個顏色可以用一個32位的數字表示,就是0-255。或者可以用2個16進制數表示。

在大多數GDI函數呼叫中,使用COLORREF值(只是一個32位的無正負號長整數)來表示一種色彩。COLORREF值按照紅、綠和藍色的亮度指定了一種顏色,通常叫做「RGB色彩」 。

這個無正負號長整數常常稱爲一個「RGB色彩」。Windows表頭文件WINGDI.H提供了幾種使用RGB色彩值的宏。RGB宏要求三個參數分別代表紅、綠和藍值,然後將它們組合爲一個無正負號長整數:

#define RGB(r,g,b) ((COLORREF)(((BYTE)(r) | 
        
                   ((WORD)((BYTE)(g)) 
<< 8)) | 
        
                   (((DWORD)(BYTE)(b)) 
<< 16)))

就是說你可以用像這樣的函數取得白色:RGB(255,255,255)。GetRValue、GetGValue和GetBValue宏從COLORREF值中抽取出原色值。當您在使用傳回RGB色彩值的Windows函數時,這些宏有時會很方便。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章