MFC繪圖基礎 .


from:http://blog.csdn.net/leolee82/article/details/6992590

先認識一下MFC中的一些和繪圖有關的結構體和類
1.點
(1)點結構POINT點數據結構POINT用來表示一點的x、y坐標:
typedef struct tagPOINT {
LONG x;
LONG y;
} POINT;

(2)點類CPoint
點類CPoint為一個沒有基類的獨立類,封裝了POINT結構,有成員變量x和y
其構造函數有5種:
CPoint( );
CPoint( int initX, int initY );
CPoint( POINT initPt );
CPoint( SIZE initSize );
CPoint( LPARAM dwPoint );// 低字設為x、高字設為y

CPoint類還定義了4個平移和設置函數:
void Offset(int xOffset, int yOffset);
void Offset(POINT point);
void Offset(SIZE size);
void SetPoint(int X, int Y);

CPoint類還重載了+、-、+=、-=、==、!=等運算符來支持CPoint對象和CPoint、POINT、SIZE對象之間的運算。

2.大小
(1)大小結構SIZE
大小(size尺寸)結構SIZE用來表示矩形的寬cx和高cy:
typedef struct tagSIZE {
LONG cx;
LONG cy;
} SIZE

(2)大小類CSize
大小類CSize也為一個沒有基類的獨立類,封裝了SIZE結構,有成員變量cx和cy
其構造函數也有5種:
CSize( );
CSize( int initCX, int initCY );
CSize( SIZE initSize );
CSize( POINT initPt );
CSize( DWORD dwSize ); // 低字設為cx、高字設為cy

CSizet類也重載了+、-、+=、-=、==、!=等運算符來支持CSize對象和CSize、POINT、SIZE、RECT對象之間的運算


3.矩形
(1)矩形結構RECT
矩形結構RECT定義了矩形的左上角與右下角的坐標:
typedef struct tagRECT {
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT;

(2)矩形類CRect
矩形類CRect也為一個沒有基類的獨立類,封裝了RECT結構,有成員變量left、top、right和bottom
其構造函數有6種:
CRect( );
CRect( int l, int t, int r, int b );
CRect( const RECT& srcRect );
CRect( LPCRECT lpSrcRect );
CRect( POINT point, SIZE size );
CRect( POINT topLeft, POINT bottomRight );

CRect類重載了=,+、-,+=、-=,==、!=,&、|,& =、|=等運算符來支持CRect對象和CRect、POINT、SIZE、RECT對象之間的運算。

還定義了轉換符LPCRECT和LPRECT來自動完成CRect對象到矩形結構和類指針LPCRECT和LPRECT的轉換。

判斷點是否在矩形中有時需要判斷某點(如鼠標位置)是否在某一矩形區域中,這可以調用CRect類的PtInRect函數來做:
BOOL PtInRect( POINT point ) const;
該函數當點point在其矩形區域內時,返回真。注意,該矩形區域不包括矩形的右邊界和底邊界


然后就是關於 設備描述表 的獲取和釋放了,前一文章提到過, 這里就不提了
只說一個特別點的概念 “安全DC句柄”
也可以用CDC類的成員函數:
HDC GetSafeHdc();
來獲取CD所對應窗口(如客戶區)的安全DC句柄,該句柄在窗口存在期間一直是有效的。
例如,可先定義類變量HDC m_hDC;,再在適當的地方給它賦值m_hDC = GetDC()->GetSafeHdc();,然后就可以放心地使用了

因為不能簡單的將這一指針保存在類的數據成員中,而是應該借助GetSafeHdc成員函數將它轉換為windows句柄 (唯一能夠持久存在的GDI標示)

例如,可以使用CDC類的成員函數
BOOL Attach(HDC hDC); // 成功返回非0
來將CDC對象與DC句柄連接在一起


4.設置繪圖顏色
(1)顏色
Windows中的顏色一般用4個字節表示,Win32 API中定義了一個專門表示顏色索引值的變量類型COLORREF:(windef.h)
typedef DWORD COLORREF; // 0x00bbggrr
和一個由紅綠藍三原色構造顏色值的宏RGB:(wingdi.h)
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))

其中,r、g、b為字節變量,取值范圍為0~255。其函數說明為:
COLORREF RGB(
BYTE bRed, // 紅分量
BYTE bGreen, // 綠分量
BYTE bBlue // 藍分量
);

例如:
COLORREF red, gray;
red = RGB(255, 0, 0);
gray = RGB(128, 128,128);

在API中還定義了由COLORREF變量獲取各個顏色分量的宏Get?Value:(wingdi.h)
#define GetRValue(rgb) (LOBYTE(rgb))
#define GetGValue(rgb) (LOBYTE(((WORD)(rgb)) >> 8))
#define GetBValue(rgb) (LOBYTE((rgb)>>16))

