版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、第2章 Visual C+圖形程序設(shè)計基礎(chǔ)內(nèi)容提要Visual C+是在Microsoft C的基礎(chǔ)上發(fā)展而來的,隨著計算機軟、硬件技術(shù)的快速發(fā)展,如今Visual C+已成為集編輯、編譯、運行、調(diào)試于一體功能強大的集成編程環(huán)境。本章以Visual C+ 6.0為對象,主要介紹Visual C+集成編成環(huán)境的使用、圖形設(shè)備接口和常用圖形程序設(shè)計、鼠標編程以及菜單設(shè)計等基礎(chǔ),目的是通過對Visual C+的學習,掌握Visual C+圖形程序設(shè)計的方法,為計算機圖形學原理部分的算法實現(xiàn)提供程序工具和方法。 2.1 Visual C+ 6.0應(yīng)用程序開發(fā)方法介紹Visual C+ 6.0集成開發(fā)環(huán)
2、境,以一個簡單的實例介紹利用Visual C+應(yīng)用程序工程建立方法和程序設(shè)計框架。 2.1.1 Visual C+的集成開發(fā)環(huán)境從開始菜單中啟動Visual C+ 6.0,進入開發(fā)集成環(huán)境。打開一個項目后,可以看到Visual C+ 6.0的開發(fā)環(huán)境由標題欄、工具欄、工作區(qū)窗口、源代碼編輯窗口、輸出窗口和狀態(tài)欄組成,見圖2.1所示。 圖2.1 Visual C+ 6.0集成開發(fā)環(huán)境 標題欄菜單欄工作區(qū)源代碼編輯窗口 狀態(tài)欄 標題欄用于顯示應(yīng)用程序名和所打開的文件名,標題欄的顏色可以表明對應(yīng)窗口是否被激活。菜單欄包括文件、編輯、顯示、插入、工程、編譯、工具、窗口和幫助九項主菜單,包含了從源代碼的
3、編輯、界面設(shè)計、程序調(diào)試和編譯運行在內(nèi)的所有功能。工具欄列出了常用的菜單命令功能和對象方法。工具欄的下面是兩個窗口,一個是工作區(qū)窗口,用于列出工程中的各種對象,一個是源代碼編輯窗口,用于各個對象的程序設(shè)計。輸出窗口顯示項目建立過程中所產(chǎn)生的各種信息。屏幕底端是狀態(tài)欄,它給出當前操作或所選擇命令的提示信息。2.1.2 應(yīng)用程序工程的建立方法 Visual C+提供了一種稱為App Wizard的工具,利用該工具,用戶可以方便地按照自己的需要創(chuàng)建符合需要的應(yīng)用程序框架。在這個基礎(chǔ)上,用戶可以進一步將自己編寫的程序加入到這個框架中,實現(xiàn)用戶程序的功能。下面介紹建立VcApp應(yīng)用程序框架的方法,其它應(yīng)
4、用程序的方法都與此類似。第一步:啟動Visual C+,選擇工程方法 從開始菜單中選擇 Visual C+,進入Visual C+集成環(huán)境。從文件菜單中選擇新建(New)命令,2.1.2 應(yīng)用程序工程的建立方法 彈出圖2-2對話框。切換到工程(Projects)標簽,項目類型選擇MFC AppWizard(exe),輸入工程的名字(如VcApp),選擇項目放置的位置,然后單擊“確定”按鈕。圖2-2 Visual C+的New對話框 2.1.2 應(yīng)用程序工程的建立方法 第二步:設(shè)置應(yīng)用程序的特性。這些設(shè)置包括六個問題,每一個問題都有不同的選項供選擇。一個問題選擇完后,通過“下一步”(Next)選
5、擇下一個問題,直到六個問題選擇完畢。還可以通過“上一步”(Back)返回上一個問題重新選擇。下面繼續(xù)上面的例子,在單擊“確定”按鈕后,彈出第一個問題窗口,如圖2-3所示。第一個問題是建立什么類型的應(yīng)用程序,有三個選項:單個文檔(Single document)、多重文檔(Multiple document)和基本對話(Dialog based)。2.1.2 應(yīng)用程序工程的建立方法 單個文檔應(yīng)用程序主窗口中只有一個窗口,多重文檔可以在主窗口中開多個子窗口,基本對話主窗口是一個對話框。例中選擇單個文檔,單擊“確定”,進入下一個問題,如圖2-4所示。第二個問題是數(shù)據(jù)庫的支持,是否用ODBC存取數(shù)據(jù)庫
6、,有四個選項:不包括數(shù)據(jù)庫的支持(None)、僅包含ODBC頭文件(Header files only)、指定一個數(shù)據(jù)庫但沒有文件支持和指定一個數(shù)據(jù)庫但需要文件支持。當選擇了后兩項,則需要用戶選擇一個已經(jīng)建立的數(shù)據(jù)庫。例中不需要數(shù)據(jù)庫支持,選擇第一個選項“否”,進入第三個問題,如圖2-5所示 圖2-3 第一個問題:選擇應(yīng)用程序的類型 圖2-4 第二個問題:選擇是否要用ODBC支持 第三個問題是對ActiveX的支持。有五個選項:(1)沒有對ActiveX的支持;(2)ActiveX容器,它可以包含鏈接和嵌入對象。容器不能為其它的ActiveX程序提供支持,它只能維護嵌入對象;(3)微型服務(wù)器(
7、Mini-server),應(yīng)用程序不能獨立運行,只能被調(diào)用為其它程序建立ActiveX對象。(4)完整服務(wù)器(Full-server),它能夠獨立運行,并能夠為其它應(yīng)用程序建立ActiveX對象。(5)容器和服務(wù)器,一個應(yīng)用程序可以同時是容器和服務(wù)器。在例子中,選擇第一個選項,沒有對ActiveX的支持,單擊“下一個”(Next)進入下一個問題。 圖2-5 第三個問題:選擇是否對ActiveX的支持 第四個問題是應(yīng)用程序的特性和高級選項,如下圖 圖2-6 應(yīng)用程序的特性和高級選項 例中全部采用默認選項,進入下一個問題。第五個問題是項目的風格、原文件注釋和MFC庫類型,如圖2-7所示。在例子中全
8、部采用默認選項,進入第六個問題。第六個問題是確定類名和文件名,如圖2-8所示。 基于第一個問題到第五個問題的回答,AppWizard會把將要建立的新類的名稱通知用戶。AppWizard將為應(yīng)用程序建立四個新類,CVcAppApp是應(yīng)用程序類,它是CWinApp的派生類。CMainFrame是一個擁有應(yīng)用程序主窗口的類。CVcAppDoc和CVcAppView是該應(yīng)用程序的文檔和視圖類。這些名字用戶可以改變。最后單擊“完成”(Finish),顯示所建項目的信息,單擊“確定”后,項目建立完成。 圖2-7 項目的風格、原文件注釋和MFC庫類型 圖2-8 通知MFC產(chǎn)生的類名稱 2.1.3 輸入源程序
9、進行程序設(shè)計 應(yīng)用程序項目工程建立以后,就為應(yīng)用程序的開發(fā)建立了一個框架,這是不輸入任何程序代碼,對該項目程序進行編譯和運行,可以生成一個完整的窗口程序。用戶根據(jù)項目工程中的不同類,輸入自己設(shè)計的程序代碼,完成用戶的程序設(shè)計。例如,從VcApp Classes中找到CVcAppView的OnDraw()函數(shù),如圖2-9所示。雙擊OnDraw()函數(shù),這時系統(tǒng)會打開VcAppView.cpp文件,而且光標正置于OnDraw()函數(shù)中,在其中輸入下列語句:pDc-TextOut(30,30,”同學們好,歡迎使用VC+編程!”);編譯并運行該程序,運行結(jié)果如圖2-10所示。圖2-9 輸入程序源代碼
10、圖2-10 運行結(jié)果 2.2 圖形設(shè)備接口和圖形程序設(shè)計 2.2.1 圖形設(shè)備接口簡介 在Windows系統(tǒng)中,程序都是通過一個叫做圖形設(shè)備接口(GDI, Graphics Device Interface)的抽象接口和硬件打交道,Windows會自動將設(shè)備環(huán)境表映射到相應(yīng)的物理設(shè)備,并且會提供正確的輸入/輸出指令。GDI是Windows系統(tǒng)核心的三種動態(tài)鏈接庫之一,它管理Windows系統(tǒng)的所有程序的圖形輸出。在Windows系統(tǒng)中,GDI向程序員提供了高層次的繪圖函數(shù),只要掌握這些繪圖函數(shù),就可以很方便地進行圖形程序設(shè)計。 DC是一個數(shù)據(jù)結(jié)構(gòu),當程序向GDI設(shè)備中繪圖時,需要訪問該設(shè)備的D
11、C。MFC將GDI的DC封裝在C+類中,包括CDC類和CDC派生類,這些類中的許多成員都是對本地GDI繪圖函數(shù)進行簡單封裝而形成的內(nèi)聯(lián)函數(shù)。DC的作用就是提供程序與物理設(shè)備或者虛擬設(shè)備之間的聯(lián)系,除此之外,DC還要處理繪圖屬性的設(shè)置,如文本的顏色等。程序員可以通過調(diào)用專門的GDI函數(shù)修改繪圖屬性,如SetTextColor()函數(shù)。CDC類是GDI封裝在MFC中最大的一個類,它表示總的DC。表2.1列出了CDC中的一些常用繪圖函數(shù)。設(shè)備描述表(DC, Device Context)表2.1 CDC類中常用繪圖函數(shù) 函 數(shù)描 述使用頻率Arc()橢圓弧*BitBlt()把位圖從一個DC拷貝到另一
12、個DC*Draw3dRect()繪制三維矩形*DrawDragRect()繪制用鼠標拖動的矩形*DrawEdge()繪制矩形的邊緣*DrawIcon()繪制圖標*Ellipse()繪制橢圓*FillRect()繪制用給定的畫刷顏色填充矩形*FillRgn()繪制用給定的畫刷顏色填充區(qū)域*FillSolidRed()繪制用給定的顏色填充矩形*FloodFill()用當前的畫刷顏色填充區(qū)域*FrameRect()繪制矩形邊界*FrameRgn()繪制區(qū)域邊界*GetBKColor()獲取背景顏色*GetCurrentBitmap()獲取所選位圖的指針*GetCurrentBrush()獲取所選畫刷
13、的指針*GetCurrentFont()獲取所選字體的指針*GetCurrentPalette()獲取所選調(diào)色板的指針*GetCurrentPen()獲取所選畫筆的指針*GetCurrentPosition()獲取畫筆的當前位置*GetDeviceCaps()獲取顯示設(shè)備能力的信息*GetMapMode()獲取當前設(shè)置映射模式*Getpixel()獲取給定像素的RGB顏色值*GetPolyFillMode()獲取多邊形填充模式*GetTextColor()獲取文本顏色*GetTextExtent()獲取文本的寬度和高度*GetTextMetrics()獲取當前文本的信息*GetWindow()
14、獲取DC窗口的指針*GrayString()繪制灰色文本*LineTo()繪制直線*MoveTo()設(shè)置當前畫筆位置*Pie()繪制餅圖*Polygon()繪制多邊形*PolyLine()繪制一組直線*RealizePalette()將邏輯調(diào)色板映射到系統(tǒng)調(diào)色板*Rectangle()繪制矩形*RoundRect()繪制圓角矩形*SelectObject()選擇GDI繪圖對象*SelectPalette()選擇邏輯調(diào)色板*SelectStockObject()選擇預定義圖形對象*這些函數(shù)的語法和使用可以通過MSDN幫助查詢。2.2.2節(jié)主要介紹Windows中基本圖形,包括點、直線、圓、圓弧、
15、矩形、橢圓、扇形、折線等程序設(shè)計 SetBkColor()設(shè)置背景顏色*SetMapMode()設(shè)置映射模式*SetPixel()把像素設(shè)定為給定的顏色*SetTextColor()設(shè)置文本顏色*StretchBlt()把位圖從一個DC拷貝到另一個DC,并根據(jù)需要擴展或壓縮位圖*TextOut()繪制字符串文本*2.2.2 繪制基本圖形 (1)畫點 SetPixel()函數(shù)可以在指定的坐標位置按指定的顏色畫點。函數(shù)原型說明如下: COLORREF CDC: SetPixel(int X, int Y, COLORREF crColor);其中(X,Y)為點的坐標位置,crColor參數(shù)為點的顏
16、色值。如果函數(shù)調(diào)用成功,則函數(shù)返回像素的顏色值,否則返回值為-1。顏色值通過RGB(Red,Green,Blue)來設(shè)置,其中三個參數(shù)取值0255。例如,在VcAPP項目中,在CVcAppView類中的OnDraw()函數(shù)中加入下列畫點語句:/繪制一組彩色點 pDC-TextOut(20,20,point:);pDC-SetPixel(100,20,RGB(255,0,0); pDC-SetPixel(110,20,RGB(0,255,0);pDC-SetPixel(120,20,RGB(0,0,255);pDC-SetPixel(100,20,RGB(255,255,0);pDC-SetPi
17、xel(100,20,RGB(255,0,255);pDC-SetPixel(100,20,RGB(0,255,255);pDC-SetPixel(100,20,RGB(0,0,0);pDC-SetPixel(100,20,RGB(255,255,255);運行程序,查看運行結(jié)果。 (2)畫直線和折線 畫直線需要LineTo()和MoveTo()兩個函數(shù)的配合使用。LineTo()函數(shù)以當前位置所在的點為直線的起點,另指定一個點為直線的終點,畫出一段直線。直線的顏色通過畫筆的顏色來設(shè)定,在后面介紹。LineTo()函數(shù)原型說明如下:BOOL CDC: LineTo(int nXEnd, int
18、 nYEnd);直線的終點位置由(nXEnd, nYEnd)指定。如果函數(shù)調(diào)用成功,那么該點就成為當前位置,并返回TRUE,否則返回FALSE。MoveTo()函數(shù)只是將當前位置移動到指定位置,它并沒有畫出直線,其函數(shù)說明為: BOOL CDC: MoveTo (int X, int Y);示例:在CVcAppView類中的OnDraw()函數(shù)中加入下列畫點語句:/繪制直線 pDC-TextOut(20,60,Line:); pDC-MoveTo(20,90); pDC-LineTo(160,90);Polyline()函數(shù)用來畫一條折線,而PolyPolyline()函數(shù)則用來畫多條折線,其
19、函數(shù)原型說明如下:BOOL CDC:Polyline(COUST POINT *lppt, int cPoints);BOOL CDC:PolyPolyline(COUST POINT * lppt, COUST DWORD *lpdwPolyPoints, DWORD cCount);在Polyline()函數(shù)中,lppt是指向折線頂點數(shù)組的指針,而cPoints是折線頂點數(shù)組中的頂點數(shù)。例如,繪制一條具有4個頂點的折線,程序如下:POINT polylinepoint4=70,240,20,190, 70,190,20,240;pDC-Polyline(polylinepoint,4);在
20、PolyPolyline()函數(shù)中,lppt是指向保存頂點數(shù)組的指針,而各條折線的頂點數(shù)則保存在lpdwPolyPoints參數(shù)所指向的數(shù)組中,最后的cCount參數(shù)指定折線的數(shù)目。例如:POINT polypolylinePt9=95,160,120,185,120,250, 145,160,120,185,90,185,150,185,80,210,160,210;DWORD dwPolyPoints4=3,2,2,2; /分四段折線,分別占用3,2,2,2個頂點 pDC-PolyPolyline(polypolylinePt, dwPolyPoints, 4);注:由于一條折線至少需要2
21、個頂點,因此dwPolyPoints數(shù)組中的數(shù)不應(yīng)該小于2。(3)畫弧線和曲線 通過Arc()函數(shù)畫弧線或整個橢圓。橢圓限定在一個矩形內(nèi),稱為外接矩形。Arc()函數(shù)的圓形說明如下: BOOL CDC: Arc(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nXStartArc, int nYStartArc, int nXEndArc, int nYEndArc); 其中(nLeftRect, nTopRect)是外接矩形的左上角坐標值,(nRightRect, nBottomRect)是外接矩形的右下角坐
22、標值。而橢圓中心與點(nXStartArc, nYStartArc)所構(gòu)成的射線與橢圓的交點成為弧線的起點,橢圓中心與點(nXEndArc, nYEndArc)所構(gòu)成的射線與橢圓的交點成為弧線的終點。橢圓上從始點到終點就形成一條弧線。 在Windows系統(tǒng)中,弧線從始點到終點的方向是逆時針方向,但可以通過SetArcDirection()函數(shù)將繪制弧線方向設(shè)置為順時針方向。 for (i=0;iArc(260-5*i,70-5*i,260+5*i,70+5*i,260+5*i,70,260+5*i,70);for (i=3;iArc(260-10*i, 70-10*i, 260+10*i, 7
23、0+10*i, (int)260+10*i*cos(60*3.1415926/180), (int)70+10*i*sin(60*3.1415926/180), (int)260+10*i*cos(60*3.1415926/180), (int)70-10*i*sin(60*3.1415926/180);pDC-Arc(260-10*i, 70-10*i, 260+10*i, 70+10*i, (int)260-10*i*cos(60*3.1415926/180), (int)70-10*i*sin(60*3.1415926/180), (int)260-10*i*cos(60*3.14159
24、26/180), (int)70+10*i*sin(60*3.1415926/180);示例,用Arc()繪制圓、圓弧和橢圓,程序如下:Bezier曲線是最常見的非規(guī)則曲線之一。Bezier曲線屬于三次曲線,需要四個控制頂點來確定一條Bezier曲線,其中曲線通過第一點和最后一點,并且第一條邊和最后一條邊是曲線在起點和終點處的切線,從而確定了曲線的走向。PolyBezier()函數(shù)可以畫出一條或多條Bezier曲線,其函數(shù)原型說明如下: BOOL CDC: PolyBezier(CONST POINT * lppt, DWORD cPoints); Bezier曲線其中,lppt參數(shù)是曲線控制
25、頂點所組成的數(shù)組,cPoints參數(shù)表示lppt數(shù)組中的頂點數(shù),一條Bezier曲線需要四個控制頂點。如果lppt數(shù)組用于畫多條Bezier曲線,第二條以后的曲線只需要三個控制頂點,因為后面的曲線總是把前一條曲線的終點作為自己的起點。示例,給出四個控制頂點,畫出一條Bezier曲線和特征多邊形。/繪制Bezier 曲線POINT polyBezier4=20,310,60,240,120,300,160,330;pDC-Polyline(polyBezier,4);pDC-PolyBezier(polyBezier,4); (4)畫封閉曲線 Windows中提供了一組畫封閉曲線的函數(shù),包括繪制
26、矩形、多邊性、橢圓等,這些畫封閉曲線的函數(shù)不但可以利用畫筆來畫出輪廓線,同時還可以利用畫刷來填充這些封閉曲線所圍成的區(qū)域。 Rectangle()函數(shù)用來畫矩形,其函數(shù)原型說明如下: BOOL CDC: Rectangle(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); 其中,參數(shù)nLeftRect和 nTopRect給出了矩形左上角的坐標,而nRightRect和 nBottomRect則給出矩形的右下角坐標。Ellipse()函數(shù)的作用則是畫橢圓形。在Ellipse()函數(shù)中,橢圓是由其外接矩形來確定的,外接矩形
27、的中心與橢圓中心重合,矩形的長與寬和橢圓的長短軸相等。函數(shù)說明如下: BOOL CDC: Ellipse(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); 其中的參數(shù)說明與Rectangle()函數(shù)相同。 RoundRect()函數(shù)用來畫圓角矩形,其函數(shù)的原型說明如下: BOOL CDC: RoundRect(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect,int nWidth, int nHeight); 其中的前四個參數(shù)與Rectangle(
28、)函數(shù)相同,nWidth表示圓角的寬度, nHeight表示圓角的高度。 Polygon()函數(shù)用來畫封閉的任意多邊形,其函數(shù)原型說明如下: BOOL CDC: Polygon(COUST POINT *lpPoints, int cCount); 其中的參數(shù)說明與Polyline()函數(shù)相同。但兩個函數(shù)有區(qū)別,Polygon()函數(shù)會自動將起點和終點相連形成封閉的多邊形,而Polyline()函數(shù)則畫出多條折線,只有當最后一點與起點相同時才畫出封閉的多邊形。 示例,繪制矩形、圓角矩形、橢圓和多邊形,程序如下:/繪制矩形、圓角矩形、橢圓和多邊形pDC-Rectangle(190,270,250
29、,310);pDC-RoundRect(265,270,330,310,30,20);pDC-Ellipse(260-50,200-30,260+50,200+30);POINT polygonPts3=390,160,430,220,350,210;pDC-Polygon(polygonPts,3); 2.2.3 畫筆與畫刷 (1)畫筆 當繪制圖形時,線條的屬性,包括顏色、寬度、樣式等都是由畫筆來確定的。程序員可以創(chuàng)建畫筆,定義畫筆的屬性,從而畫出多彩的圖形。方法一:直接構(gòu)造一個CPen對象,并將定義畫筆的參數(shù)傳給它,例如: CPen pen(PS-SOLID,1,RGB(255,0,0);
30、 創(chuàng)建一個寬度為一個像素、實線和紅色的畫筆。 方法二:首先聲明一個沒有初始化的CPen類對象,然后再用CreatePen()函數(shù)定義畫筆的屬性。例如, CPen Pen; Pen-CreatePen (PS-SOLID,1,RGB(255,0,0);方法三:先聲明一個CPen類對象和一個描述畫筆結(jié)構(gòu)的LOGPEN類對象,并填入畫筆的屬性值,然后調(diào)用CreatePenIndirect()函數(shù)來創(chuàng)建畫筆。如下所示:CPen Pen;LOGPEN LogPen;LogPen.lopnStyle=PS_SOLID;LogPen.lopnWidth=1;LogPen.lpenColor=RGB(255,
31、0,0);Pen.CreatePenIndirect(&LogPen); 如果畫筆被成功創(chuàng)建,那么兩個函數(shù)返回TRUE,否則返回FALSE。 畫筆包括樣式、寬度和顏色三個屬性。表2.2列出了GDI畫筆的樣式。畫筆的寬度用像素個數(shù)來確定。PS_DASH、PS_DOT、PS_DASHDOT和PS_DASHDOTDOT參數(shù)要求畫筆寬度只能為1,其它參數(shù)可以創(chuàng)建任意寬度的畫筆。畫筆的顏色是一個24位的RGB顏色,由RGB(rColor,gColor,bColor)來定義,三個參數(shù)取值0255。Windows預定義了三個實線、1個像素寬的畫筆,它們是WHITE_PEN、BLACK_PEN和NULL_PE
32、N,程序中可以直接使用這些畫筆,方法如下: CPen Pen; Pen.CreateStockObject(WHITE_PEN);示例:在屏幕上繪制三組直線,第一組按不同線型繪制,第二組按不同寬度繪制,第三組按不同顏色繪制。程序如下: /畫筆的樣式、寬度和顏色int i1;int nPenStyle= PS_SOLID,PS_DASH,PS_DOT,PS_DASHDOT,PS_DASHDOTDOT,PS_NULL,PS_INSIDEFRAME,;CPen *pNewPen;CPen *pOldPen;/用不同樣式的畫筆for (i1=0;i1CreatePen(nStylei1,1,RGB(0
33、,0,0)pOldPen=pDC-SelectObject(pNewPen); /選擇新筆,并保存舊筆/畫直線pDC-MoveTo(20,60+i1*20);pDC-LineTo(160,60+i1*20);/恢復原有的筆pDC-SelectObject(pOldPen);else /出錯提示AfxMessageBox(CreatePen Erroe!); /刪除新筆delete pNewPen;/用不同的寬度的筆繪圖for(i1=0;i1CreatePen(PS_SOLID,i1+1,RGB(0,0,0)pOldPen=pDC-SelectObject(pNewPen);/畫直線pDC-Mo
34、veTo(200,60+i1*20);pDC-LineTo(340,60+i1*20);/恢復原有的筆pDC-SelectObject(pOldPen);else /出錯提示AfxMessageBox(CreatePen Erroe!);/刪除新筆delete pNewPen;/設(shè)置顏色表 struct tagColor int r,g,b; color7= 255,0,0,0,255,0,0,0,255, 255,255,0,255,0,255,0,255,255,0,0,0, ; /用不同顏色繪圖for(i1=0;i1CreatePen(PS_SOLID,2,RGB(colori1.r,c
35、olori1.g,colori1.b)pOldPen=pDC-SelectObject(pNewPen);/畫直線pDC-MoveTo(380,60+i1*20);pDC-LineTo(520,60+i1*20);/恢復原有的筆pDC-SelectObject(pOldPen);else/出錯提示AfxMessageBox(CreatePen Erroe!);/刪除新筆delete pNewPen;/畫筆程序結(jié)束 在進行區(qū)域填充或繪制封閉圖形時,需要用到畫刷。MFC把GDI畫刷封裝在CBrush類中。畫刷分三種基本類型:純色畫刷、陰影畫刷和圖案畫刷。 純色畫刷繪圖使用單色來定義,顏色由RGB(
36、)函數(shù)來確定。純色畫刷可以采用直接聲明的方法,例如: CBrush Brush(RGB(255,0,0); 創(chuàng)建一個紅色畫刷。 也可以采用分步方法,由CreateSolidBrush()函數(shù)創(chuàng)建。 CBrush Brush; Brush-Create-CreateSolidBrush(RGB(255,0,0);(2)畫刷Windows預定義了七種畫刷,包括:BLACK_BRUSH、 DKGRAY_BRUSH、 GRAY_BRUSH、LTGRAY_BRUSH、HOLLOW_BRUSH、NULL_BRUSH和WHITE_BRUSH??梢詤⒄誄Pen類的方法,采用CreateStockObject(
37、)來使用預定義的畫刷。陰影畫刷使用預定義的六種陰影樣式進行繪圖。表2.3列出了六種陰影樣式。 創(chuàng)建陰影畫刷的方法與純色畫刷的創(chuàng)建方法相似,例如創(chuàng)建一個45度方向的交叉陰影線的畫刷,方法如下: CBrush Brush(HS_DIAGCROSS,RGB(255,0,0); 或者 CBrush Brush; Brush-CreateHatchBrush (HS_DIAGCROSS,RGB(255,0,0); 函數(shù)中有兩個參數(shù),第一個參數(shù)是畫刷的陰影樣式,第二個參數(shù)是陰影線的顏色。示例:繪制缺省畫刷的矩形,純色畫刷矩形和繪制100單位的矩形,并且用白色45度交叉線陰影將其填充,程序如下:/畫刷程序p
38、DC-Rectangle(300,300,400,400); /缺省的畫刷,白色/純色畫刷CBrush *pNewBrush1;CBrush *pOldBrush1;pNewBrush1=new CBrush;if (pNewBrush1-CreateSolidBrush(RGB(255,0,0)/選擇新畫刷 pOldBrush1=pDC-SelectObject(pNewBrush1);/繪制矩形 pDC-Rectangle(200,200,300,400);/恢復原有畫刷 pDC-SelectObject(pOldBrush1); delete pNewBrush1;/陰影畫刷CBrush
39、 Brush(HS_DIAGCROSS,RGB(255,255,255);CBrush *pOldBrush;pOldBrush=pDC-SelectObject(&Brush);pDC-SetBkColor(RGB(192,192,192);pDC-Rectangle(0,0,100,100);pDC-SelectObject(pOldBrush);2.2.4 文本顯示 Windows可以顯示很多數(shù)據(jù),包括在窗口中顯示文本信息。由于文本是以圖像的形式顯示在窗口中的,因此需要處理設(shè)備描述表(DC),另外還需要對文本字體的處理,包括:文本的顯示、文本的顏色、字符的間距和文本的對齊方式等。(1)文
40、本顯示 在擁有一個設(shè)備描述表以后,就可以調(diào)用TextOut()函數(shù)來顯示文本行。例如: pDC-TextOut(20,20,”This is a line of text.”); TextOut()函數(shù)的三個參數(shù)分別是輸出文本的X坐標和Y坐標以及輸出文本串。(2)設(shè)置文本顏色 在默認情況下,Windows繪制黑色文本??梢酝ㄟ^SetTextColor()函數(shù)改變文本的顏色。例如: CDC *pDC=GetDC(); /聲明一個設(shè)備描述表pDC1 pDC-SetTextColor(RGB(255,0,0); /設(shè)置文本顏色為紅色 可以通過GetTextColor()函數(shù)檢索到當前文本的顏色,例如
41、: COLORREF color=pDC-GetTextColor(); SetBkColor()和GetBkColor()函數(shù)用于設(shè)置背景顏色和獲取當前的背景顏色。(3)設(shè)置字符間距 SetTextCharacterExtra()函數(shù)用來設(shè)置文本字符的間距,GetTextCharacterExtra()用來獲得當前文本字符的間距,函數(shù)說明如下: pDC- SetTextCharacterExtra(space); int space=pDC- GetTextCharacterExtra(); 其中,space表示在文本字符之間使用的額外空間的像素數(shù)。SetTextAlign()函數(shù)用于設(shè)置顯
42、示文本的對齊方式,函數(shù)說明如下: pDC-SetTextAlign(alignment); 其中,alignment參數(shù)取值:TA_LEFT、TA_CENTER和TA_RIGHT,分別表示左對齊、居中方法和右對齊。Alignment參數(shù)取值:TA_TOP、TA_BOTTOM和TA_BASELINE分別表示文本在垂直方向的對齊方式,上對齊、下對齊和字符的基線對齊。(3)設(shè)置文本的對齊方式2.3 鼠標編程 在圖形操作系統(tǒng)中,鼠標是最重要的輸入設(shè)備之一。Windows系統(tǒng)為用戶提供了統(tǒng)一的鼠標編程接口,而不必過多了解其底層的知識。Windows是基于消息傳遞、事件驅(qū)動的操作系統(tǒng),當用戶移動鼠標、按下
43、或釋放鼠標鍵時都會產(chǎn)生鼠標消息。應(yīng)用程序可以接收10種鼠標消息,表2.3列出了這些鼠標消息和它們的描述。2.3.1 鼠標消息處理 MFC把鼠標消息處理函數(shù)封裝在CView類中,它們分別是: OnMouseMove(UINT nFlags, CPoint point); OnLButtonDblclk(UINT nFlags, CPoint point); OnLButtonDown(UINT nFlags, CPoint point); OnLButtonUp(UINT nFlags, CPoint point); 分別對應(yīng)表2.3中10個鼠標消息。在鼠標處理函數(shù)中,point參數(shù)代表鼠標熱點
44、處的坐標位置,point.x為橫坐標,point.y為縱坐標。默認坐標原點(0,0)位于窗口的左上角。由于應(yīng)用程序要求自動捕獲鼠標事件,因此應(yīng)當采用Windows事件處理函數(shù),而不是成員函數(shù),具體使用方法參見2.3.3節(jié)示例程序。 nFlags參數(shù)中包含了鼠標按鈕和鍵盤組合使用標志,用來描述鼠標按鈕和鍵盤上的Shift鍵和Ctrl鍵的組合狀態(tài)。nFlag參數(shù)取值范圍:MK_LBUTTON:鼠標左鍵被按下;MK_RBUTTON:鼠標右鍵被按下;MK_MBUTTON:鼠標中鍵被按下;MK_SHIFT:鍵盤上的Shift鍵被按下;MK_CONTROL:鍵盤上的Ctrl鍵被按下; 如果想知道某個鍵是否
45、被按下,可用對應(yīng)的位屏蔽值與nFlags參數(shù)作按位邏輯“與”運算,所的結(jié)果若為非零值,則表示該按鈕被按下,例如:if (nFlags & LBUTTON) AfxMessageBox(“LButton is pressed down!”)Else AfxMessageBox(“LButton is pressed Up!”); 如何區(qū)分兩次單擊和一次雙擊,這取決于兩次按下按鈕之間的時間間隔,只有當時間間隔小于一定值時才被認為是Windows默認的時間為500ms。可以用SetDoubleClickTime()函數(shù)來重新設(shè)置時間間隔值。 若要使窗口函數(shù)能接收到鼠標雙擊產(chǎn)生的消息,在注冊窗口類時,
46、必須指明該窗口具有CS_DBLCLKS風格,否則,即使進行了雙擊操作,該窗口也只能收到兩條“WM_LBUTTONDOWN”和“WM_LBUTTONUP”消息,例如:wndclass.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;2.3.2 捕捉鼠標 在交互式圖形程序設(shè)計中,經(jīng)常要使用鼠標的位置拾取、拖動或拖放,這些動作必須進行鼠標的捕捉。 鼠標捕捉只需要調(diào)用CWnd:SetCapture()函數(shù)。用戶完成鼠標捕捉工作后一般是響應(yīng)一個鼠標按下信息,要釋放鼠標捕捉則是調(diào)用CWnd:ReleaseCapture()函數(shù)。釋放被捕捉鼠標的最好時間是在響應(yīng)鼠標彈起的時候(
47、WM_LBUTTON)。 2.3.3 鼠標編程綜合示例 示例1:在窗口中以文本的形式給出鼠標的狀態(tài),即當鼠標移動時,給出鼠標的位置;當鼠標按下鼠標左、右鍵時顯示出鼠標按鍵狀態(tài)。例如,當鼠標左鍵按下時,顯示“LBUTTON DOWN!”。 第一步:建立一個myMouse工程文件; 第二步:添加鼠標事件處理函數(shù) 鼠標右擊視圖類(如CmyMouseView),選擇“add windows message handler”,彈出事件處理函數(shù)列表窗口,如圖2-11所示 圖2-11 Windows事件處理函數(shù)列表窗口 從左邊事件消息列表中選擇“WM_LBUTTONDOWN”,然后單擊“Add and Ed
48、it”按鈕,即加入鼠標左鍵按下事件函數(shù),并要求編輯事件處理程序。 第三步:輸入事件處理程序 void CMymouseView:OnLButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call default/獲得pDCCDC* pDC=GetDC();pDC-CView:TextOut(20,40,”LBUTTONDOWM!”); / 輸出顯示信息OnLButtonDown(nFlags, point); 其中,陰影部分是用戶輸入的程序,其它內(nèi)容都是自動生成的內(nèi)容。
49、第四步:重復第二步和第三步,分別添加WM_LBUTTONUP,WM_MOUSEMOVE,WM_RBUTTONDOWN,WM_RBUTTONUP,WM_LBUTTONDBCLK, WM_RBUTTONDBCLK鼠標事件,并輸入以下程序:void CMouseView:OnLButtonUp(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultCDC *pDC=GetDC(); pDC-TextOut(20,40,LButton UP!); CView:OnLButtonU
50、p(nFlags, point);void CMouseView:OnRButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call default CDC *pDC=GetDC(); pDC-TextOut(20,60,RButton Down!); CView:OnRButtonDown(nFlags, point);void CMouseView:OnRButtonUp(UINT nFlags, CPoint point) / TODO: Add your mess
51、age handler code here and/or call defaultCDC *pDC=GetDC(); pDC-TextOut(20,40,RButton UP!); CView:OnRButtonUp(nFlags, point);void CMouseView:OnMouseMove(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultCDC *pDC=GetDC(); char tbuf80;sprintf(tbuf,Position:(%3d,%3
52、d),point.x,point.y);/ 輸出鼠標當前位置 pDC-TextOut(20,20,tbuf);CView:OnMouseMove(nFlags, point);void CMouseView:OnLButtonDblClk(UINT nFlags, CPoint point)/ TODO: Add your message handler code here and/or call defaultCDC *pDC=GetDC(); pDC-TextOut(20,80,LButton is double clicked!);CView:OnLButtonDblClk(nFlags
53、, point);void CMouseView:OnRButtonDblClk(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultCDC *pDC=GetDC(); pDC-TextOut(20,80,RButton is double clicked!);CView:OnRButtonDblClk(nFlags, point);第五步:編譯程序,并驗證執(zhí)行結(jié)果。 鼠標橡皮筋技術(shù)畫圓就是采用圓心和圓周上任一點畫圓技術(shù)(簡稱C+P方法),首先用鼠標左擊選擇圓心位置,然
54、后移動鼠標,圓隨鼠標移動而擴大或縮小,當再次單擊鼠標左鍵時,確定圓周上的一點,從而畫出相應(yīng)的圓。直線、矩形等基本圖形都可以采用橡皮筋技術(shù)。 第一步:建立MouseSpring工程文件; 第二步:向視圖類中添加自定義的成員變量 用鼠標右鍵單擊視圖類,選擇“Add Member Variable”,添加下面三個成員變量。proctected : CPoint m_bO; / 圓心 CPoint m_bR; /圓上的點 int m_ist; /圓心與圓周上點的區(qū)別,m_ist=0,表示鼠標左擊點為圓心,m_ist=1,表示鼠標左擊點為圓周上的點 示例2:采用鼠標橡皮筋技術(shù)畫圓圖2-13 添加成員變量
55、操作方法如圖2-13所示,分別添加上述三個成員變量。第三步:向視圖類中添加自定義的成員函數(shù)原型: public: void DrawCircle(CDC* pDC, CPoint cenp, CPoint ardp); int ComputeRadius(CPoint cenp,CPoint ardp); 具體操作方法:用鼠標右鍵單擊視圖類,選擇“Add Member Function”,如圖2-14所示。分別添加上述兩個成員函數(shù),分別用于畫圓和計算圓的半徑。圖2-14 添加成員函數(shù) 第四步:在視圖類CPP文件的構(gòu)造函數(shù)中初始化成員變量 視圖類的構(gòu)造函數(shù)名與該視圖類的名字相同。在視圖類中選擇構(gòu)
56、造函數(shù),如:CMouseSpringView(),用鼠標左鍵雙擊,輸入下面程序代碼:CMouseSpringView: CMouseSpringView() /TODO: add construction code here m_bO.x=0; m_bO.y=0; /圓心 m_bR.x=0; m_bR.y=0; /圓上的點 m_ist=0; /圓心與圓上的點區(qū)別第五步:在視圖類的OnDraw()函數(shù)中加入下列代碼,實現(xiàn)視圖繪圖。 void CMouseSpringView:OnDraw(CDC* pDC)CMouseSpringDoc* pDoc = GetDocument();ASSERT_
57、VALID(pDoc); / TODO: add draw code for native data herepDC-SelectStockObject(NULL_BRUSH);DrawCircle(pDC,m_bO,m_bR); / 調(diào)用自定義的成員函數(shù)畫圓第六步:向視圖類中添加兩個鼠標消息響應(yīng)函數(shù),并輸入鼠標處理程序代碼。 具體操作方法與鼠標示例1方法相同。一個是OnLButtonDown()函數(shù),另一個是OnMouseMove()函數(shù)。程序如下:void CMouseSpringView:OnLButtonDown(UINT nFlags, CPoint point) / TODO: A
58、dd your message handler code here and/or call defaultCDC *pDC=GetDC(); pDC-SelectStockObject(NULL_BRUSH);if (!m_ist) /繪制圓 m_bO=m_bR=point; /紀錄第一次單擊鼠標位置,定圓心 m_ist+;else m_bR=point; /記錄第二次單擊鼠標的位置,定圓周上的點 m_ist-; / 為新繪圖作準備 DrawCircle(pDC,m_bO,m_bR); /繪制新圓ReleaseDC(pDC); /釋放設(shè)備環(huán)境CView:OnLButtonDown(nFlags
59、, point);void CMouseSpringView:OnMouseMove(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultCDC *pDC=GetDC(); int nDrawmode=pDC-SetROP2(R2_NOT); /設(shè)置異或繪圖模式,并保存原來繪圖模式pDC-SelectStockObject(NULL_BRUSH);if(m_ist=1)CPoint prePnt,curPnt;prePnt=m_bR; /獲得鼠標所在的前一位置curPn
60、t=point;/繪制橡皮筋線DrawCircle(pDC,m_bO,prePnt); /用異或模式重復畫圓,擦出所畫的圓 DrawCircle(pDC,m_bO,curPnt); /用當前位置作為圓周上的點畫圓m_bR=point; pDC-SetROP2(nDrawmode); /恢復原繪圖模式ReleaseDC(pDC); /釋放設(shè)備環(huán)境CView:OnMouseMove(nFlags, point);分別為兩個成員函數(shù)DrawCircle()和ComputeRadius()添加程序代碼,程序如下:void CMouseSpringView:DrawCircle(CDC *pDC, CP
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年生物質(zhì)循環(huán)流化床氣化裝置項目規(guī)劃申請報告
- 玻璃棧道采購計劃方案
- 玻璃廊道規(guī)劃方案
- 玻璃切割課程設(shè)計
- 猜數(shù)java課程設(shè)計
- 版畫校本課程設(shè)計
- 愛藍國學堂課程設(shè)計
- 泵站設(shè)備安裝監(jiān)理方案
- 泵站格柵清理方案
- 氨氣解析塔課程設(shè)計
- Unit6Craftsmanship+單詞課件-中職高二英語高教版(2021)基礎(chǔ)模塊2
- 辦公設(shè)備投標方案368
- 2023-2024年新人教版pep六年級英語上冊試卷全套含答案
- 消防安全問卷調(diào)查表范本
- 獸醫(yī)產(chǎn)科學智慧樹知到課后章節(jié)答案2023年下甘肅農(nóng)業(yè)大學
- 虛擬化技術(shù)在教育和培訓領(lǐng)域的應(yīng)用解決方案
- 冀教版小學數(shù)學四年級上冊教案7.1《垂線的認識》
- 小學四年級數(shù)學上冊口算題卡
- 門禁安全檢查制度范本
- 請款單(可直接打印-標準模板)
- 班主任德育工作:班主任培訓講課件
評論
0/150
提交評論