第四部分的圖形設(shè)備接口及繪圖_第1頁
第四部分的圖形設(shè)備接口及繪圖_第2頁
第四部分的圖形設(shè)備接口及繪圖_第3頁
第四部分的圖形設(shè)備接口及繪圖_第4頁
第四部分的圖形設(shè)備接口及繪圖_第5頁
已閱讀5頁,還剩92頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第四部分的圖形設(shè)備接口及繪圖第一頁,共九十七頁,編輯于2023年,星期一1圖形設(shè)備接口(GDI)大多數(shù)應(yīng)用程序都需要在客戶區(qū)繪制一些圖形,如繪制文本、幾何圖形、位圖和光標(biāo)等Windows是一個圖形操作系統(tǒng),其所有的圖形可視化效果都是通過繪制操作而完成的圖形顯示的實質(zhì)就是利用Windows提供的圖形設(shè)備接口(GraphicsDeviceInterface,GDI)將圖形繪制在顯示器上,在Windows中向屏幕或打印機上繪圖時,需要調(diào)用GDI函數(shù)第二頁,共九十七頁,編輯于2023年,星期一1圖形設(shè)備接口(GDI)GDI作為Windows所提供的一個抽象接口,它負(fù)責(zé)管理用戶繪圖操作時功能的轉(zhuǎn)換,用戶通過調(diào)用GDI函數(shù)與設(shè)備打交道,GDI通過不同設(shè)備提供的驅(qū)動程序?qū)⒗L圖語句轉(zhuǎn)換為對應(yīng)的繪圖指令,避免了直接對硬件進(jìn)行操作,從而實現(xiàn)所謂的設(shè)備無關(guān)性GDI管理Windows應(yīng)用程序圖形的繪制,在應(yīng)用程序中,通過調(diào)用GDI函數(shù)繪制不同尺寸、顏色、風(fēng)格的幾何圖形、文本和位圖。這些圖形處理函數(shù)組成了圖形設(shè)備接口GDI第三頁,共九十七頁,編輯于2023年,星期一1.1設(shè)備無關(guān)性Windows繪圖過程和設(shè)備無關(guān)性的實現(xiàn)GDI處于設(shè)備驅(qū)動程序的上一層,當(dāng)程序調(diào)用繪圖函數(shù)時,GDI將繪圖命令傳送給當(dāng)前設(shè)備的驅(qū)動程序,以調(diào)用驅(qū)動程序提供的接口函數(shù)驅(qū)動程序的接口函數(shù)將Windows繪圖命令轉(zhuǎn)化為設(shè)備能夠執(zhí)行的輸出命令,實現(xiàn)圖形的繪制。不同設(shè)備具有不同的驅(qū)動程序,設(shè)備驅(qū)動程序是設(shè)備相關(guān)的第四頁,共九十七頁,編輯于2023年,星期一2設(shè)備環(huán)境(DeviceContex,DC)應(yīng)用程序與輸出設(shè)備之間的橋梁Win系統(tǒng)外設(shè)直接訪問不允許統(tǒng)一的設(shè)備環(huán)境(DC)提供使應(yīng)用程序與設(shè)備相連用戶為確保圖形輸出的設(shè)備無關(guān)性第五頁,共九十七頁,編輯于2023年,星期一2設(shè)備環(huán)境(DeviceContex,DC)設(shè)備環(huán)境也稱設(shè)備描述表或設(shè)備上下文,它是由Windows管理的一個數(shù)據(jù)結(jié)構(gòu),用來確定GDI輸出的位置和形象的屬性集合,如背景、調(diào)色板、字體、刷子等,它保存了繪圖操作中一些共同需要設(shè)置的信息,如當(dāng)前的畫筆、畫刷、字體和位圖等圖形對象及其屬性,以及顏色和背景等影響圖形輸出的繪圖模式形象地說,一個設(shè)備環(huán)境提供了一張畫布和一些繪畫的工具,我們可以使用不同顏色的工具在上面繪制點、線、圓和文本第六頁,共九十七頁,編輯于2023年,星期一2設(shè)備環(huán)境(DeviceContex,DC)設(shè)備環(huán)境中的“設(shè)備”是指任何類型的顯示器或打印機等輸出設(shè)備,繪圖時用戶不用關(guān)心所使用設(shè)備的編程原理和方法;所有的繪制操作必須通過設(shè)備環(huán)境進(jìn)行間接的處理,Windows自動將設(shè)備環(huán)境所描述的結(jié)構(gòu)映射到相應(yīng)的物理設(shè)備上從根本上來說,設(shè)備環(huán)境DC是一個Windows數(shù)據(jù)結(jié)構(gòu),該結(jié)構(gòu)存儲著程序向設(shè)備輸出時所需要的信息,應(yīng)用程序利用它定義圖形對象及其屬性,并實現(xiàn)應(yīng)用程序、設(shè)備驅(qū)動程序和輸出設(shè)備之間繪圖命令的轉(zhuǎn)換在Windows中不使用DC無法進(jìn)行輸出,在使用任何GDI繪圖函數(shù)之前,必須建立一個設(shè)備環(huán)境第七頁,共九十七頁,編輯于2023年,星期一2.1MFC設(shè)備環(huán)境類CDC在VisualC++中,MFC將設(shè)備描述符(DC)和圖形設(shè)備接口(GDI)都封裝在CDC類中CDC類既包含了有關(guān)設(shè)備的屬性,同時又包含了繪圖方法;CDC類既作為其它MFC設(shè)備環(huán)境類的基類,又可以作為一個一般的設(shè)備環(huán)境類使用利用它可以訪問設(shè)備屬性和設(shè)置繪圖屬性。CDC類對GDI的所有繪圖函數(shù)進(jìn)行了封裝第八頁,共九十七頁,編輯于2023年,星期一2.1MFC設(shè)備環(huán)境類CDC在MFC應(yīng)用程序中,一般情況下,很多繪圖操作都是在視類的OnDraw()成員函數(shù)中進(jìn)行OnDraw()函數(shù)參數(shù)中自動有一個CDC的指針pDC,利用pDC調(diào)用CDC類的成員函數(shù)完成繪圖操作另外,當(dāng)用戶需要立即繪制圖像時,可以通過調(diào)用更新窗口函數(shù)Invalidate()使Windows送出WM_PAINT消息自動調(diào)用OnDraw()函數(shù)來重繪圖形第九頁,共九十七頁,編輯于2023年,星期一2.1MFC設(shè)備環(huán)境類CDCMFC的DC類包括CDC類、CPaintDC類、CClientDC類、CWindowDC類和CMetaFileDC類等,其中CDC類是MFC設(shè)備環(huán)境類的基類,其它的MFC設(shè)備環(huán)境類都是CDC的派生類第十頁,共九十七頁,編輯于2023年,星期一2.1.1CDC類的派生類CPaintDC類是OnPaint()函數(shù)使用的設(shè)備環(huán)境類,它代表一個窗口的繪圖畫面。如果添加WM_PAINT消息處理函數(shù)OnPaint(),就需要使用CPaintDC類來定義一個設(shè)備環(huán)境對象CClientDC類代表了客戶區(qū)設(shè)備環(huán)境當(dāng)在客戶區(qū)實時繪圖時,需要利用CClientDC類定義一個客戶區(qū)設(shè)備環(huán)境CWindowDC類代表了整個程序窗口設(shè)備環(huán)境,可以在整個窗口區(qū)域繪圖第十一頁,共九十七頁,編輯于2023年,星期一2.2獲取設(shè)備環(huán)境DC的方法在程序中不能直接存取DC數(shù)據(jù)結(jié)構(gòu),只能通過系統(tǒng)提供的一系列函數(shù)或使用設(shè)備環(huán)境的句柄HDC來間接地獲取或設(shè)置設(shè)備環(huán)境結(jié)構(gòu)中的各項屬性,如顯示器高度和寬度、支持的顏色數(shù)及分辨率等獲取DC的方法獲取DC的一般方法MFC中獲取設(shè)備環(huán)境DC的方法第十二頁,共九十七頁,編輯于2023年,星期一2.2.1獲取DC的一般方法如果采用SDK(SoftwareDevelopmentKit,“軟件開發(fā)工具包”,即開發(fā)Windows平臺下的應(yīng)用程序所使用的SDK)方法編程,獲取DC的方法有兩種:在WM_PAINT消息處理函數(shù)中通過調(diào)用API函數(shù)BeginPaint()獲取設(shè)備環(huán)境,在消息處理函數(shù)返回前調(diào)用API函數(shù)EndPaint()釋放設(shè)備環(huán)境在其他函數(shù)中通過調(diào)用API函數(shù)GetDC()獲取設(shè)備環(huán)境,調(diào)用API函數(shù)ReleaseDC()釋放設(shè)備環(huán)境第十三頁,共九十七頁,編輯于2023年,星期一2.2.2MFC中獲取設(shè)備環(huán)境DC的方法如果采用MFC方法編程,MFC提供了不同類型的DC類,每一個類都封裝了DC句柄,并且它們的構(gòu)造函數(shù)自動調(diào)用獲取DC的API函數(shù),析構(gòu)函數(shù)自動調(diào)用釋放DC的API函數(shù)因此,在程序中通過聲明一個MFC設(shè)備環(huán)境類的對象就自動獲取了一個DC,而當(dāng)該對象被銷毀時就自動釋放了獲取的DC。MFCAppWizard應(yīng)用程序向?qū)?chuàng)建的OnDraw()函數(shù)自動支持所獲取的DC第十四頁,共九十七頁,編輯于2023年,星期一2.3GDI坐標(biāo)系和映射模式Windows坐標(biāo)系分為邏輯坐標(biāo)系和設(shè)備坐標(biāo)系兩種,GDI支持這兩種坐標(biāo)系。一般而言,GDI的文本和圖形輸出函數(shù)使用邏輯坐標(biāo),而在客戶區(qū)移動或按下鼠標(biāo)的鼠標(biāo)位置是采用設(shè)備坐標(biāo)邏輯坐標(biāo)系是面向DC的坐標(biāo)系,這種坐標(biāo)不考慮具體的設(shè)備類型,在繪圖時,Windows會根據(jù)當(dāng)前設(shè)置的映射模式將邏輯坐標(biāo)轉(zhuǎn)換為設(shè)備坐標(biāo)設(shè)備坐標(biāo)系是面向物理設(shè)備的坐標(biāo)系,這種坐標(biāo)以像素或設(shè)備所能表示的最小長度單位為單位,X軸方向向右,Y軸方向向下。設(shè)備坐標(biāo)系的原點位置(0,0)不限定在設(shè)備顯示區(qū)域的左上角第十五頁,共九十七頁,編輯于2023年,星期一屏幕坐標(biāo)系、窗口坐標(biāo)系和客戶區(qū)坐標(biāo)系設(shè)備坐標(biāo)系分為屏幕坐標(biāo)系、窗口坐標(biāo)系和客戶區(qū)坐標(biāo)系三種相互獨立的坐標(biāo)系屏幕坐標(biāo)系以屏幕左上角為原點,一些與整個屏幕有關(guān)的函數(shù)均采用屏幕坐標(biāo),如GetCursorPos()、SetCursorPos()、CreateWindow()、MoveWindow();彈出式菜單使用的也是屏幕坐標(biāo)第十六頁,共九十七頁,編輯于2023年,星期一屏幕坐標(biāo)系、窗口坐標(biāo)系和客戶區(qū)坐標(biāo)系窗口坐標(biāo)系以窗口左上角為坐標(biāo)原點,它包括窗口標(biāo)題欄、菜單欄和工具欄等范圍客戶區(qū)坐標(biāo)系以窗口客戶區(qū)左上角為原點,主要用于客戶區(qū)的繪圖輸出和窗口消息的處理。鼠標(biāo)消息的坐標(biāo)參數(shù)使用客戶區(qū)坐標(biāo),CDC類繪圖成員函數(shù)使用與客戶區(qū)坐標(biāo)對應(yīng)的邏輯坐標(biāo)第十七頁,共九十七頁,編輯于2023年,星期一坐標(biāo)之間的相互轉(zhuǎn)換編程時,有時需要根據(jù)當(dāng)前的具體情況進(jìn)行三種設(shè)備坐標(biāo)之間或與邏輯坐標(biāo)的相互轉(zhuǎn)換MFC提供了兩個函數(shù)CWnd::ScreenToClient()和CWnd::ClientToScreen()用于屏幕坐標(biāo)與客戶區(qū)坐標(biāo)的相互轉(zhuǎn)換MFC提供了兩個函數(shù)CDC::DPtoLP()和CDC::LPtoDP()用于設(shè)備坐標(biāo)與邏輯坐標(biāo)之間的相互轉(zhuǎn)換第十八頁,共九十七頁,編輯于2023年,星期一例:設(shè)備坐標(biāo)與邏輯坐標(biāo)之間的轉(zhuǎn)換例:設(shè)備坐標(biāo)轉(zhuǎn)換為邏輯坐標(biāo)Windows鼠標(biāo)位置使用設(shè)備坐標(biāo)系,以客戶區(qū)窗口原點作為基準(zhǔn),而在OnDraw()函數(shù)中使用邏輯坐標(biāo)。因此,為了在滾動視圖中重繪圖形,必須在存儲線段起點和終點之前將其坐標(biāo)轉(zhuǎn)換為邏輯坐標(biāo)。實質(zhì)上,OnDraw()函數(shù)由OnPaint()函數(shù)調(diào)用,在調(diào)用OnDraw()函數(shù)前,OnPaint()函數(shù)已經(jīng)調(diào)用了函數(shù)OnPrepareDC()對設(shè)備環(huán)境進(jìn)行了調(diào)整打開應(yīng)用程序項目MyDraw,修改單擊鼠標(biāo)和鼠標(biāo)移動的消息處理函數(shù)第十九頁,共九十七頁,編輯于2023年,星期一例:設(shè)備坐標(biāo)與邏輯坐標(biāo)之間的轉(zhuǎn)換voidCMyDrawView::OnLButtonDown(UINTnFlags,CPointpoint){ //TODO:Addyourmessagehandlercodehere...

CClientDCdc(this);

OnPrepareDC(&dc);

//調(diào)整設(shè)備環(huán)境的屬性

dc.DPtoLP(&point);

//將設(shè)備坐標(biāo)轉(zhuǎn)換為邏輯坐標(biāo)

SetCapture();//捕捉鼠標(biāo) ::SetCursor(m_hCross);//設(shè)置十字光標(biāo)

m_ptOrigin=point; m_bDragging=TRUE;//設(shè)置拖拽標(biāo)記

//CScrollView::OnLButtonDown(nFlags,point);}第二十頁,共九十七頁,編輯于2023年,星期一例:設(shè)備坐標(biāo)與邏輯坐標(biāo)之間的轉(zhuǎn)換voidCMyDrawView::OnMouseMove(UINTnFlags,CPointpoint){ if(m_bDragging) { CClientDCdc(this); OnPrepareDC(&dc); dc.DPtoLP(&point); dc.MoveTo(this->m_ptOrigin); dc.LineTo(point); m_ptOrigin=point; } //CView::OnMouseMove(nFlags,point);}第二十一頁,共九十七頁,編輯于2023年,星期一例:設(shè)備坐標(biāo)與邏輯坐標(biāo)之間的轉(zhuǎn)換voidCMyDraw2View::OnLButtonUp(UINTnFlags,CPointpoint){ //TODO:在此添加消息處理程序代碼和或調(diào)用默認(rèn)值

m_bDragging=false; ReleaseCapture(); //CView::OnLButtonUp(nFlags,point);}第二十二頁,共九十七頁,編輯于2023年,星期一映射模式映射模式確定了在繪制圖形時所依據(jù)的坐標(biāo)系,它定義了邏輯單位的實際大小、坐標(biāo)增長方向,所有映射模式的坐標(biāo)原點均在設(shè)備輸出區(qū)域(如客戶區(qū)或打印區(qū))的左上角。此外,對于某些映射模式,用戶還可以自定義窗口的長度和寬度,設(shè)置視圖區(qū)的物理范圍Windows定義了8種映射模式:MM_TEXT、MM_LOMETRIC、MM_HIMETRIC、MM_LOENGLISH、MM_HIENGLISH、MM_TWIPS、MM_ISOTROPIC、MM_ANISOTROPIC映射模式使得程序員可不必考慮輸出設(shè)備的具體設(shè)備坐標(biāo)系,而在一個統(tǒng)一的邏輯坐標(biāo)系中進(jìn)行圖形的繪制第二十三頁,共九十七頁,編輯于2023年,星期一Windows映射模式映射模式邏輯單位坐標(biāo)系設(shè)定MM_TEXT一個像素X軸正方向朝右,Y軸正方向朝下MM_LOMETRIC0.1毫米X軸正方向朝右,Y軸正方向朝上MM_HIMETRIC0.01毫米X軸正方向朝右,Y軸正方向朝上MM_LOENGLISH0.01英寸X軸正方向朝右,Y軸正方向朝上MM_HIENGLISH0.001英寸X軸正方向朝右,Y軸正方向朝上MM_TWIPS1/1440英寸X軸正方向朝右,Y軸正方向朝上MM_ISOTROPIC系統(tǒng)確定X、Y軸可任意調(diào)節(jié),X、Y軸比例為1:1MM_ANISOTROPIC系統(tǒng)確定X、Y軸可任意調(diào)節(jié),X、Y軸比例任意第二十四頁,共九十七頁,編輯于2023年,星期一設(shè)置原點的坐標(biāo)CDC::SetWindowOrg()Setwindoworiginas(x,y)設(shè)置設(shè)備環(huán)境的窗口原點的坐標(biāo),窗口是對應(yīng)于邏輯坐標(biāo)系(設(shè)備環(huán)境)由用戶設(shè)定的一個區(qū)域CDC::SetViewportOrg()Setwindoworiginto(x,y)重新設(shè)置設(shè)備的視口原點的坐標(biāo),視口是對應(yīng)于設(shè)備坐標(biāo)系(實際輸出設(shè)備)由用戶設(shè)定的一個區(qū)域由于SetViewportOrg的參數(shù)是設(shè)備坐標(biāo),與邏輯坐標(biāo)無關(guān),所以當(dāng)它移動坐標(biāo)軸時與上一次的坐標(biāo)軸的位置無關(guān)第二十五頁,共九十七頁,編輯于2023年,星期一設(shè)置原點的坐標(biāo)窗口原點是指邏輯窗口坐標(biāo)系的原點在視口(設(shè)備)坐標(biāo)系中的位置,視口原點是指設(shè)備實際輸出區(qū)域的原點除了映射模式,窗口和視口也是決定一個點的邏輯坐標(biāo)如何轉(zhuǎn)換為設(shè)備坐標(biāo)的一個因素。一個點的邏輯坐標(biāo)按照如下式子轉(zhuǎn)換為設(shè)備坐標(biāo):

設(shè)備(視口)坐標(biāo)=邏輯坐標(biāo)–窗口原點坐標(biāo) +視口原點坐標(biāo)第二十六頁,共九十七頁,編輯于2023年,星期一例:設(shè)置原點的坐標(biāo)分別在OnDraw()函數(shù)中添加如下代碼,設(shè)置不同的窗口原點和視口原點,結(jié)果有什么不同?pDC->SetMapMode(MM_TEXT); pDC->Rectangle(CRect(50,50,100,100)); //直接基于屏幕繪制pDC->SetMapMode(MM_TEXT); pDC->SetWindowOrg(50,50);//屏幕左上角的坐標(biāo)設(shè)置為(50,50) pDC->Rectangle(CRect(50,50,100,100));pDC->SetMapMode(MM_TEXT); pDC->SetViewportOrg(50,50);//當(dāng)前原點位置移動到(50,50)的位置 pDC->Rectangle(CRect(50,50,100,100));pDC->SetMapMode(MM_TEXT); pDC->SetViewportOrg(50,50);//當(dāng)前原點位置移動到(50,50)的位置 pDC->SetWindowOrg(50,50);//當(dāng)前的原點坐標(biāo)設(shè)置為(50,50) pDC->Rectangle(CRect(50,50,100,100));第二十七頁,共九十七頁,編輯于2023年,星期一例:設(shè)置原點的坐標(biāo)第二十八頁,共九十七頁,編輯于2023年,星期一2.4顏色的設(shè)置Windows用COLORREF類型的數(shù)據(jù)存放顏色,它是一個32位整數(shù)。任何一種顏色都是由紅、綠、藍(lán)三種基本顏色組成,COLORREF類型數(shù)據(jù)的低位字節(jié)存放紅色強度值,第2個字節(jié)存放綠色強度值,第3個字節(jié)存放藍(lán)色強度值,高位字節(jié)為0,每一種顏色分量的取值范圍為0到255直接設(shè)置COLORREF數(shù)據(jù)不太方便,Windows提供了RGB宏用于設(shè)置顏色,將其中的紅、綠、藍(lán)分量值轉(zhuǎn)換為COLORREF類型的顏色數(shù)據(jù):

RGB(byRed,byGreen,byBlue)

其中參數(shù)byRed、byGreen和byBlue分別表示紅、綠、藍(lán)分量值(范圍0到255)第二十九頁,共九十七頁,編輯于2023年,星期一RGB宏的使用很多涉及到顏色的GDI函數(shù)都需要使用COLORREF類型的參數(shù),如設(shè)置背景色的成員函數(shù)CDC::SetBkColor()、設(shè)置文本顏色的成員函數(shù)CDC::SetTextColor()。例如: COLORREFrgbBkClr=RGB(192,192,192); //定義灰色 pDC->SetBkCorlor(rgbBkClr); //背景色為灰色 pDC->SetTextColor(RGB(0,0,255)); //文本顏色為蘭色第三十頁,共九十七頁,編輯于2023年,星期一標(biāo)準(zhǔn)彩色的RGB值顏色RGB分量值顏色RGB分量值淺紅255,0,0深紅128,0,0淺綠0,255,0深綠0,128,0淺藍(lán)0,0,255深藍(lán)0,0,128淺黃255,255,0深黃128,128,0淺青0,255,255深青0,128,128紫色255,0,255灰色192,192,192白色255,255,255黑色0,0,0第三十一頁,共九十七頁,編輯于2023年,星期一3畫筆和畫刷在默認(rèn)狀態(tài)下,當(dāng)用戶創(chuàng)建一個設(shè)備環(huán)境并在其中繪圖時,系統(tǒng)使用設(shè)備環(huán)境缺省的繪圖工具及其屬性。如果要使用不同風(fēng)格和顏色的繪圖工具進(jìn)行繪圖,用戶必須重新為設(shè)備環(huán)境設(shè)置自定義的畫筆和畫刷等繪圖工具畫筆和畫刷是Windows中兩種最重要的繪圖工具,畫筆用于繪制點、線、矩形和橢圓等幾何圖形,畫刷用指定的顏色和圖案來填充繪圖區(qū)域,這些繪圖工具又統(tǒng)稱為GDI對象第三十二頁,共九十七頁,編輯于2023年,星期一3.1GDI對象WindowsGDI提供了一些繪圖對象,程序通過這些GDI對象設(shè)置繪圖的工具和風(fēng)格,這里的對象是指Windows數(shù)據(jù)結(jié)構(gòu),而不是C++類的對象GDI對象是Windows圖形設(shè)備接口的抽象繪圖工具。除了畫筆和畫刷,其它GDI對象還包括字體、位圖和調(diào)色板。MFC對GDI對象進(jìn)行了很好的封裝,提供了封裝GDI對象的類,如CPen、CBrush、CFont、CBitmap和CPalette等,這些類都是GDI對象類CGdiObject的派生類第三十三頁,共九十七頁,編輯于2023年,星期一選擇一個GDI對象CDC類提供了成員函數(shù)SelectObject()選擇用戶自己創(chuàng)建的GDI對象,該函數(shù)有多種重載形式,可以選擇用戶已定制好的畫筆、畫刷、字體和位圖等不同類型的GDI對象e.g.

CPen*SelectObject(CPen*pPen); CBrush*SelectObject(CBrush*pBrush); virtualCFont*SelectObject(CFont*pFont); CBitmap*SelectObject(CBitmap*pBitmap);

函數(shù)參數(shù)是一個指向用戶已定制好的GDI對象的指針

選擇操作成功函數(shù)將返回以前GDI對象的指針,否則返回NULL第三十四頁,共九十七頁,編輯于2023年,星期一3.2使用畫筆當(dāng)用戶創(chuàng)建一個用于繪圖的設(shè)備環(huán)境時,該設(shè)備環(huán)境自動提供了一個寬度為一個像素單位、風(fēng)格為實黑線(BLACK_PEN)的缺省畫筆。如果要在設(shè)備環(huán)境使用自己的畫筆繪圖,首先需要創(chuàng)建一個指定風(fēng)格的畫筆,然后將創(chuàng)建的畫筆選入設(shè)備環(huán)境,最后,在使用該畫筆繪圖結(jié)束后需要釋放該畫筆創(chuàng)建畫筆

創(chuàng)建畫筆最簡單的方法是調(diào)用CPen類的一個帶參數(shù)的構(gòu)造函數(shù)來構(gòu)造一個CPen類畫筆對象,以下代碼創(chuàng)建了一個紅色虛線畫筆:

CPenPenNew(PS_DASH,1,RGB(255,0,0));第三十五頁,共九十七頁,編輯于2023年,星期一3.2使用畫筆創(chuàng)建畫筆的第二種方法是首先構(gòu)造一個沒有初始化的CPen類畫筆對象,然后調(diào)用成員函數(shù)CPen::CreatePen()創(chuàng)建定制的畫筆工具

CPenPenNew; PenNew.CreatePen(PS_DASH,1,RGB(255,0,0));函數(shù)CreatePen()的參數(shù)類型與帶參數(shù)的CPen類構(gòu)造函數(shù)完全一樣。當(dāng)畫筆對象的聲明與創(chuàng)建不在同一個地方時(如需要多次改變畫筆)只有采用這種方法樣式說明樣式說明PS_SOLID實線PS_DASHDOTDOT雙點劃線PS_DOT點線PS_NULL空的邊框PS_DASH虛線PS_INSIDEFRAME邊框?qū)嵕€PS_DASHDOT點劃線

