【正文】
第 3講 Windows的圖形設(shè)備接口及 windows繪圖 Windows圖形設(shè)備接口 (GDI)是為與 設(shè)備無關(guān) 的圖形設(shè)計的。所謂設(shè)備的無關(guān)性,就是操作系統(tǒng)屏蔽了硬件設(shè)備的差異,因而設(shè)備無關(guān)性能使用戶編程時無需考慮特殊的硬件設(shè)置 一、圖形設(shè)備按口 (GDI) GDI負(fù)責(zé)系統(tǒng)與用戶或繪圖程序之間的信息交換,并控制在輸出設(shè)備上 顯示圖形 或 文字 , 是 Windows系統(tǒng)的重要組成部分 Windows 支持與設(shè)備無關(guān)的圖形 利用 GDI和Windows設(shè)備驅(qū)動程序 開發(fā)人員只要建 立與輸出設(shè)備的 關(guān)聯(lián),讓系統(tǒng)加 載相應(yīng)的設(shè)備驅(qū) 動程序即可 1. GDI的一些基本概念 設(shè)備描述表 即為 設(shè)備環(huán)境 的屬性的集合 應(yīng)用程序 與輸出設(shè)備 之間的橋梁 Win系統(tǒng) 外設(shè) 直接訪問 不允許 統(tǒng)一的設(shè)備環(huán)境 (DC) 提供 使應(yīng)用程序與設(shè)備相連 用戶 為確保圖形輸出 的設(shè)備無關(guān)性 應(yīng)用程序 設(shè)備描述表及其屬性 應(yīng)用程序每一次圖形操作均參照設(shè)備描述表中的屬性執(zhí)行 圖形刷新 是繪圖過程中必須考慮的重要問題 刷新請求 對刷新請求的響應(yīng) 刷新方法 包括 (1) 刷新請求 應(yīng)用程序在窗口中 繪制了一個橢圓, 顏色列表框覆蓋了 橢圓的一部分 關(guān)閉顏色選框后, 應(yīng)用程序需要恢 復(fù)被覆蓋部分的顏色和形狀 窗口大小的調(diào)整 窗口移動 被覆蓋后的恢復(fù) (2) 系統(tǒng)對刷新請求的響應(yīng) 當(dāng)用戶區(qū)的內(nèi)容需要刷新時,系統(tǒng)向應(yīng)用程序消息隊列發(fā)送 WM_PAINT消息,系統(tǒng)在應(yīng)用程序的消息隊列中加入該消息,以通知窗口函數(shù)執(zhí)行刷新處理 三種 刷新 窗口移動后的刷新 被覆蓋區(qū)域的刷新 對象穿越后的刷新 (系統(tǒng)自動完成 ) 用戶區(qū)移動或顯示 用戶窗口大小改變 程序通過滾動條滾動窗口 窗口被另一個窗口覆蓋的 恢復(fù)如下拉式菜單關(guān)閉等 光標(biāo)穿過用戶區(qū) 圖標(biāo)拖過用戶區(qū) 窗口被另一個窗口覆蓋的區(qū)域稱為 無效區(qū)域 。 Windows系統(tǒng)為每個窗口建立了一個 PAINTSTRUCT結(jié)構(gòu) , 該結(jié)構(gòu)中包含了包圍 無效區(qū)域 的一個最小矩形的結(jié)構(gòu) RECT, 應(yīng)用程序可以根據(jù)這個無效矩形執(zhí)行刷新操作。 typedef struct tagPAINTSTRUCT { HDC hdc。 //設(shè)備環(huán)境句柄 BOOL fErase。 //一般取真值,表示擦除無效矩形的背景 RECT rcPaint。 //無效矩形標(biāo)識 BOOL fRestore。 //系統(tǒng)保留 BOOL fIncUpdate。 //系統(tǒng)保留 BYTE rgbReserved[32]; //系統(tǒng)保留 }PAINTSTRUCT。 rcPaint 為標(biāo)準(zhǔn)的 RECT數(shù)據(jù)結(jié)構(gòu),其作用是標(biāo)識無效矩形,它包含了無效矩形的左上角和右下角的坐標(biāo) 常用的 Windows應(yīng)用程序刷新窗口的方法 保存副本。刷新時將副本拷貝到相應(yīng)的窗口中 記錄事件。刷新時重新執(zhí)行這個曾經(jīng)發(fā)生的事件 重新繪制。將圖形繪制處理程序放在消息WM_PAINT響應(yīng)模塊中,刷新時重繪圖形 (3) 有效的刷新方法 3. 獲取設(shè)備環(huán)境的方法 獲取設(shè)備環(huán)境是應(yīng)用程序輸出圖形的先決條件,常用的兩種方法是調(diào)用函數(shù) BeginPaint或 GetDC (1) 調(diào)用 BeginPaint函數(shù) 應(yīng)用程序響應(yīng) WM_PAINT消息進(jìn)行圖形刷新時,主要通過調(diào)用BeginPaint函數(shù)獲取設(shè)備環(huán)境 hdc=BeginPaint(hwnd,amp。ps); //ps為 PAINTSTRUCT類型結(jié)構(gòu) 定義方式為: PAINTSTRUCT ps。 系統(tǒng)獲取設(shè)備環(huán)境的 同時填寫 ps結(jié)構(gòu),以 標(biāo)識無效矩形區(qū) 由 BeginPaint函數(shù)獲取的設(shè)備環(huán)境要用 EndPaint函數(shù)釋放 BOOL EndPaint(HWND hwnd, PAINTSTRUCT amp。ps) (2) 調(diào)用 GetDC函數(shù) 如果繪圖工作并非由 WM_PAINT消息驅(qū)動,則調(diào)用 GetDC函數(shù)獲取設(shè)備環(huán)境。 hdc=GetDC(hwnd)。 由 GetDC函數(shù)獲取的設(shè)備環(huán)境必須用 ReleaseDC函數(shù)釋放 void ReleaseDC(HWND hwnd)。 B e g in P a in t 與 G e t D C 的區(qū)別項目 函數(shù) B e g i n P a i n t 函數(shù) G e tD c 函數(shù)使用環(huán)境只用于圖形刷新時獲取設(shè)備環(huán)境使用較為廣泛操作區(qū)域使用 B e g i n P a i n t 函數(shù)獲取設(shè)備環(huán)境后,操作區(qū)域為無效區(qū)域使用 G e tD C 函數(shù)獲取設(shè)備環(huán)境后,操作區(qū)域為整個用戶區(qū)釋 放設(shè) 備環(huán)境所用函數(shù)由 E n d P a i n t 函數(shù)釋放由 R e l e a s e D C 函數(shù)釋放4. 映像模式 映像模式定義了將邏輯單位轉(zhuǎn)化為設(shè)備的度量單位以及設(shè)備的 x方向和 y方向,程序員可在一個統(tǒng)一的邏輯坐標(biāo)系中操作而不必考慮輸出設(shè)備的坐標(biāo)系情況 窗口 :對應(yīng)邏輯坐標(biāo)系上程序員設(shè)定的區(qū)域 視口 :對應(yīng)實際輸出設(shè)備上程序員設(shè)定的區(qū)域 窗口和視口 如何映射? 映像模式將一個邏輯單位映射為坐標(biāo)系設(shè)定M M _ A N I S O T R O P I C 系統(tǒng)確定 O p ti o n a lM M _ H I E N G L I S H 0 . 0 0 1 英寸 Y 上, X 右M M _ H I M E T R I C 0 . 0 1 毫米 Y 上, X 右M M _ I S O T R O P I C 系統(tǒng)確定O p ti o n a l ,但 x軸和 y 軸的單位此例為 1 : 1M M _ L O E N G L I S H 0 . 0 1 英寸 Y 上, X 右M M _ L O M E T R I C 0 . 1 毫米 Y 上, X 右M M _ T E X T 一個像素 Y 下, X 右M M _ T W I P S 1 / 1 4 4 0 英寸 Y 上, X 右缺省的映射模式 將窗口中的對稱圖形映射到視口時仍為對稱圖形 按照窗口和視口的坐標(biāo)比例進(jìn)行映射 坐標(biāo)系統(tǒng) 邏輯坐標(biāo)系統(tǒng) 設(shè)備坐標(biāo)系統(tǒng) 屏幕坐標(biāo)系統(tǒng) 窗口坐標(biāo)系統(tǒng) 用戶區(qū)坐標(biāo)系統(tǒng) 應(yīng)用程序可獲取設(shè)備環(huán)境的當(dāng)前映像模式,并根據(jù)需要設(shè)置映像模式。 相關(guān) 函數(shù) 設(shè)置設(shè)備環(huán)境的映像模式 SetMapMode(hdc,nMapMode)。 nMapMode為映像模式的整型標(biāo)識符 獲取當(dāng)前設(shè)備環(huán)境的映像模式 nMapMode=GetMapMode(hdc)。 窗口 區(qū)域的定義由 SetWindowExtEx函數(shù)完成,其函數(shù)原型形為 :BOOL SetWindowExtEx ( HDC hdc, int nHeight,nWidth, //以 邏輯 單位表示的窗口區(qū)域高寬度 LPSIZE lpSize, //函數(shù)調(diào)用前窗口區(qū)域尺寸的 SIZE結(jié)構(gòu)地址 )。 視口 區(qū)域的定義由 SetViewportExtEx函數(shù)完成,函數(shù)原型為: BOOL SetViewportExtEx ( HDC hdc, int nHeight,nWidth,//以 物理 設(shè)備單位表示的新視口區(qū)域高寬度 LPSIZE lpSize )。 只有在映射模式為 MM_ANISOTROPIC 和 MM_ISOTROPIC 時才有意義 視口 的缺省原點和 窗口 的缺省原點均為( 0, 0)。可通過調(diào)用函數(shù)SetViewportOrgEx和 SetWindowOrgEx設(shè)定窗口與視口的原點。 SetWindowOrgEx函數(shù)的原形為 : BOOL SetWindowOrgEx ( HDC hdc, int X,Y, //以 邏輯 單位表示的窗口原點坐標(biāo) LPPOINT lpPoint //函數(shù)調(diào)用前原點坐標(biāo)的 POINT結(jié)構(gòu)的地址 )。 只有在映射模式為 MM_ANISOTROPIC 和 MM_ISOTROPIC 時才有意義 二、繪圖工具與顏色 1. 畫筆 (1) 畫筆的創(chuàng)建 使用畫筆之前必須事先定義一個畫筆句柄。形式如下 : HPEN hP。 然后調(diào)用函數(shù) GetStockObject獲取 Windows系統(tǒng)定義的 四種 畫筆例如獲取畫筆 BLACK_PEN的形式如下 : hP=GetStockObject( BLACK_PEN) 。 WHITE_PEN BLACK_PEN DC_PEN NULL_PEN 畫筆的操作 創(chuàng)建畫筆 將畫筆選入設(shè)備環(huán)境 刪除畫筆 (2) 創(chuàng)建 新 畫筆,形式如下 : hP=CreatePen ( int nPenStyle, //確定 畫筆樣式 int nWidth, //畫筆寬度 COLORREF rgbColor //畫筆顏色