1.筆記
1.1CDC類
第一個C是Class,D是Device,第二個C是Context,即“裝置上下文”,是MFC中應用程式的圖形裝置接口,封裝了繪圖所需的成員函數。
1.1.1使用規則
任何時候,最多隻能獲得5個CDC同時使用。
1.1.2獲得CDC
函數原型:
CDC* CWnd::GetDC();
調用成功則傳回目前視窗客戶區裝置上下文辨別符,否則傳回NULL。
1.1.3釋放CDC
函數原型:
int CWnd::ReleaseDC(CDC* pDC);
pDC是要釋放裝置上下文的辨別符,調用成功則傳回非0,否則傳回0。
1.2繪圖工具類
1.2.1主要繪圖工具類
CGdiObject | 提供各種Windows GDI繪圖工具的基類 |
CBitmap | 封裝GDI位圖,提供位圖操作的接口 |
CBrush | 封裝GDI畫刷,可以選作裝置上下文的目前畫刷 |
CFont | 封裝GDI字型,可以選作裝置上下文的目前字型 |
CPalette | 封裝GDI調色闆,提供應用程式和顯示器之間的顔色接口 |
CPen | 封裝GDI畫筆,可以選作裝置上下文的目前畫筆 |
1.2.2 使用GDI對象繪圖時的規則
(1)繪圖開始前,建立一個新的GDI對象,并選入目前裝置上下文中,同時儲存指向原GDI對象的指針。
(2)使用新的GDI對象畫圖。
(3)繪圖結束後,使用儲存的原GDI對象的指針将裝置上下文恢複原狀。
1.3繪制像素點
1.3.1SetPixel
函數原型:
COLORREF CDC::SetPixel(POINT point,COLORREF crColor);
COLORREF CDC::SetPixel(int x,int y,COLORREF crColor);
參數順序為像素點位置,像素點顔色。調用成功則傳回像素點的RGB值,否則傳回-1。
1.3.2SetPixelV
函數原型:
BOOL CDC::SetPixelV(POINT point,COLORREF crColor);
BOOL CDC::SetPixelV(int x,int y,COLORREF crColor);
參數含義同上,調用成功則傳回非0,否則傳回0。
1.3.3比較
因為SetPixel要傳回RGB值,而SetPixelV不需要,故SetPixelV執行速度稍快。
1.4RGB
1.4.1RGB宏
原型:
COLORREF RGB(BYTE byRed,BYTE byGreen,BYTE byBlue);
三個參數都是位元組型變量,傳回值COLORREF類型,是用DWORD表示的整型數。
1.4.2RGB宏定義
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|
(((DWORD)(BYTE)(b)<<16)))
記憶體原理圖:

1.4.3表示方法
以紅色為例:
(1)RGB(255,0,0):順序為red,green,blue
(2)0x0000FF:順序為blue,green,red,與記憶體原理圖對應
2.使用練習
2.1使用SetPixelV在(100,100)位置處繪制一個紅色像素點,然後讀出該像素點顔色,水準右移100個像素點再繪制一個紅色像素點,在裝置坐标系中程式設計實作。
2.1.1擷取像素點的顔色
函數原型:
COLORREF CDC::GetPixel(int x,int y)const;
COLORREF CDC::GetPixel(POINT point)const;
調用成功傳回指定位置的RGB值,否則傳回-1。
2.1.2程式設計實作
void CExample1View::OnDraw(CDC* pDC)
{
CExample1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此處為本機資料添加繪制代碼
CPoint p0(100, 100);//聲明點
CPoint p1(p0.x + 100, p0.y);
pDC->SetPixelV(p0, RGB(255, 0, 0));//繪制像素點
COLORREF crColor = pDC->GetPixel(p0);//擷取像素點顔色
pDC->SetPixelV(p1,crColor);
}
2.2使用SetPixelV,将顔色設定為随機色,在x軸正向繪制左下角為(50,-50),右上角為(150,50)的正方形點集,然後讀出該正方形每個像素點顔色,在x軸負向對稱位置重新繪制該正方形。
因為繪圖範圍不止第一象限,是以需要在客戶區自建坐标系,采用之前的代碼在客戶區中心建立x正向右、y正向上的坐标系。因為x坐标和y坐标是互相獨立的,是以嵌套循環中x和y的順序可以交換,結合循環變量的設定,可以實作不同的動畫效果。
void CExample1View::OnDraw(CDC* pDC)
{
CExample1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此處為本機資料添加繪制代碼
CRect rect;
GetClientRect(rect);
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetWindowExt(rect.Width(), rect.Height());
pDC->SetViewportExt(rect.Width(), -rect.Height());
pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);
rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);
srand((unsigned)time(NULL));//防止獲得的随機數重複,time傳回系統時間的秒數
COLORREF crColor;
for (int x = 50; x < 150; ++x)//從左往右
for (int y = -50; y < 50; ++y)//一列一列畫,從下往上
pDC->SetPixelV(x, y, RGB(rand() % 256,
rand() % 256, rand() % 256));
for(int x = 50; x < 150; ++x)//對應x'從-50到-150,從右往左
for (int y = -50; y < 50; ++y) {
crColor = pDC->GetPixel(x, y);
pDC->SetPixelV(-x, y, crColor);
}
}