第三十六頁,共九十七頁,編輯于2023年,星期一選擇創(chuàng)建的畫筆創(chuàng)建畫筆后必須調(diào)用成員函數(shù)CDC::SelectObject()將創(chuàng)建的畫筆選入當(dāng)前設(shè)備環(huán)境。如果選擇成功,函數(shù)SelectObject()將返回以前畫筆對象的指針。選擇新的畫筆時應(yīng)該保存以前的畫筆對象,如下代碼所示:CPen*pPenOldpPenOld=pDC->SelectObject(&PenNew);第三十七頁,共九十七頁,編輯于2023年,星期一還原畫筆創(chuàng)建和選擇畫筆工具后,應(yīng)用程序就可以使用該畫筆繪圖。當(dāng)繪圖完成后,應(yīng)該通過調(diào)用成員函數(shù)CDC::SelectObject()恢復(fù)設(shè)備環(huán)境以前的畫筆工具,并通過調(diào)用成員函數(shù)CGdiObject::DeleteObject()釋放GDI對象所占的內(nèi)存資源,如下代碼所示:pDC->SelectObject(pPenOld);

//恢復(fù)設(shè)備環(huán)境DC中原來的畫筆PenNew.DeleteObject();

//刪除底層的GDI對象第三十八頁,共九十七頁,編輯于2023年,星期一實例:使用畫筆編寫一個SDI應(yīng)用程序,繪制不同風(fēng)格、寬度和顏色的直線在OnDraw()函數(shù)中添加如下所示的代碼:

