日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

戏说 Windows GDI (1)

發(fā)布時間:2025/3/15 windows 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 戏说 Windows GDI (1) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

0.題記:

作為QT開發(fā)的支持者和踐行者,明知道MFC已經(jīng)過時,但是還不得不用;老板要求,項目組師兄弟代碼兼容Balabala~也許這就是中國式項目研發(fā)。

好啦,聊點正經(jīng)事......

1.設(shè)備描述表(Device Context,DC):通往各種輸出設(shè)備的橋梁

在單任務(wù)環(huán)境如MS-DOS中,運行中的應(yīng)用程序隨時可自由的想做他想做的事,無論是在屏幕上畫一條線,重新編寫適配器的調(diào)色板,還是轉(zhuǎn)換到另一種圖像模式。而在窗口化多任務(wù)環(huán)境如Windows中,程序則無此自由。因為程序A的輸出必須與程序B的輸出相隔離。首先,這意味著各程序的輸出必須限制在自己的窗口中。GDI(Graphic Device Inteface,GDI)使用一簡單的機(jī)制保證在窗口中畫圖的各程序遵循這些規(guī)則。這種機(jī)制即為“設(shè)備描述表”,也就是我們常說的DC。

當(dāng)Windows程序在屏幕、打印機(jī)或其他輸出設(shè)備上畫圖時,他并不是將像素直接輸出到設(shè)備上,而是將圖繪制到由設(shè)備描述表表示的邏輯意義上的“顯示平面”上去。設(shè)備描述表是深寓于Windows中的一種設(shè)備結(jié)構(gòu),它包含GDI需要的關(guān)于顯示平面情況的描述字段,包括相連的物理設(shè)備和各種各樣的狀態(tài)信息。在平面上畫圖之前,Windows程序從GDI獲取設(shè)備描述表的句柄,并且每次調(diào)出GDI輸出函數(shù)時,將句柄返回給GDI。若沒有有效的設(shè)備描述表聚丙,則GDI不會畫第一個像素。

再利用MFC編制Windows程序時,設(shè)備描述表具有更加突出的作用。除了可以作為通往各種輸出設(shè)備的橋梁之外,設(shè)備描述表對象還封裝了程序用來產(chǎn)生輸出的GDI函數(shù)。在MFC中,我們不再需要捕獲設(shè)備描述表句柄和調(diào)用GDI輸出函數(shù),至少不用直接捕獲和調(diào)用,而是通過創(chuàng)建設(shè)備描述表對象并調(diào)用它的成員函數(shù)來畫圖。

2.MFC設(shè)備描述表類

在MFC應(yīng)用程序中獲取設(shè)備描述表的一種方法是調(diào)用CWnd::GetDC(),它返回指向表示W(wǎng)indows設(shè)備描述表的CDC對象的指針。在畫圖完畢時,要用CWnd::ReleaseDC()釋放由GetDC()獲得到的設(shè)備吧、描述表的指針。具體如下面程序所示:

CDC* pdc = GetDC(); //do some drawing ReleaseDC(pdc);再這里需要我們注意的是,如果在OnPain處理程序中時,則需要Cwnd::BeginPaint和CWnd::EndPaint分別代替GetDC()和ReleaseDC(),以保證合理地處理WM_PAINT消息:

PAINTSTRUCT PS; CDC* pDC = BeginPaint( & ps ); //do some drawing EndPaint( & ps );為避免要記住獲取和釋放設(shè)備描述表時需要調(diào)用的函數(shù)(并且為了確保在使用設(shè)備描述表的消息處理程序結(jié)束時設(shè)備描述表能合理的被釋放)MFC提供了CDC派生類,具體如下:

專門用途的設(shè)備描述表類
類名描述
?CPaintDC?用于在窗口客戶區(qū)畫圖(僅限于OnPaint處理程序)
?CClientDC?用于在窗口客戶區(qū)畫圖(除了OnPaint以外的任何程序中)
?CWindowDC?用于在窗口內(nèi)任意地方畫圖,包括非客戶區(qū)
?CMetaFileDC?用于向GDI原文件畫圖

這些類在設(shè)計的時候可直接進(jìn)行實例化(類是事物的抽象封裝,對象是類的具體化)各個類的構(gòu)造函數(shù)和析構(gòu)函數(shù)調(diào)用相應(yīng)的函數(shù)捕獲和釋放設(shè)備描述表,從而使得設(shè)備描述表的使用非常方便:

CPaintDC dc(this);//該參數(shù)傳給CPaintDC的類構(gòu)造函數(shù),確定設(shè)備描述表所屬的窗口 //do some drawing當(dāng)在棧上構(gòu)造設(shè)備描述表對象時,若對象的生命周期結(jié)束,則它的析構(gòu)函數(shù)會被自動調(diào)用。而且析構(gòu)函數(shù)一旦被調(diào)用,設(shè)備描述表就會被返回給Windows。在堆上用new創(chuàng)建的設(shè)備描述表時,一定要注意親自釋放設(shè)備描述表。示例如下:

CPaintDC *pDC = new CPaintDC (this);//堆上創(chuàng)建指向CPaintDC的對象指針 delete pDC;CPaintDC類
MFC的CPaintDC類響應(yīng)WM_PAINT消息,允許在窗口客戶區(qū)畫圖。但是,需要注意。我們只能在OnPaint處理程序中使用,不能再其他別的地方應(yīng)用。WM_PAINT消息有一點與其他Windows消息都不同。如果處理程序調(diào)用Windows的::BeginPaint()和::EndPaint函數(shù)失敗,那么不管有多少繪圖工作,都不能將該消息從消息隊列中刪除。因此,應(yīng)用程序講一遍又一遍的處理同一個WM_PAINT消息,這不就陷入死循環(huán)了嗎?而通過分別從CPaintDC的構(gòu)造函數(shù)和析構(gòu)函數(shù)中調(diào)用::BeginPaint和::EndPaint,CPaintDC能保證陷入死循環(huán)這種事不發(fā)生!

CClientDC和CWindowDC類

Windows程序不是總將繪圖限制在OnPaint上,如果編寫一個應(yīng)用程序,只要以單擊鼠標(biāo)嗎,應(yīng)用程序就在屏幕上畫一個圓餅,那么我們就希望在接收到按鈕單擊消息時就立刻畫圓,而不必刻意的去等待WM_PAINT消息。這就是CClientDC存在的價值。CClientDC創(chuàng)建了可以在OnPaint外使用的用戶區(qū)域設(shè)備描述表。下面示例程序使用了CClientDC創(chuàng)建了兩個CDC成員函數(shù),來完成了在鼠標(biāo)左鍵被單擊時畫一個X鏈接串口客戶區(qū)四角的功能。

void CMainWindow::OnButtonDown( UINT nFlag, CPoint point){ CRect rect; GetClientRect( & rect );CClientDC dc(this);//傳遞當(dāng)前窗口指針 dc.MoveTo(rect.left,rect.top); dc.LineTo(rect.right,rect.bottom); dc.MoveTo(rect.right,rect.top); dc.LineTo(rect.left,rect.bottom); }如果我們不僅想使用窗口客戶區(qū),還用使用非客戶區(qū)(標(biāo)題欄,窗口邊框等),這就需要使用CWindowDC類。比如,我們想自己繪制標(biāo)題欄和帶圓角的窗口,大多數(shù)情況下CWindowDC并不常用。因為如果我們想在窗口非客戶區(qū)作圖,可以借助OnNcPaint處理程序捕捉WM_NCPAINT消息。

3.設(shè)備描述表屬性

下面總結(jié)一下設(shè)備描述表中最常用的屬性和訪問這些屬性所用的CDC函數(shù):

主要的設(shè)備描述表屬性
AttributeDefaultSet withGet with
文本顏色BlackCDC::SetTextColorCDC::GetTextColor
背景顏色WhiteCDC::SetBkColorCDC::GetBkColor
背景模式OPAQUECDC::SetBkModeCDC::GetBkMode
映射模式MM_TEXTCDC::SetMapModeCDC::GetMapMode
繪圖模式R2_COPYPENCDC::SetROP2CDC::GetROP2
當(dāng)前位置(0,0)CDC::MoveToCDC::GetCurrentPosition
當(dāng)前畫筆BLACK_PENCDC::SelectObjectCDC::SelectObject
當(dāng)前畫刷WHITECDC::SelectObject
CDC::SelectObject
當(dāng)前字體SYSTEM_FONTCDC::SelectObject
CDC::SelectObject











毫無疑問,對于Windows編程的新手來說,GDI編程中最困難的部分就是映射模式(mapping mode)。映射模式用于確定從邏輯坐標(biāo)值到設(shè)備坐標(biāo)值的轉(zhuǎn)換方式。傳送給CDC輸出函數(shù)的是邏輯坐標(biāo)值。設(shè)備坐標(biāo)值是指窗口相應(yīng)的像素點位置。調(diào)用dc.Rectangle(0,0,200,200)函數(shù)是,不知告訴GDI畫一個200個像素點寬、100個像素點高的矩形,而是告訴它畫一個200個單位寬、100個單位高的矩形。在默認(rèn)映射模式MM_TEXT下,一個像素點錢錢相當(dāng)于一個單位。

總結(jié)

以上是生活随笔為你收集整理的戏说 Windows GDI (1)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。