(2)點色(像素)
在Windows中,像素(pixel)的顏色是直接由設備上下文類CDC的成員函數SetPixel來設置的
該函數的原型為:
COLORREF SetPixel( int x, int y, COLORREF crColor );
COLORREF SetPixel( POINT point, COLORREF crColor );
其中,x與y分別為像素點的橫坐標與縱坐標,crColor為像素的顏色值。

例如:
pDC->SetPixel(10, 10, RGB(0, 255, 0));
另外,也可以用CDC的成員函數
COLORREF GetPixel( int x, int y ) const;
COLORREF GetPixel( POINT point ) const;
來獲得指定點(x, y)或point的顏色。

例如:
COLORREF col;
col = pDC->GetPixel(10, 10);

(3)線色(筆)
在Windows中,線狀圖必須用筆(pen)來畫,所以線的顏色就由筆色來確定。
在MFC中,筆的屬性和功能由CPen類提供(CPen是CGDIObject的派生類)。
筆的創建與使用的步驟為:

#1創建筆對象:
創建筆類CPen對象的方法有如下兩種:
CPen( int nPenStyle, int nWidth, COLORREF crColor );
其中:
nPenStyle為筆的風格,可取值:PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PSDASHDOTDOT
注意:1~4號筆風格只是在筆寬=0或1時有效,筆寬>1時總為實心的
BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor );

#2將筆對象選入設備上下文:
為了能使用我們所創建的筆對象,必須先將它選入設備上下文,這可以調用設備上下文類CDC的成員函數SelectObject來完成:
CPen* SelectObject( CPen* pPen );返回值為指向原來筆對象的指針(一般將其保存下來,供下次再裝入時使用)。
pOldPen = pDC->SelectObject(&pen);

另外,Windows中有一些預定義的筆對象,可用CDC的另一成員函數SelectStockObject將其選入DC
其函數原型為:virtual CGdiObject* SelectStockObject( int nIndex );
預定義的筆對象有BLACK_PEN(黑色筆)、WHITE_PEN (白色筆)、NULL_PEN(空筆/無色筆)
例如:pDC->SelectStockObject(BLACK_PEN);

#3使用設備上下文畫線狀圖:
畫線狀圖以及面狀圖的邊線,所使用的是當前設備上下文中的筆對象。
線狀圖有直線、折線、矩形、(橢)圓(弧)等,詳見

#4將筆對象從設備上下文中放出:
為了能刪除使用過的筆對象,必須先將它從設備上下文中釋放出來后,然后才能刪除。
釋放的方法是裝入其他的筆對象(一般是重新裝入原來的筆對象)。例如
pDC->SelectObject(pOldPen);

#5刪除筆對象:
為了能刪除筆對象,必須先將其從設備上下文中釋放。刪除方法有如下幾種:
調用筆類CDC的成員函數DeleteObject刪除筆的當前內容(但是未刪除筆對象,以后可再用成員函數CreatePen在筆對象中繼續創建新的筆內容)。

pen.DeleteObject();
使用刪除運算符delete將筆對象徹底刪除,如delete pen;
自動刪除:若筆對象為局部變量,則在離開其作用域時,會被系統自動刪除


(4)面色(刷)
在Windows中,面狀圖必須用刷(brush)來填充,所以面色是由刷色來確定的。
MFC中的刷類為CBrush(它也是CGDIObject的派生類),刷的創建與使用的步驟與筆的相似。
構造函數有4個:
CBrush( ); // 創建一個刷的空對象
CBrush( COLORREF crColor ); // 創建顏色為crColor的實心刷
CBrush( int nIndex, COLORREF crColor ); // 創建風格由nIndex指定且顏色為crColor的條紋(hatch)刷,其中nIndex可取條紋風格(Hatch Styles)值:
符號常量 數字常量 風格
HS_HORIZONTAL 0 水平線
HS_VERTICAL 1 垂直線
HS_FDIAGONAL 2 正斜線
HS_BDIAGONAL 3 反斜線
HS_CROSS 4 十字線(正網格)
HS_DIAGCROSS 5 斜十字線(斜網格)


CBrush( CBitmap* pBitmap ); // 創建位圖為pBitmap的圖案刷
如:pDC->FillRect( &rect, new CBrush( RGB(r, g, b) ) );


與構造函數相對應,有多個創建不同類型刷的成員函數:
BOOL CreateSolidBrush( COLORREF crColor );
BOOL CreateHatchBrush( int nIndex, COLORREF crColor );
BOOL CreatePatternBrush( CBitmap* pBitmap );
BOOL CreateDIBPatternBrush( HGLOBAL hPackedDIB, UINT nUsage );
BOOL CreateDIBPatternBrush( const void* lpPackedDIB, UINT nUsage );
BOOL CreateBrushIndirect( const LOGBRUSH* lpLogBrush );
BOOL CreateSysColorBrush( int nIndex );

