小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

VC-MFC畫圖3

 杰杰梅梅一生一世 2011-08-30

5.清屏

Windows沒有提供專門的清屏函數(shù),可以調(diào)用CWnd的下面兩個函數(shù)調(diào)用來完成該功能:

void Invalidate(BOOL bErase = TRUE);

void UpdateWindow( );

或調(diào)用CWnd的函數(shù)

BOOL RedrawWindow(

LPCRECT lpRectUpdate = NULL,

CRgn* prgnUpdate = NULL,

UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE

);

來完成。

例如(菜單項(xiàng)ID_CLEAR的事件處理函數(shù)):

CDrawView::OnClear() { // 調(diào)用OnDraw來清屏

//Invalidate();

//UpdateWindow( );

RedrawWindow( );

}

也可以用畫填充背景色矩形的方法來清屏,如:

RECT rect;

GetClientRect(&rect);

pDC->FillSolidRect(&rect, RGB(255, 255, 255));

6.在控件上繪圖

可以在對話框資源中放置圖片控件,并對其類型屬性選Frame??稍趯υ捒虻睦L圖消息響應(yīng)函數(shù)OnPaint或其他函數(shù)中,用CWnd類的函數(shù)GetDlgItem:

CWnd* GetDlgItem( int nID ) const;

來獲得圖片控件的窗口對象,再用函數(shù)GetDC:

CDC* GetDC( );

由窗口對象得到DC,然后就可以用該DC在控件中畫圖。如(在ID為IDC_HUESAT的圖片控件上畫調(diào)色板)

void CColorDlg::OnPaint()

{

if (IsIconic()) {

... ...

}

else {

CDialog::OnPaint();

int i, j;

BYTE r, g, b;

// get control window and DC of Hue&Saturation

CWnd *pWin = GetDlgItem(IDC_HUESAT);

CDC *pDC = pWin->GetDC();

// draw hue-saturation palette

for (i = 0; i < 360; i++)

for (j = 0; j <= 255; j++) {

HSLtoRGB(i, 255 - j, 128, r, g, b); // 自定義函數(shù),見網(wǎng)絡(luò)硬盤的

// res目錄中的ColTrans.cpp文件

pDC->SetPixel(i, j, RGB(r, g, b));

}

... ...

}

}

在非Frame類靜態(tài)控件上繪圖,必須先按順序依次調(diào)用CWnd類的Invalidate和UpdateWindow函數(shù)后,再開始用DC畫圖。如在一個ID為IDC_COLOR的按鈕上繪圖:

void CComDlgDlg::DrawColor()

{

CWnd* pWnd = GetDlgItem(IDC_COLOR);

CDC* pDC = pWnd->GetDC();

CRect rect;

pWnd->GetClientRect(&rect);

pWnd->Invalidate();

pWnd->UpdateWindow();

pDC->FillRect(&rect, new CBrush(m_crCol));

}

若干說明:

<!--[if !supportLists]-->l <!--[endif]-->除了基于對話框的程序外,其他對話框類都需要自己添加(重寫型)消息響應(yīng)函數(shù)OnInitDialog,來做一些必要的初始化對話框的工作。添加方法是:先在項(xiàng)目區(qū)選中“類視圖”頁,再選中對應(yīng)的對話框類,然后在屬性窗口的“重寫”頁中添加該函數(shù);

<!--[if !supportLists]-->l <!--[endif]-->為了使在運(yùn)行時能夠不斷及時更新控件的顯示(主要是自己加的顯式代碼),可以將自己繪制控件的所有代碼都全部加入對話框類的消息響應(yīng)函數(shù)OnPaint中。在需要時(例如在繪圖參數(shù)修改后),自己調(diào)用CWnd的Invalidate和UpdateWindow函數(shù),請求系統(tǒng)刷新對話框和控件的顯示。因?yàn)榭丶彩谴翱?,控件類都是CWnd的派生類。所以在對話框和控件中,可以像在視圖類中一樣,調(diào)用各種CWnd的成員函數(shù)。

<!--[if !supportLists]-->l <!--[endif]-->一般的對話框類,缺省時都沒有明寫出OnPaint函數(shù)??梢宰约涸趯υ捒蝾愔刑砑覹M_PAINT消息的響應(yīng)函數(shù)OnPaint來進(jìn)行一些繪圖工作。

<!--[if !supportLists]-->l <!--[endif]-->為了在鼠標(biāo)指向按鈕時,讓按鈕上自己繪制的圖形不被消去,可以設(shè)置按鈕控件的“Owner Draw”屬性為“True”。

<!--[if !supportLists]-->l <!--[endif]-->如果希望非按鈕控件(如圖片控件和靜態(tài)文本等),也可以響應(yīng)鼠標(biāo)消息(如單擊、雙擊等),需要設(shè)置控件的“Notify”屬性為“True”。

<!--[if !supportLists]-->l <!--[endif]-->使用OnPaint函數(shù)在對話框客戶區(qū)的空白處(無控件的地方)繪制自己的圖形,必須屏蔽掉其中缺省的對對話框基類的OnPaint函數(shù)的調(diào)用:

//CDialog::OnPaint();

<!--[if !supportLists]-->l <!--[endif]-->對話框的背景色,可以用CWnd類的成員函數(shù):

DWORD GetSysColor( int nIndex);

得到,其中的nIndex取為COLOR_BTNFACE。例如:

dc.SetBkColor(GetSysColor(COLOR_BTNFACE));

下面是部分例子代碼:(其中FillColor和ShowImg為自定義的成員函數(shù))

void CSetDlg::OnBnClickedPenColor()

{

// TODO: 在此添加控件通知處理程序代碼

CColorDialog colDlg(m_crLineColor);

if (colDlg.DoModal() == IDOK) {

m_crLineColor = colDlg.GetColor();

Invalidate();

UpdateWindow();

}

}

// ……

void CSetDlg::OnPaint()

{

CPaintDC dc(this); // device context for painting

// TODO: 在此處添加消息處理程序代碼

// 不為繪圖消息調(diào)用 CDialog::OnPaint()

FillColor(IDC_PEN_COLOR, m_crLineColor);

FillColor(IDC_BRUSH_COLOR, m_crBrushColor);

if(m_pBitmap0 != NULL) ShowImg(IDC_BRUSH_IMG, m_hBmp0);

else if(m_pBitmap != NULL) ShowImg(IDC_BRUSH_IMG, m_hBmp);

}

void CSetDlg::FillColor(UINT id, COLORREF col)

{

CWnd* pWnd = GetDlgItem(id);

CDC* pDC = pWnd->GetDC();

pDC->SelectObject(new CPen(PS_SOLID, 1, RGB(0, 0, 0)));

pDC->SelectObject(new CBrush(col));

CRect rect;

pWnd->GetClientRect(&rect);

pWnd->Invalidate();

pWnd->UpdateWindow();

pDC->RoundRect(&rect, CPoint(8, 8));

}

void CSetDlg::ShowImg(UINT ID, HBITMAP hBmp)

{

CWnd* pWnd = GetDlgItem(ID);

CDC* pDC = pWnd->GetDC();

CRect rect;

pWnd->GetClientRect(&rect);

pWnd->Invalidate();

pWnd->UpdateWindow();

BITMAP bs;

GetObject(hBmp, sizeof(bs), &bs);

CDC dc;

if(dc.CreateCompatibleDC(pDC)) {

int x0, y0, w, h;

float rx = (float)bs.bmWidth / rect.right,

ry = (float)bs.bmHeight / rect.bottom;

if (rx >= ry) {

x0 = 0; w = rect.right;

h = (int)(bs.bmHeight / rx + 0.5);

y0 = (rect.bottom - h) / 2;

}

else {

y0 = 0; h = rect.bottom;

w = (int)(bs.bmWidth / ry + 0.5);

x0 = (rect.right - w) / 2;

}

::SelectObject(dc.GetSafeHdc(), hBmp);

pDC->SetStretchBltMode(HALFTONE);

pDC->StretchBlt(x0, y0, w, h, &dc, 0, 0, bs.bmWidth, bs.bmHeight, SRCCOPY);

SetDlgItemInt(IDC_W, bs.bmWidth);

SetDlgItemInt(IDC_H, bs.bmHeight);

}

}

//……

5 設(shè)置繪圖屬性

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

1.背景

1)背景色

當(dāng)背景模式為不透明時,背景色決定線狀圖的空隙顏色(如虛線中的空隙、條紋刷的空隙和文字的空隙),可以使用CDC類的成員函數(shù)GetBkColor和SetBkColor來獲得和設(shè)置當(dāng)前的背景顏色:

COLORREF GetBkColor( ) const; // 返回當(dāng)前的背景色

virtual COLORREF SetBkColor( COLORREF crColor ); // 返回先前的背景色

// 若出錯返回0x80000000

2)背景模式

背景模式影響有空隙的線狀圖的空隙(如虛線中的空隙、條紋刷的空隙和文字的空隙)用什么辦法填充??梢允褂肅DC類的成員函數(shù)GetBkMode和SetBkMode來獲得和設(shè)置當(dāng)前的背景模式:

int GetBkMode( ) const; // 返回當(dāng)前背景模式

int SetBkMode( int nBkMode ); // 返回先前背景模式

背景模式的取值

nBkMode值 名稱 作用

OPAQUE 不透明的(缺省值) 空隙用背景色填充

TRANSPARENT 透明的 空隙處保持原背景圖不變

2. 繪圖模式

繪圖模式(drawing mode)指前景色的混合方式,它決定新畫圖的筆和刷的顏色(pbCol)如何與原有圖的顏色(scCol)相結(jié)合而得到結(jié)果像素色(pixel)。

1)設(shè)置繪圖模式

可使用CDC類的成員函數(shù)SetROP2 (ROP = Raster OPeration光柵操作)來設(shè)置繪圖模式:

int SetROP2( int nDrawMode );

其中,nDrawMode可取值:

繪圖模式nDrawMode的取值

符號常量 作用 運(yùn)算結(jié)果

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(異或)較常用。

2)畫移動圖形

為了能畫移動的位置標(biāo)識(如十字、一字)和隨鼠標(biāo)移動畫動態(tài)圖形(如直線、矩形、橢圓),必須在不破壞原有背景圖形的基礎(chǔ)上移動這些圖形。

移動圖形采用的是異或畫圖方法,移動圖形的過程為:異或畫圖、在原位置再異或化圖(擦除)、在新位置異或畫圖、……。

pGrayPen = new CPen(PS_DOT, 0, RGB(128, 128, 128));

pDC->SetBkMode(TRANSPARENT);

pOldPen = pDC->SelectObject(pGrayPen);

pDC->SelectStockObject(NULL_BRUSH);

pDC->SetROP2(R2_XORPEN);

if (m_bErase) pDC->Ellipse(rect0);

pDC->Ellipse(rect);

pDC->SetROP2(R2_COPYPEN);

pDC->SelectObject(pOldPen);

rect0 = rect;

較完整的拖放動態(tài)畫圖的例子,可參照下面的“3. 拖放畫動態(tài)直線”部分。

3)其他屬性

<!--[if !supportLists]-->l <!--[endif]-->多邊形填充方式:可使用CDC類的成員函數(shù)GetPolyFillMode和SetPolyFillMode來確定多邊形的填充方式:

int GetPolyFillMode( ) const;

int SetPolyFillMode( int nPolyFillMode );

其中nPolyFillMode 可取值A(chǔ)LTERNATE(交替——填充奇數(shù)邊和偶數(shù)邊之間的區(qū)域,缺省值)或WINDING(纏繞——根據(jù)多邊形邊的走向來確定是否填充一區(qū)域)

<!--[if !supportLists]-->l <!--[endif]-->畫弧方向:可使用CDC類的成員函數(shù)GetArcDirection和SetArcDirection來確定Arc、Chord、Pie等函數(shù)的畫弧方向:

int GetArcDirection( ) const;

int SetArcDirection( int nArcDirection );

其中,nArcDirection可取值A(chǔ)D_COUNTERCLOCKWISE(逆時針方向,缺省值)和AD_CLOCKWISE(順時針方向)

<!--[if !supportLists]-->l <!--[endif]-->刷原點(diǎn):可使用CDC類的成員函數(shù)GetBrushOrg和SetBrushOrg來確定可填充繪圖函數(shù)的條紋或圖案刷的起點(diǎn):(缺省值為客戶區(qū)左上角的坐標(biāo)原點(diǎn)(0, 0))

CPoint GetBrushOrg( ) const;

CPoint SetBrushOrg( int x, int y );

CPoint SetBrushOrg( POINT point );

3.拖放畫動態(tài)直線

下面是一個較完整的拖放動態(tài)畫直線的例子:

// 類變量

class CDrawView : public CView {

//……

protected:

BOOL m_bLButtonDown, m_bErase; // 判斷是否按下左鼠標(biāo)鍵

//和是否需要擦除圖形的類變量

CPoint p0, pm; // 記錄直線起點(diǎn)和動態(tài)終點(diǎn)的類變量

CPen * pGrayPen, * pLinePen; // 定義灰色和直線筆

//……

}

// 構(gòu)造函數(shù)

CDrawView::CDrawView() {

m_bLButtonDown = FALSE; // 設(shè)左鼠標(biāo)鍵按下為假

m_bErase = FALSE; // 設(shè)需要擦除為假

pGrayPen = new CPen(PS_SOLID, 0, RGB(128, 128, 128));// 創(chuàng)建灰色筆

pLinePen = new CPen(PS_SOLID, 0, RGB(255, 0, 0));// 創(chuàng)建紅色的直線筆

}

// 鼠標(biāo)消息響應(yīng)函數(shù)

void CDrawView::OnLButtonDown(UINT nFlags, CPoint point) {

m_bLButtonDown = TRUE; // 設(shè)左鼠標(biāo)鍵按下為真

SetCapture(); // 設(shè)置鼠標(biāo)捕獲

// SetCursor(LoadCursor(NULL, IDC_CROSS)); // 設(shè)置鼠標(biāo)為十字

p0 = point; // 保存矩形左上角

pm = p0; // 讓矩形右下角等于左上角

CView::OnLButtonDown(nFlags, point);

}

void CDrawView::OnMouseMove(UINT nFlags, CPoint point) {

SetCursor(LoadCursor(NULL, IDC_CROSS)); // 設(shè)置鼠標(biāo)為十字

if (m_bLButtonDown) { // 左鼠標(biāo)鍵按下為真

CDC* pDC = GetDC(); // 獲取設(shè)備上下文

pDC->SelectObject(pGrayPen);// 選取灰色筆

pDC->SetROP2(R2_XORPEN);// 設(shè)置為異或繪圖方式

if (m_bErase) { // 需要擦除為真

pDC->MoveTo(p0); pDC->LineTo(pm); // 擦除原直線

}

else // 需要擦除為假

m_bErase = TRUE; // 設(shè)需要擦除為真

pDC->MoveTo(p0); pDC->LineTo(point); // 繪制新直線

pm = point; // 記錄老終點(diǎn)

ReleaseDC(pDC); // 釋放設(shè)備上下文

}

CView::OnMouseMove(nFlags, point);

}

void CDrawView::OnLButtonUp(UINT nFlags, CPoint point) {

ReleaseCapture(); // 釋放鼠標(biāo)捕獲

if (m_bLButtonDown) { // 左鼠標(biāo)鍵按下為真

CDC* pDC = GetDC(); // 獲取設(shè)備上下文

pDC->SelectObject(pGrayPen);// 選取灰色筆

pDC->SetROP2(R2_XORPEN); // 設(shè)置為異或繪圖方式

pDC->MoveTo(p0); pDC->LineTo(pm); // 擦除原直線

pDC->SelectObject(pLinePen); // 選擇直線筆

pDC->SetROP2(R2_COPYPEN);// 設(shè)置為覆蓋繪圖方式

pDC->MoveTo(p0); pDC->LineTo(point); // 繪制最終的直線

m_bLButtonDown = FALSE; // 重設(shè)左鼠標(biāo)鍵按下為假

m_bErase = FALSE; // 重需要擦除為假

ReleaseDC(pDC); // 釋放設(shè)備上下文

}

CView::OnLButtonUp(nFlags, point);

}

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多