CPen*pPenOld,PenNew; intnPenStyle[]={ PS_SOLID, //實線

PS_DOT, //點線

PS_DASH, //虛線

PS_DASHDOT, //點劃線

PS_DASHDOTDOT, //雙點劃線

PS_NULL, //空的邊框

PS_INSIDEFRAME, //邊框?qū)嵕€

}; char*strStyle[]={"Solid","Dot","Dash","DashDot", "DashDotDot","Null","InsideFrame"}; pDC->TextOut(60,10,“用不同樣式的畫筆繪圖”);第三十九頁,共九十七頁,編輯于2023年,星期一實例:使用畫筆(續(xù)1)for(inti=0;i<7;i++){

//用不同樣式的畫筆繪圖

if(PenNew.CreatePen(nPenStyle[i],1,RGB(0,0,0))){

//創(chuàng)建畫筆

pPenOld=pDC->SelectObject(&PenNew);

//選擇畫筆

pDC->TextOut(10,30+20*i,strStyle[i]); pDC->MoveTo(100,40+20*i); pDC->LineTo(200,40+20*i);

pDC->SelectObject(pPenOld);

//恢復(fù)原來的畫筆

PenNew.DeleteObject();

//刪除底層的GDI對象}else{ MessageBox("不能創(chuàng)建畫筆!");}}第四十頁,共九十七頁,編輯于2023年,星期一實例:使用畫筆(續(xù)2)char*strWidth[]={"1","2","3","4","5","6","7"};pDC->TextOut(260,10,"用不同寬度的畫筆繪圖");for(i=0;i<7;i++){//用不同寬度的畫筆繪圖if(PenNew.CreatePen(PS_SOLID,i+1,RGB(0,0,0))){//創(chuàng)建畫筆

pPenOld=pDC->SelectObject(&PenNew);//選擇畫筆

pDC->TextOut(260,30+20*i,strWidth[i]); pDC->MoveTo(300,40+20*i); pDC->LineTo(400,40+20*i);

pDC->SelectObject(pPenOld);

//恢復(fù)原來的畫筆

PenNew.DeleteObject();

//刪除底層的GDI對象}else{ MessageBox("不能創(chuàng)建畫筆!");}}第四十一頁,共九十七頁,編輯于2023年,星期一實例:使用畫筆(續(xù)3)

char*strColor[]={"紅","綠","藍(lán)","黃","紫","青","灰"};COLORREFrgbPenClr[]={RGB(255,0,0),RGB(0,255,0), RGB(0,0,255),RGB(255,255,0),RGB(255,0,255), RGB(0,255,255),RGB(192,192,192)};pDC->TextOut(460,10,"用不同顏色的畫筆繪圖");for(i=0;i<7;i++){

//用不同顏色的畫筆繪圖

CPen*pPenNew=newCPen(PS_SOLID,2,rgbPenClr[i]);

//創(chuàng)建畫筆的另一種方法

pPenOld=pDC->SelectObject(pPenNew);//選擇創(chuàng)建的畫筆

pDC->TextOut(460,30+20*i,strColor[i]); pDC->MoveTo(500,40+20*i); pDC->LineTo(600,40+20*i);

pDC->SelectObject(pPenOld);//恢復(fù)原來的畫筆

deletepPenNew;//自動刪除底層的GDI對象}}第四十二頁,共九十七頁,編輯于2023年,星期一實例:使用畫筆(續(xù)4)第四十三頁,共九十七頁,編輯于2023年,星期一3.3使用畫刷當(dāng)創(chuàng)建一個設(shè)備環(huán)境時,該設(shè)備環(huán)境自動提供了一個填充色為白色(WHITE_BRUSH)的缺省畫刷。與畫筆一樣,也可以利用MFC畫刷類CBrush創(chuàng)建自己的畫刷,用于填充圖形的繪制畫刷有三種基本類型:純色畫刷、陰影畫刷和圖案畫刷,CBrush類提供了多個不同重載形式的構(gòu)造函數(shù)。以下創(chuàng)建三種不同類型的畫刷:

CBrushbrush1(RGB(255,0,0)); //創(chuàng)建純色畫刷 CBrushbrush2(HS_DIAGCROSS,RGB(0,255,0)); //創(chuàng)建陰影畫刷 CBrushbrush3(&bmp); //創(chuàng)建圖案畫刷第四十四頁,共九十七頁,編輯于2023年,星期一3.3使用畫刷創(chuàng)建畫刷也可先構(gòu)造一個沒有初始化的CBrush類畫刷對象,然后調(diào)用CBrush類的初始化成員函數(shù)創(chuàng)建定制的畫刷工具。CBrush類提供的常用創(chuàng)建函數(shù)有:CreateSolidBrush()用指定的顏色創(chuàng)建一個純色畫刷;CreateHatchBrush()用指定的陰影樣式和顏色創(chuàng)建一個陰影畫刷;CreatePatternBrush()用位圖創(chuàng)建一個圖案畫刷;CreateSysColorBrush()用系統(tǒng)默認(rèn)顏色創(chuàng)建一個指定陰影樣式的畫刷如下代碼創(chuàng)建了一個填充色為紅色、圖案為垂直相交陰影線的畫刷:

CBrushBrushNew; BrushNew.CreateHatchBrush(HS_CROSS,RGB(255,0,0));第四十五頁,共九十七頁,編輯于2023年,星期一實例:使用畫刷編寫一個對話框應(yīng)用程序,并重新設(shè)置對話框的背景色(1)建立一個基于對話框的應(yīng)用程序UseBrush,為對話框類CUseBrushDlg添加一個CBrush類型的成員變量m_BrushBkClr。在對話框初始化成員函數(shù)OnInitDialog()中創(chuàng)建一個自定義顏色的畫刷。

BOOLCUseBrushDlg::OnInitDialog() { ...... //TODO:Addextrainitializationhere m_BrushBkClr.CreateSolidBrush(RGB(0,0,255)); //創(chuàng)建一個藍(lán)色畫刷

returnTRUE;//returnTRUEunlessyousetthefocus... }第四十六頁,共九十七頁,編輯于2023年,星期一實例:使用畫刷(續(xù)1)(2)利用ClassWzard為對話框類CUseBrushDlg添加WM_CTLCOLOR的消息處理函數(shù),返回用戶自己創(chuàng)建的畫刷m_BrushBkClrHBRUSHCUseBrushDlg::OnCtlColor(CDC*pDC, CWnd*pWnd,UINTnCtlColor){ //HBRUSHhbr=CDialog::OnCtlColor(pDC,pWnd, nCtlColor);//不使用缺省的畫刷 //TODO:Returnadifferentbrushifthedefault... returnm_BrushBkClr;}第四十七頁,共九十七頁,編輯于2023年,星期一實例:使用畫刷(續(xù)1)第四十八頁,共九十七頁,編輯于2023年,星期一3.4使用GDI堆對象Windows預(yù)定義了一些簡單風(fēng)格的GDI對象,用戶使用這些GDI對象時,無需自己創(chuàng)建它們,可以直接將它們選入當(dāng)前的設(shè)備環(huán)境,這些GDI對象稱作為堆(Stock)對象。堆對象包括堆畫筆、堆畫刷和堆字體等通過調(diào)用成員函數(shù)CDC::SelectStockObject()可以選擇一個堆對象繪圖工具,以下代碼將堆畫筆和堆畫刷作為當(dāng)前的繪圖工具:

pPenOld=(CPen*)pDC->SelectStockObject(NULL_PEN); //使用堆畫筆對象 pBrhOld=(CBrush*)pDC->SelectStockObject(LTGRAY_BRUSH); //使用堆畫刷對象第四十九頁,共九十七頁,編輯于2023年,星期一堆畫筆、畫刷的樣式及說明樣式說明樣式說明BLACK_PEN黑色畫筆WHITE_PEN白色畫筆NULL_PEN空畫筆BLACK_BRUSH黑色畫刷WHITE_BRUSH白色畫刷NULL_BRUSH空畫刷GRAY_BRUSH灰色畫刷DKGRAY_BRUSH深灰色畫刷LTGRAY_BRUSH淺灰色畫刷HOLLOW_BRUSH虛畫刷第五十頁,共九十七頁,編輯于2023年,星期一3.4使用GDI堆對象也可以利用CGdiObject::CreateStockObject()將GDI對象設(shè)置成指定的堆對象,這時需要首先聲明一個GDI對象,最后還需要調(diào)用函數(shù)SelectObject()將與堆對象關(guān)聯(lián)的GDI對象選入當(dāng)前的設(shè)備環(huán)境,如下代碼所示:

CBrush*pBrhOld,BrhNew; BrhNew.CreateStockObject(LTGRAY_BRUSH); //設(shè)置堆畫刷對象 pBrhOld=pDC->SelectObject(&BrhNew);第五十一頁,共九十七頁,編輯于2023年,星期一實例:使用GDI堆對象編寫一個SDI應(yīng)用程序,使用堆畫筆和堆畫刷繪制圖形利用MFCAppWizard向?qū)?chuàng)建一個SDI應(yīng)用程序UseStock,利用ClassWizard為類CUseStockView添加WM_PAINT消息處理函數(shù)OnPaint(): voidCUseStockView::OnPaint() { CPaintDCdc(this);//devicecontextforpainting //TODO:Addyourmessagehandlercodehere CPen*pPenOld,PenNew; CBrush*pBrhOld,BrhNew; pPenOld=(CPen*)dc.SelectStockObject(BLACK_PEN); //使用堆畫筆對象

pBrhOld=(CBrush*)dc.SelectStockObject(GRAY_BRUSH); //使用堆畫刷對象

dc.Rectangle(100,100,300,300);第五十二頁,共九十七頁,編輯于2023年,星期一實例:使用GDI堆對象(續(xù)1)PenNew.CreateStockObject(NULL_PEN);

//NULL_PEN用于繪制無邊界的填充圖形dc.SelectObject(&PenNew);BrhNew.CreateStockObject(LTGRAY_BRUSH);dc.SelectObject(&BrhNew);dc.Ellipse(400,100,600,200);dc.SelectObject(pPenOld);//恢復(fù)系統(tǒng)默認(rèn)的GDI對象dc.SelectObject(pBrhOld);dc.Ellipse(400,210,600,310); //DonotcallCView::OnPaint()forpaintingmessages}第五十三頁,共九十七頁,編輯于2023年,星期一實例:使用GDI堆對象(續(xù)2)第五十四頁,共九十七頁,編輯于2023年,星期一3.5繪制基本圖形生成設(shè)備環(huán)境、設(shè)置繪圖屬性和選擇繪圖工具后,就可以開始繪制不同形狀的幾何圖形,Windows中可以繪制的基本幾何圖形包括點、直線、曲線、矩形、橢圓、弧、扇形、弦形和多邊形等GDI為提供了繪制基本圖形的成員函數(shù),這些函數(shù)封裝在MFC的CDC類中繪圖函數(shù)使用的坐標(biāo)都是邏輯坐標(biāo)第五十五頁,共九十七頁,編輯于2023年,星期一函

數(shù)功

能SetPixel用指定的顏色在指定的坐標(biāo)畫一個點MoveTo移動當(dāng)前位置到指定的坐標(biāo),函數(shù)返回以前位置的坐標(biāo)。LineTo從當(dāng)前位置到指定位置畫一條直線Polyline從當(dāng)前位置開始,根據(jù)函數(shù)參數(shù)繪制多條折線。PolyBezier根據(jù)兩個端點和兩個控制點繪制貝濟埃(Bezier)曲線。Rectangle根據(jù)指定的左上角和右下角坐標(biāo)繪制一個矩形RoundRect繪制一個圓角矩形。Ellipse根據(jù)指定的矩形繪制一個內(nèi)切橢圓Arc根據(jù)指定的矩形繪制內(nèi)切橢圓上的一段弧邊ArcTo該函數(shù)功能與Arc函數(shù)相同,不同之處在于畫弧成功后Pie繪制扇形Chord繪制弦形,弦形是一條橢圓弧和其對應(yīng)的弦所組成的封閉圖形。Polygon根據(jù)兩個或兩個以上頂點繪制一個多邊形DrawIcon在指定位置畫一個圖標(biāo),如果成功函數(shù)返回非0,否則返回0。第五十六頁,共九十七頁,編輯于2023年,星期一實例:繪制基本圖形編寫一個繪圖程序,利用上表中的成員函數(shù)繪制幾種常見的幾何圖形利用MFCAppWizard建立一個SDI應(yīng)用程序,在OnDraw()函數(shù)中添加如下程序代碼:

voidCMyGraphView::OnDraw(CDC*pDC) { CMyGraphDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); //TODO:adddrawcodefornativedatahere for(intxPos=20;xPos<100;xPos+=10) pDC->SetPixel(xPos,30,RGB(0,0,0));//繪制像素點

POINTpolylpt[5]={{10,100},{50,60},{120,80},{80,150},{30,130}}; pDC->Polyline(polylpt,5);//繪制五條折線第五十七頁,共九十七頁,編輯于2023年,星期一實例:繪制基本圖形(續(xù)1)POINTpolybpt[4]={{150,160},{220,60},{300,180},{330,20}};pDC->PolyBezier(polybpt,4);//繪制貝濟埃曲線

CBrush*pBrhOld;pBrhOld=(CBrush*)pDC->SelectStockObject( LTGRAY_BRUSH); //使用淺灰色堆畫刷

pDC->RoundRect(400,30,550,100,20,20); //繪制圓角矩形

pDC->Arc(20,200,200,300,200,250,20,200); //繪制橢圓弧

pDC->Pie(220,200,400,380,380,270,240,220); //繪制扇形

pDC->Chord(420,120,540,240,520,160,420,180);//繪制弦形

POINTpolygpt[5]={{450,200},{530,220},{560,300}, {480,320},{430,280}};pDC->Polygon(polygpt,5); //繪制五邊形

pDC->SelectObject(pBrhOld); //恢復(fù)系統(tǒng)默認(rèn)的畫刷}第五十八頁,共九十七頁,編輯于2023年,星期一實例:繪制基本圖形(續(xù)2)第五十九頁,共九十七頁,編輯于2023年,星期一4文本與字體很多Windows應(yīng)用程序都需要顯示文本,并且,文本還是一些應(yīng)用程序的主要處理對象,如MSWord字處理軟件文本與字體密切相關(guān),輸出文本時選擇不同類型的字體在很大程度上影響程序的界面風(fēng)格,合適的字體可以增強程序的感染力。因此,對軟件用戶來說,文本輸出也是很重要的Windows為文本的顯示提供了多種物理字體支持,而在程序中我們可以創(chuàng)建不同風(fēng)格的邏輯字體來輸出文本第六十頁,共九十七頁,編輯于2023年,星期一4.1繪制文本以圖形方式進(jìn)行文本的輸出是Windows操作系統(tǒng)一個特性,文本輸出實際上是按照指定的字體樣式將文本中的每個字符繪制出來Windows圖形設(shè)備接口GDI提供了很多有關(guān)文本輸出的函數(shù),MFC的CDC類對這些GDI文本輸出函數(shù)進(jìn)行了封裝編程時最常用的文本輸出函數(shù)是TextOut()函數(shù),該函數(shù)只能輸出單行文本。要繪制多行文本可以調(diào)用DrawText()函數(shù),另一個函數(shù)ExtTextOut()可以用一個矩形框?qū)敵鑫谋敬M(jìn)行裁剪第六十一頁,共九十七頁,編輯于2023年,星期一4.1繪制文本在缺省情況下繪制文本時,字體顏色是黑色,背景顏色是白色,背景模式為不透明模式。可以通過調(diào)用CDC類成員函數(shù)重新設(shè)置字體顏色、背景顏色和文本對齊方式等文本屬性SetTextColor()設(shè)置顯示文本的顏色GetTextColor獲得當(dāng)前文本的顏色SetBkColor()設(shè)置顯示文本的背景顏色GetBkColor()獲得當(dāng)前文本的背景顏色SetBkMode()設(shè)置文本的背景模式GetBkMode()獲得當(dāng)前文本的背景模式SetTextAlign()設(shè)置顯示文本的對齊方式GetTextAlign()獲得當(dāng)前文本的對齊方式第六十二頁,共九十七頁,編輯于2023年,星期一4.2字體概述文本與字體密切相關(guān),輸出文本的大小和外觀是由字體描述的。字體是指采用某種字樣的一套字符和符號,每一種字體都有字符集決定字體的三個要素是字樣、風(fēng)格和大小。字樣是字母的樣式和文本的視覺外觀,字體的風(fēng)格是字體的粗細(xì)和傾斜度。Windows支持光柵字體、矢量字體和TrueType三種字體。光柵字體即點陣字體,這種字體需要為每一種大小的字體創(chuàng)建獨立的字體文件矢量字體以一系列線段存儲字符TrueType字體是與設(shè)備無關(guān)的字體,字符以輪廓的形式存儲,包括線段和曲線第六十三頁,共九十七頁,編輯于2023年,星期一4.2字體概述TrueType字體正成為真正的主流,這種字體能夠以一種非常出色的字體技術(shù)繪制文本。TrueType字體能夠縮放為任何大小的字體,而不會降低圖形的質(zhì)量。Windows中提供的TrueType字體主要有Arial、Courier、Symbol、TimeNewRoman等,可以通過Windows“控制面板|字體”瀏覽系統(tǒng)已安裝的字體。輸出文本時,默認(rèn)情況下使用系統(tǒng)提供的缺省字體,如果需要可以改變顯示文本的字體。與畫筆和畫刷一樣,字體也是一種GDI對象,MFC類CFont對GDI字體對象進(jìn)行了封裝,我們一般利用CFont類創(chuàng)建自己的字體(GDI對象),然后把創(chuàng)建的字體選入設(shè)備環(huán)境,以用于在設(shè)備環(huán)境中繪制文本第六十四頁,共九十七頁,編輯于2023年,星期一選擇堆字體除了選擇任意尺寸TrueType字體,也可以選擇固定尺寸的系統(tǒng)字體(堆字體)。當(dāng)選擇堆字體作為文本輸出的字體時,無需創(chuàng)建字體對象,只需簡單地調(diào)用成員函數(shù)CDC::SelectStockObject()將堆字體對象選入設(shè)備環(huán)境Windows提供了以下六種堆字體對象:

(1)ANSI_FIXED_FONT(2)ANSI_VAR_FONT

(3)SYSTEM_FONT (4)SYSTEM_FIXED_FONT

(5)DEVICE_DEFAULT_FONT(6)OEM_FIXED_FONT例如:

pDC->SelectStockObject(ANSI_FIXED_FONT);第六十五頁,共九十七頁,編輯于2023年,星期一TEXTMETRIC結(jié)構(gòu)輸出文本時,Windows使用一個矩形框以位圖的方式繪制出每一個字符的形狀。文本的顯示是以像素為單位,有時需要精確地知道文本的詳細(xì)屬性,如高度、寬度等編程時我們可以通過訪問TEXTMETRIC結(jié)構(gòu)來獲取顯示器關(guān)于文本字符的屬性信息,因為每一種物理字體的信息由數(shù)據(jù)結(jié)構(gòu)TEXTMETRIC描述。調(diào)用函數(shù)CDC::GetTextMetrics()可得到當(dāng)前字體的TEXTMETRIC結(jié)構(gòu)第六十六頁,共九十七頁,編輯于2023年,星期一4.3創(chuàng)建字體Windows本身提供了豐富的字體,直接選用其中的字體就能滿足一般需要。也可以根據(jù)Windows提供的字體創(chuàng)建自己的字體,但利用CFont類創(chuàng)建自定義字體并不是創(chuàng)建一種新的物理字體,而是創(chuàng)建一種邏輯字體。邏輯字體是一種抽象的字體描述,是用與設(shè)備無關(guān)的方式來描述一個字體。邏輯字體只定義了字體的一般特征,如高度、寬度、旋轉(zhuǎn)角度、黑體、斜體及下劃線等宏觀特性,它并沒有描述字體詳細(xì)的微觀特性,也沒有生成對應(yīng)的字庫文件第六十七頁,共九十七頁,編輯于2023年,星期一4.3創(chuàng)建字體值得注意的是,有時不知道機器上是否安裝了需要的字體,因此,程序運行時顯示文本的字體可能并不是你想要的字體。實際上,在程序中創(chuàng)建一種字體并不是真正創(chuàng)建一種完全滿足程序要求的字體,而是僅尋找匹配的Windows字體并與之相關(guān)聯(lián)當(dāng)利用CFont類創(chuàng)建邏輯字體并利用成員函數(shù)CDC::SelectObject()將它選入設(shè)備環(huán)境時,GDI字體映射器根據(jù)邏輯字體給出的特性,從現(xiàn)有的物理字體中選擇與之最匹配的物理字體,這就是所謂的字體實現(xiàn)(Fontrealization)第六十八頁,共九十七頁,編輯于2023年,星期一創(chuàng)建字體的方法使用成員函數(shù)CFont::CreatPointFont()使用成員函數(shù)CFont::CreateFontIndirect()使用成員函數(shù)CFont::CreateFont()第六十九頁,共九十七頁,編輯于2023年,星期一實例:創(chuàng)建字體CClientDCdc(this);CFontfntZdy,*pfntOld;VERIFY(fntZdy.CreatePointFont(200,"Arial",&dc));pfntOld=dc.SelectObject(&fntZdy);//選入設(shè)備環(huán)境dc.TextOut(100,100,"Hello!Thisis20PtArialFont.");dc.SelectObject(pfntOld); //恢復(fù)原來字體fntZdy.DeleteObject(); //刪除自定義字體第七十頁,共九十七頁,編輯于2023年,星期一使用CreateFontIndirect()函數(shù)和LOGFONT結(jié)構(gòu)CFontfont;LOGFONTLogFnt;memset(&LogFnt,0,sizeof(LOGFONT)); //清零結(jié)構(gòu)LogFontLogFnt.lfHeight=22; //字體高度為22像素strcpy(LogFnt.lfFaceName,"Courier"); //匹配字體為CourierVERIFY(font.CreateFontIndirect(&LogFnt)); //創(chuàng)建字體CClientDCdc(this);CFont*def_font=dc.SelectObject(&font); //選入設(shè)備環(huán)境dc.TextOut(100,130,"Hello!Thisis22-pixel-heightCourierFont.");dc.SelectObject(def_font);font.DeleteObject();第七十一頁,共九十七頁,編輯于2023年,星期一實例:創(chuàng)建字體(自己編寫)編寫一個文本輸出程序UseFont,采用不同方法創(chuàng)建字體,并根據(jù)創(chuàng)建的字體輸出不同的文本串第七十二頁,共九十七頁,編輯于2023年,星期一公用字體對話框Windows還提供了一個公用字體對話框,很多程序都利用它來選擇不同的字體,并可以設(shè)置字體的大小和顏色。公用字體對話框?qū)?yīng)的MFC類是類CFontDialog,編程時可以通過訪問CFontDialog類的有關(guān)成員變量或調(diào)用成員函數(shù)獲得用戶所選擇的字體及其屬性,程序員無須具體定義這種字體就可以通過調(diào)用函數(shù)CreateFontIndirect()創(chuàng)建字體第七十三頁,共九十七頁,編輯于2023年,星期一實例:公用字體對話框(自己編寫)編寫一個單文檔應(yīng)用程序FontDlg,當(dāng)執(zhí)行菜單命令“字體”時,使用公用字體對話框動態(tài)設(shè)置字體第七十四頁,共九十七頁,編輯于2023年,星期一5位圖、圖標(biāo)和光標(biāo)使用圖象形式的標(biāo)志可以使用戶很快地找到某個程序或了解一個程序的大致功能,因此在Windows環(huán)境中大量使用各種圖形圖像標(biāo)志。Windows應(yīng)用程序中主要使用位圖、圖標(biāo)和光標(biāo)等幾種圖形資源利用VisualC++集成開發(fā)環(huán)境中的資源編輯器可以創(chuàng)建或編輯這幾種圖形資源,在程序中需要時可以通過編寫源代碼使用創(chuàng)建的圖形資源第七十五頁,共九十七頁,編輯于2023年,星期一5.1位圖位圖是一個由位構(gòu)成的圖象,它是由一系列數(shù)據(jù)排列而成的點陣結(jié)構(gòu),這些數(shù)據(jù)分別表示各點的顏色信息。Windows支持兩種不同形式的位圖:設(shè)備相關(guān)位圖DDB(DeviceDependentBitmap)和設(shè)備無關(guān)位圖DIB(DeviceIndependentBitmap)DDB又稱GDI位圖,它是某種顯示設(shè)備的內(nèi)部表示。DDB是針對某個設(shè)備創(chuàng)建的位圖,顯示它依賴具體硬件的調(diào)色板DIB是不依賴硬件的位圖,它包含了創(chuàng)建DIB位圖時所在設(shè)備的顏色格式、分辨率和調(diào)色板等信息。DIB位圖通常以BMP文件形式保存在磁盤中,或者以資源形式存在于EXE或DLL執(zhí)行文件中第七十六頁,共九十七頁,編輯于2023年,星期一MFC處理位圖的方法MFC只提供了處理DDB位圖的類CBitmap,要顯示DIB位圖,可以先將一個DIB位圖轉(zhuǎn)換為DDB位圖。類CBitmap提供了一個成員函數(shù),用于從程序的資源中裝載位圖,并可以將基于資源的DIB位圖轉(zhuǎn)換成GDI位圖,該函數(shù)聲明如下:

BOOLLoadBitmap(LPCTSTRpszResourceName);

BOOLLoadBitmap(UINTnIDResource);其中參數(shù)lpszResourceName或nIDResource分別為資源名稱或資源標(biāo)識,載入成功返回值為真,否則返回值為假第七十七頁,共九十七頁,編輯于2023年,星期一顯示位圖的編程方法位圖在顯示之前必須先裝入內(nèi)存,當(dāng)駐留在內(nèi)存的位圖數(shù)據(jù)送到視頻內(nèi)存時,位圖就在顯示器上顯示。顯示一個DDB位圖步驟:

(1)調(diào)用CDC::CreateCompatibleDC()創(chuàng)建一個兼容的內(nèi)存設(shè)備環(huán)境;

(2)調(diào)用CBitmap::LoadBitmap()裝入位圖資源或調(diào)用CBitmap::CreateCompatibleBitmap()創(chuàng)建一個與內(nèi)存設(shè)備環(huán)境兼容的位圖;

(3)調(diào)用CDC::SelectObject()將位圖選入設(shè)備環(huán)境;

(4)調(diào)用CDC::BitBlt()或CDC::StretchBlt()將位圖從內(nèi)存設(shè)備環(huán)境中復(fù)制到指定設(shè)備如顯示器第七十八頁,共九十七頁,編輯于2023年,星期一實例:位圖編程編寫程序MyBMP,程序運行后在客戶區(qū)顯示一幅位圖利用向?qū)?chuàng)建一個SDI應(yīng)用程序MyBMP。執(zhí)行菜單命令I(lǐng)nsert|Resource插入一個Bitmap資源。利用資源編輯器對位圖進(jìn)行編輯,并將其ID改為IDB_MYBITMAP。在函數(shù)OnDraw()中添加代碼:

voidCMyBMPView::OnDraw(CDC*pDC) { CMyBMPDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); //TODO:adddrawcodefornativedatahere CDCMemDC; MemDC.CreateCompatibleDC(pDC);//創(chuàng)建內(nèi)存設(shè)備環(huán)境第七十九頁,共九十七頁,編輯于2023年,星期一實例:位圖編程(續(xù)1)CBitmapBitmap;Bitmap.LoadBitmap(IDB_MYBITMAP);//裝入位圖資源CBitmap*pOldBitmap=MemDC.SelectObject(&Bitmap); //將位圖對象選入設(shè)備環(huán)境

BITMAPbm;Bitmap.GetObject(sizeof(BITMAP),&bm);//讀取位圖信息//將內(nèi)存中的位圖復(fù)制到屏幕上

pDC->BitBlt(0,0,bm.bmWidth,bm.bmHeight,&MemDC, 0,0,SRCCOPY);MemDC.SelectObject(pOldBitmap);//恢復(fù)原來位圖對象}第八十頁,共九十七頁,編輯于2023年,星期一實例:位圖編程(續(xù)2)第八十一頁,共九十七頁,編輯于2023年,星期一5.2圖標(biāo)在Windows中,每個文件都有一個圖標(biāo)(Icon)。應(yīng)用程序圖標(biāo)通常會出現(xiàn)在程序標(biāo)題欄的左上角、Windows底部的任務(wù)欄、資源管理器窗口和Windows桌面上。圖標(biāo)實質(zhì)上是特殊形式的位圖,但圖標(biāo)與位圖有兩個不同之處。首先,圖標(biāo)大小尺寸只能有三種,一種是用于標(biāo)題欄和最小化時的16×16圖標(biāo),另外兩種是用于桌面、資源管理器的32×32和48×48圖標(biāo)。其次,設(shè)計圖標(biāo)時可以指定像素的顏色為屏幕顏色或屏幕反轉(zhuǎn)色,如圖所示。這樣,Windows在顯示圖標(biāo)時,采用屏幕顏色的像素位置顏色不變,該位置圖標(biāo)部分看起來是透明的,而屏幕反轉(zhuǎn)色部分在任何彩色背景下都能顯示第八十二頁,共九十七頁,編輯于2023年,星期一第八十三頁,共九十七頁,編輯于2023年,星期一添加自己的圖標(biāo)一般應(yīng)用程序使用MFC提供的缺省圖標(biāo),也可以添加自己的圖標(biāo)。通過Insert|Resource菜單命令插入Icon圖標(biāo)資源,利用圖形資源編輯器編輯圖標(biāo)。圖標(biāo)創(chuàng)建后通過調(diào)用函數(shù)CWinApp::LoadIcon()加載圖標(biāo)并獲得其句柄,該函數(shù)原型為:

HICONLoadIcon(LPCTSTRlpszResourceName)const;HICONLoadIcon(UINTnIDResource)const;對于圖標(biāo),MFC沒有提供對應(yīng)的類,編程時只有采用句柄的方式使用一個圖標(biāo)用戶也可以通過調(diào)用CWinApp::LoadStandardIcon()加載Windows系統(tǒng)提供的預(yù)定義圖標(biāo)第八十四頁,共九十七頁,編輯于2023年,星期一顯示圖標(biāo)圖標(biāo)被加載后,為了在窗口顯示圖標(biāo),可以調(diào)用成員函數(shù)CDC::DrawIcon(),該函數(shù)原型為:

BOOLDrawIcon(intx,inty,HICONhIcon); BOOLDrawIcon(POINTpoint,HICONhIcon); 其中,參數(shù)x、y或point指定圖標(biāo)顯示的左上角坐標(biāo),hIcon為圖標(biāo)句柄。在初始化函數(shù)InitInstance()中可以通過調(diào)用成員函數(shù)CWnd::SetIcon()安裝圖標(biāo),此時應(yīng)該同時安裝16×16和32×32大小標(biāo)準(zhǔn)的圖標(biāo),該函數(shù)原型為:

HICONSetIcon(HICONhIcon,BOOLbBigIcon); 其中,參數(shù)hIcon為要安裝的圖標(biāo)句柄,bBigIcon確定安裝何種大小的圖標(biāo)第八十五頁,共九十七頁,編輯于2023年,星期一實例:圖標(biāo)編寫一個應(yīng)用程序MyIcon,程序運行后在標(biāo)題欄刪除程序原來默認(rèn)的圖標(biāo),顯示自己創(chuàng)建的圖標(biāo),并在客戶區(qū)顯示該圖標(biāo)和Windows預(yù)定義圖標(biāo)

(1)利用MFCAppWizard[exe]創(chuàng)建一個SDI應(yīng)用程序MyIcon,然后執(zhí)行Insert|Resource菜單命令,要創(chuàng)建的資源選為Icon,單擊New按鈕。也可通過Import命令導(dǎo)入一個圖標(biāo)文件。打開圖形編輯器后就可以開始創(chuàng)建圖標(biāo),新創(chuàng)建圖標(biāo)的ID設(shè)為IDI_ICON1。

(2)為了在標(biāo)題欄顯示創(chuàng)建的圖標(biāo)IDI_ICON1,在初始化函數(shù)InitInstance()中添加如下代碼:

HICONhIcon=AfxGetApp()->LoadIcon(IDI_ICON1);

m_pMainWnd->SetIcon(hIcon,TRUE); //設(shè)置32×32圖標(biāo)

m_pMainWnd->SetIcon(hIcon,FALSE); //設(shè)置16×16圖標(biāo)第八十六頁,共九十七頁,編輯于2023年,星期一實例:圖標(biāo)(續(xù)1)

(3)在函數(shù)OnDraw()中使用圖標(biāo),需要編寫代碼加載和顯示圖標(biāo)。在OnDraw()函數(shù)中添加如下代碼

HICONhIcon=AfxGetApp()->LoadIcon(IDI_ICON1)

溫馨提示

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

評論

0/150

提交評論