預定義的刷對象有BLACK_BRUSH(黑刷)、DKGRAY_BRUSH(暗灰刷)、GRAY_BRUSH(灰刷)、 HOLLOW_BRUSH(空刷)、LTGRAY_BRUSH(亮灰刷)、NULL_BRUSH(空刷)、WHITE_BRUSH(白刷)
缺省的刷為空刷

與筆一樣,可以用函數SelectObject或SelectStockObject將自定義的刷或預定義的刷選入DC中,供繪面狀圖時使用。

(5)文本色
可使用CDC類的成員函數SetTextColor和SetBkColor來分別設置輸出文本的前景色和背景色:
(缺省的前景色為黑色,背景色空)
COLORREF GetTextColor( ) const;
virtual COLORREF SetTextColor( COLORREF crColor );
COLORREF GetBkColor( ) const;
virtual COLORREF SetBkColor( COLORREF crColor );

例如:
pDC->TextOut(10, 10, "Test text");
pDC->SetTextColor(RGB(0, 128, 0));
pDC->TextOut(10, 30, "Test text");
pDC->SetBkColor(RGB(0, 0, 128));
pDC->TextOut(10, 50, "Test text");


5.清屏
Windows沒有提供專門的清屏函數,可以調用CWnd的下面兩個函數調用來完成該功能:
void Invalidate(BOOL bErase = TRUE);void UpdateWindow( );
或調用CWnd的函數BOOL RedrawWindow(
LPCRECT lpRectUpdate = NULL,
CRgn* prgnUpdate = NULL,
UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE
);來完成。


5 設置繪圖屬性除了映射模式外,還有許多繪圖屬性可以設置
如背景、繪圖方式、多邊形填充方式、畫弧方向、刷原點等。

#1.背景
1)背景色當背景模式為不透明時,背景色決定線狀圖的空隙顏色(如虛線中的空隙、條紋刷的空隙和文字的空隙)
可以使用CDC類的成員函數GetBkColor和SetBkColor來獲得和設置當前的背景顏色:
COLORREF GetBkColor( ) const; // 返回當前的背景色
virtual COLORREF SetBkColor( COLORREF crColor ); // 返回先前的背景色
// 若出錯返回0x800000002)
背景模式背景模式影響有空隙的線狀圖的空隙(如虛線中的空隙、條紋刷的空隙和文字的空隙)用什么辦法填充。
可以使用CDC類的成員函數GetBkMode和SetBkMode來獲得和設置當前的背景模式:
int GetBkMode( ) const; // 返回當前背景模式
int SetBkMode( int nBkMode ); // 返回先前背景模式背景模式的取值nBkMode值 名稱 作用

OPAQUE 不透明的(缺省值) 空隙用背景色填充
TRANSPARENT 透明的 空隙處保持原背景圖不變

2. 繪圖模式繪圖模式(drawing mode)指前景色的混合方式,
它決定新畫圖的筆和刷的顏色(pbCol)如何與原有圖的顏色(scCol)相結合而得到結果像素色(pixel)。
1)設置繪圖模式可使用CDC類的成員函數SetROP2 (ROP = Raster OPeration光柵操作)來設置繪圖模式:
int SetROP2( int nDrawMode );
其中,nDrawMode可取值:繪圖模式nDrawMode的取值

符號常量 作用 運算結果
R2_BLACK 黑色 pixel = black
R2_WHITE 白色 pixel = white
R2_NOP 不變 pixel = scCol
R2_NOT 反色 pixel = ~scCol
R2_COPYPEN 覆蓋 pixel = pbCol
R2_NOTCOPYPEN 反色覆蓋 pixel = ~pbCol
R2_MERGEPENNOT 反色或 pixel = ~scCol | pbCol
R2_MERGENOTPEN 或反色 pixel = scCol | ~pbCol
R2_MASKNOTPEN 與反色 pixel = scCol & ~pbCol
R2_MERGEPEN 或 pixel = scCol | pbCol
R2_NOTMERGEPEN 或非 pixel = ~(scCol | pbCol)
R2_MASKPEN 與 pixel = scCol & pbCol
R2_NOTMASKPEN 與非 pixel = ~(scCol & pbCol)
R2_XORPEN 異或 pixel = scCol ^ pbCol
R2_NOTXORPEN 異或非 pixel = ~(scCol ^ pbCol)
其中,R2_COPYPEN(覆蓋)為缺省繪圖模式,R2_XORPEN(異或)較常用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM