MFC繪圖(轉載)
LONG x;
LONG y;
LONG left;
LONG top;
LONG right;
LONG bottom;
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 );
BOOL PtInRect( POINT point ) const;
CRect rect( 10, 10, 371, 267 );
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
// TODO: Add your message handler code here and/or call default
CView::OnSize(nType, cx, cy);
<!--[if !supportLists]-->l <!--[endif]-->SIZE_MAXIMIZED(窗口已被最大化)
<!--[if !supportLists]-->l <!--[endif]-->SIZE_MINIMIZED(窗口已被最小化)
<!--[if !supportLists]-->l <!--[endif]-->SIZE_RESTORED(窗口已被改變大小)
<!--[if !supportLists]-->l <!--[endif]-->SIZE_MAXHIDE(其他窗口被最大化)
<!--[if !supportLists]-->l <!--[endif]-->SIZE_MAXSHOW(其他窗口從最大化還原)
void GetClientRect( LPRECT lpRect ) const;
在Windows中,繪圖使用的是MFC的DC(Device-Context, 設備上下文)類CDC中各種繪圖函數。
CDC* GetDC( );
int ReleaseDC( CDC* pDC ); // 成功返回非0
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
pDC->SelectObject(new CPen(PS_SOLID, 0, RGB(255, 0, 0)));
LPCTSTR AFXAPI AfxRegisterWndClass( UINT nClassStyle, HCURSOR hCursor = 0,
HBRUSH hbrBackground = 0, HICON hIcon = 0 );
cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS | CS_HREDRAW |
CS_VREDRAW | CS_CLASSDC, 0,
return CView::PreCreateWindow(cs);
HDC GetSafeHdc();
來獲取CD所對應窗口(如客戶區)的安全DC句柄,該句柄在窗口存在期間一直是有效的。例如,可先定義類變量HDC m_hDC;,再在適當的地方給它賦值m_hDC = GetDC()->GetSafeHdc();,然后就可以放心地使用了。例如,可以使用CDC類的成員函數
BOOL Attach(HDC hDC); // 成功返回非0
typedef DWORD COLORREF; // 0x00bbggrr
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
BYTE bRed, // red component of color
BYTE bBlue // blue component of color
COLORREF red, gray;
red = RGB(255, 0, 0);
gray = RGB(128, 128,128);
#define GetRValue(rgb) (LOBYTE(rgb))
#define GetGValue(rgb) (LOBYTE(((WORD)(rgb)) >> 8))
#define GetBValue(rgb) (LOBYTE((rgb)>>16))
typedef ULONG_PTR DWORD_PTR;
pDC->SetPixel(10, 10, RGB(0, 255, 0));
<!--[if !supportLists]-->l <!--[endif]-->創建筆對象:創建筆類CPen對象的方法有如下兩種:
<!--[if !supportLists]-->n <!--[endif]-->使用構造函數CPen
CPen( int nPenStyle, int nWidth, COLORREF crColor );
<!--[if !supportLists]-->u <!--[endif]-->nPenStyle為筆的風格,可取值:
PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PSDASHDOTDOT
<!--[if !supportLists]-->u <!--[endif]-->nWidth為筆寬,與映射模式有關,使用缺省映射時為像素數,若nWidth = 0,則不論什么映射模式,筆寬都為一個像素;
<!--[if !supportLists]-->u <!--[endif]-->crColor為筆的顏色值。
<!--[if !supportLists]-->n <!--[endif]-->使用成員函數CreatePen
BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor );
<!--[if !supportLists]-->n <!--[endif]-->缺省的筆為單像素寬的實心黑色筆
<!--[if !supportLists]-->l <!--[endif]-->將筆對象選入設備上下文:為了能使用我們所創建的筆對象,必須先將它選入設備上下文,這可以調用設備上下文類CDC的成員函數SelectObject來完成:
<!--[if !supportLists]-->l <!--[endif]-->使用設備上下文畫線狀圖:畫線狀圖以及面狀圖的邊線,所使用的是當前設備上下文中的筆對象。線狀圖有直線、折線、矩形、(橢)圓(弧)等,詳見4)(2)
<!--[if !supportLists]-->l <!--[endif]-->將筆對象從設備上下文中放出:為了能刪除使用過的筆對象,必須先將它從設備上下文中釋放出來后,然后才能刪除。釋放的方法是裝入其他的筆對象(一般是重新裝入原來的筆對象)。例如
<!--[if !supportLists]-->l <!--[endif]-->刪除筆對象:為了能刪除筆對象,必須先將其從設備上下文中釋放。刪除方法有如下幾種:
<!--[if !supportLists]-->n <!--[endif]-->調用筆類CDC的成員函數DeleteObject刪除筆的當前內容(但是未刪除筆對象,以后可再用成員函數CreatePen在筆對象中繼續創建新的筆內容)。如
<!--[if !supportLists]-->n <!--[endif]-->使用刪除運算符delete將筆對象徹底刪除,如delete pen;
<!--[if !supportLists]-->n <!--[endif]-->自動刪除:若筆對象為局部變量,則在離開其作用域時,會被系統自動刪除
for (int j = 0; j <= 255; j++) {
HSLtoRGB(m_hue, m_sat, 255 - j, r, g, b); // 自定義的函數
pen.CreatePen(PS_SOLID, 0, RGB(r, g, b));
pOldPen = pDC->SelectObject(&pen);
pDC->MoveTo(0, j); pDC->LineTo(40, j);
<!--[if !supportLists]-->l <!--[endif]-->構造函數有4個:
<!--[if !supportLists]-->n <!--[endif]-->CBrush( ); // 創建一個刷的空對象
<!--[if !supportLists]-->n <!--[endif]-->CBrush( COLORREF crColor ); // 創建顏色為crColor的實心刷
<!--[if !supportLists]-->n <!--[endif]-->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
|
斜十字線(斜網格)
|
<!--[if !supportLists]-->n <!--[endif]-->CBrush( CBitmap* pBitmap ); // 創建位圖為pBitmap的圖案刷
如:pDC->FillRect( &rect, new CBrush( RGB(r, g, b) ) );
<!--[if !supportLists]-->l <!--[endif]-->與構造函數相對應,有多個創建不同類型刷的成員函數:
<!--[if !supportLists]-->n <!--[endif]-->BOOL CreateSolidBrush( COLORREF crColor );
<!--[if !supportLists]-->n <!--[endif]-->BOOL CreateHatchBrush( int nIndex, COLORREF crColor );
<!--[if !supportLists]-->n <!--[endif]-->BOOL CreatePatternBrush( CBitmap* pBitmap );
<!--[if !supportLists]-->n <!--[endif]-->BOOL CreateDIBPatternBrush( HGLOBAL hPackedDIB, UINT nUsage );
<!--[if !supportLists]-->n <!--[endif]-->BOOL CreateDIBPatternBrush( const void* lpPackedDIB, UINT nUsage );
<!--[if !supportLists]-->n <!--[endif]-->BOOL CreateBrushIndirect( const LOGBRUSH* lpLogBrush );
<!--[if !supportLists]-->n <!--[endif]-->BOOL CreateSysColorBrush( int nIndex );
<!--[if !supportLists]-->l <!--[endif]-->預定義的刷對象有BLACK_BRUSH(黑刷)、DKGRAY_BRUSH(暗灰刷)、GRAY_BRUSH(灰刷)、HOLLOW_BRUSH(空刷)、LTGRAY_BRUSH(亮灰刷)、NULL_BRUSH(空刷)、WHITE_BRUSH(白刷)
<!--[if !supportLists]-->l <!--[endif]-->缺省的刷為空刷
<!--[if !supportLists]-->l <!--[endif]-->與筆一樣,可以用函數SelectObject或SelectStockObject將自定義的刷或預定義的刷選入DC中,供繪面狀圖時使用。
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");
Windows的圖形設備接口(GDI = graphics device interface)對象指各種繪圖工具,如筆、刷、位圖、字體、調色板、區域等,對應的MFC類為CPen、CBrush、CBitmap、CFont等。這些圖形繪制對象類都是CGDIObject的派生類,而CGDIObject則是直接從CObject類派生的抽象基類。<!--[endif]-->其中,Windws CE不支持調色板類CPalette;CRgn為區域類,對應于窗口中的一個矩形、多邊形或(橢)圓區域(region),可用于移動、拷貝、合并、判斷和裁剪。
HDC hdc, // handle to device context
UINT uObjectType // specifies the object-type
OBJ_PEN // Returns the current selected pen.
OBJ_PAL // Returns the current selected palette.
OBJ_FONT // Returns the current selected font.
CPen* GetCurrentPen( ) const;
CBrush* GetCurrentBrush( ) const;
CFont* GetCurrentFont( ) const;
CBitmap* GetCurrentBitmap( ) const;
CPalette* GetCurrentPalette( ) const;
HPEN hPen = (HPEN)GetCurrentObject(pDC->m_hDC, OBJ_PEN);
CPen* pPen = CPen::FromHandle(hPen);
CPen* pPen = pDC-> GetCurrentPen( );
缺省情況下,繪圖的默認映射模式為MM_TEXT,其繪圖單位為像素(只要不打印輸出,屏幕繪圖使用該模式就夠了)。若窗口客戶區的寬和高分別為w和h像素,則其x坐標是從左到右,范圍為0 ~ w-1;y坐標是從上到下,范圍為0 ~ h-1。
virtual int SetMapMode( int nMapMode ); // 返回先前的映射模式
符號常量
|
數字常量
|
x方向
|
y方向
|
邏輯單位的大小
|
MM_TEXT
|
1
|
向右
|
向下
|
像素
|
MM_LOMETRIC
|
2
|
向右
|
向上
|
0.1 mm
|
MM_HIMETRIC
|
3
|
向右
|
向上
|
0.01 mm
|
MM_LOENGLISH
|
4
|
向右
|
向上
|
0.01 in
|
MM_HIENGLISH
|
5
|
向右
|
向上
|
0.001 in
|
MM_TWIPS
|
6
|
向右
|
向上
|
1/1440 in
|
MM_ISOTROPIC
|
7
|
自定義
|
自定義
|
自定義
|
MM_ANISOTROPIC
|
8
|
自定義
|
自定義
|
自定義
|
virtual CSize SetWindowExt( int cx, int cy );
virtual CSize SetViewportExt( int cx, int cy );
pDC->SetViewportExt(rect.right, -rect.bottom);
pDC->SetViewportOrg(rect.right / 2, rect.bottom /2);
pDC->Ellipse(CRect(-500, -500, 500, 500));
<!--[if !supportLists]-->l <!--[endif]-->CDC的成員函數(如各種繪圖函數)具有邏輯坐標參數
<!--[if !supportLists]-->l <!--[endif]-->CWnd的成員函數(如各種響應函數)具有設備坐標參數(如鼠標位置point)
<!--[if !supportLists]-->l <!--[endif]-->位置的測試操作(如CRect的PtInRect函數)只有使用設備坐標時才有效
<!--[if !supportLists]-->l <!--[endif]-->長期使用的值應該用邏輯坐標保存(如窗口滾動后保存的設備坐標就無效了)
void LPtoDP( LPPOINT lpPoints, int nCount = 1 ) const;
void DPtoLP( LPPOINT lpPoints, int nCount = 1 ) const;
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point) {
CRect rect = m_rect; // 邏輯坐標
if (rect.PtInRect(point)) // 位置的測試操作只有使用設備坐標時才有效
void CDrawView:: OnMouseMove (UINT nFlags, CPoint point) {
float t,y;
CDC* pDC = GetDC();
t = t1 + (point.x * dt) / w; sprintf(buf, "%.4fs", t); pSB->SetPaneText(xV, buf);
COLORREF SetPixel( int x, int y, COLORREF crColor ); 或
COLORREF SetPixel( POINT point, COLORREF crColor );
pDC->SetPixel(i, j, RGB(r, g, b));
<!--[if !supportLists]-->l <!--[endif]-->當前位置:設置當前位置為(x, y)或point:(返回值為原當前位置的坐標)
CPoint MoveTo( int x, int y ); 或 CPoint MoveTo( POINT point );
<!--[if !supportLists]-->l <!--[endif]-->畫線:使用DC中的筆從當前位置畫線到點(x, y)或point:(若成功返回非0值):
<!--[if !supportLists]-->l <!--[endif]-->畫折線:使用DC中的筆,依次將點數組lpPoints中的nCount(≥2)個點連接起來,形成一條折線:
<!--[if !supportLists]-->l <!--[endif]-->畫多邊形:似畫折線,但還會將最后的點與第一個點相連形成多邊形,并用DC中的刷填充其內部區域:
<!--[if !supportLists]-->l <!--[endif]-->畫矩形:使用DC中的筆畫左上角為(x1, y1)、右下角為(x2, y2)或范圍為*lpRect的矩形的邊線,并用DC中的刷填充其內部區域:
rect = CRect(min(p0.x, point.x), min(p0.y, point.y), max(p0.x, point.x), max(p0.y, point.y));
<!--[if !supportLists]-->l <!--[endif]-->畫圓角矩形:使用DC中的筆畫左上角為(x1, y1)、右下角為(x2, y2)或范圍為*lpRect的矩形的邊線,并用寬x3或point.x高y3或point.y矩形的內接橢圓倒角,再用DC中的刷填充其內部區域:
int d = min(rect.Width(), rect.Height()) / 4;
<!--[if !supportLists]-->l <!--[endif]-->畫(橢)圓:使用DC中的筆在左上角為(x1, y1)、右下角為(x2, y2)或范圍為*lpRect的矩形中畫內接(橢)圓的邊線,并用DC中的刷填充其內部區域:
<!--[if !supportLists]-->l <!--[endif]-->畫弧:(x1, y1)與(x2, y2)或lpRect的含義同畫(橢)圓,(x3, y3)或ptStart為弧的起點,(x4, y4)或ptEnd為弧的終點:(逆時針方向旋轉)
BOOL Arc( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 );
BOOL ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
BOOL AngleArc(int x, int y, int nRadius, float fStartAngle, float fSweepAngle);
<!--[if !supportLists]-->l <!--[endif]-->畫弓弦:參數的含義同上,只是用一根弦連接弧的起點和終點,形成一個弓形,并用DC中的刷填充其內部區域:
BOOL Chord( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 );
<!--[if !supportLists]-->l <!--[endif]-->畫填充矩形:用指定的刷pBrush畫一個以lpRect為區域的填充矩形,無邊線,填充區域包括矩形的左邊界和上邊界,但不包括矩形的右邊界和下邊界:
<!--[if !supportLists]-->l <!--[endif]-->畫單色填充矩形:似FillRect,但只能填充單色,不能填充條紋和圖案:
<!--[if !supportLists]-->l <!--[endif]-->畫餅圖(扇形):參數含義同Arc,但將起點和終點都與外接矩形的中心相連接,形成一個扇形區域,用DC中的刷填充整個扇形區域,無另外的邊線:
BOOL Pie( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 );
<!--[if !supportLists]-->l <!--[endif]-->畫拖動的矩形:先擦除線寬為sizeLast、填充刷為pBrushLast的原矩形lpRectLast,然后再以線寬為size、填充刷為pBrush畫新矩形lpRectLast。矩形的邊框用灰色的點虛線畫,缺省的填充刷為空刷:
void DrawDragRect( LPCRECT lpRect, SIZE size, LPCRECT lpRectLast,
SIZE sizeLast, CBrush* pBrush = NULL, CBrush* pBrushLast = NULL );
如:pDC->DrawDragRect(rect, size, rect0, size);
<!--[if !supportLists]-->l <!--[endif]-->填充區域:
<!--[if !supportLists]-->n <!--[endif]-->用當前刷從點(x, y)開始向四周填充到顏色為crColor的邊界:
BOOL FloodFill(int x, int y, COLORREF crColor); // 成功返回非0
<!--[if !supportLists]-->n <!--[endif]-->用當前刷從點(x, y)開始向四周填充:
BOOL ExtFloodFill(int x, int y, COLORREF crColor,
UINT nFillType); // 成功返回非0
pDC->ExtFloodFill(point.x, point.y, pDC->GetPixel(point), FLOODFILLSURFACE);
LPCRECT lpRectUpdate = NULL,
UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE
pDC->FillSolidRect(&rect, RGB(255, 255, 255));
CDC* GetDC( );
// 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); // 自定義函數,見網絡硬盤的
pDC->SetPixel(i, j, RGB(r, g, b));
CWnd* pWnd = GetDlgItem(IDC_COLOR);
CDC* pDC = pWnd->GetDC();
CRect rect;
<!--[if !supportLists]-->l <!--[endif]-->除了基于對話框的程序外,其他對話框類都需要自己添加(重寫型)消息響應函數OnInitDialog,來做一些必要的初始化對話框的工作。添加方法是:先在項目區選中“類視圖”頁,再選中對應的對話框類,然后在屬性窗口的“重寫”頁中添加該函數;
<!--[if !supportLists]-->l <!--[endif]-->為了使在運行時能夠不斷及時更新控件的顯示(主要是自己加的顯式代碼),可以將自己繪制控件的所有代碼都全部加入對話框類的消息響應函數OnPaint中。在需要時(例如在繪圖參數修改后),自己調用CWnd的Invalidate和UpdateWindow函數,請求系統刷新對話框和控件的顯示。因為控件也是窗口,控件類都是CWnd的派生類。所以在對話框和控件中,可以像在視圖類中一樣,調用各種CWnd的成員函數。
<!--[if !supportLists]-->l <!--[endif]-->一般的對話框類,缺省時都沒有明寫出OnPaint函數。可以自己在對話框類中添加WM_PAINT消息的響應函數OnPaint來進行一些繪圖工作。
<!--[if !supportLists]-->l <!--[endif]-->為了在鼠標指向按鈕時,讓按鈕上自己繪制的圖形不被消去,可以設置按鈕控件的“Owner Draw”屬性為“True”。
<!--[if !supportLists]-->l <!--[endif]-->如果希望非按鈕控件(如圖片控件和靜態文本等),也可以響應鼠標消息(如單擊、雙擊等),需要設置控件的“Notify”屬性為“True”。
<!--[if !supportLists]-->l <!--[endif]-->使用OnPaint函數在對話框客戶區的空白處(無控件的地方)繪制自己的圖形,必須屏蔽掉其中缺省的對對話框基類的OnPaint函數的調用:
<!--[if !supportLists]-->l <!--[endif]-->對話框的背景色,可以用CWnd類的成員函數:
CColorDialog colDlg(m_crLineColor);
if (colDlg.DoModal() == IDOK) {
m_crLineColor = colDlg.GetColor();
CPaintDC dc(this); // device context for painting
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));
pDC->RoundRect(&rect, CPoint(8, 8));
void CSetDlg::ShowImg(UINT ID, HBITMAP hBmp)
CWnd* pWnd = GetDlgItem(ID);
CDC* pDC = pWnd->GetDC();
GetObject(hBmp, sizeof(bs), &bs);
if(dc.CreateCompatibleDC(pDC)) {
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;
y0 = 0; h = rect.bottom;
w = (int)(bs.bmWidth / ry + 0.5);
x0 = (rect.right - w) / 2;
::SelectObject(dc.GetSafeHdc(), hBmp);
pDC->StretchBlt(x0, y0, w, h, &dc, 0, 0, bs.bmWidth, bs.bmHeight, SRCCOPY);
SetDlgItemInt(IDC_W, bs.bmWidth);
SetDlgItemInt(IDC_H, bs.bmHeight);
nBkMode值
|
名稱
|
作用
|
OPAQUE
|
不透明的(缺省值)
|
空隙用背景色填充
|
TRANSPARENT
|
透明的
|
空隙處保持原背景圖不變
|
int SetROP2( int 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)
|
pGrayPen = new CPen(PS_DOT, 0, RGB(128, 128, 128));
<!--[if !supportLists]-->l <!--[endif]-->多邊形填充方式:可使用CDC類的成員函數GetPolyFillMode和SetPolyFillMode來確定多邊形的填充方式:
<!--[if !supportLists]-->l <!--[endif]-->畫弧方向:可使用CDC類的成員函數GetArcDirection和SetArcDirection來確定Arc、Chord、Pie等函數的畫弧方向:
<!--[if !supportLists]-->l <!--[endif]-->刷原點:可使用CDC類的成員函數GetBrushOrg和SetBrushOrg來確定可填充繪圖函數的條紋或圖案刷的起點:(缺省值為客戶區左上角的坐標原點(0, 0))
BOOL m_bLButtonDown, m_bErase; // 判斷是否按下左鼠標鍵
CPoint p0, pm; // 記錄直線起點和動態終點的類變量
CPen * pGrayPen, * pLinePen; // 定義灰色和直線筆
m_bLButtonDown = FALSE; // 設左鼠標鍵按下為假
m_bErase = FALSE; // 設需要擦除為假
pGrayPen = new CPen(PS_SOLID, 0, RGB(128, 128, 128));// 創建灰色筆
pLinePen = new CPen(PS_SOLID, 0, RGB(255, 0, 0));// 創建紅色的直線筆
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point) {
m_bLButtonDown = TRUE; // 設左鼠標鍵按下為真
SetCapture(); // 設置鼠標捕獲
// SetCursor(LoadCursor(NULL, IDC_CROSS)); // 設置鼠標為十字
p0 = point; // 保存矩形左上角
CView::OnLButtonDown(nFlags, point);
void CDrawView::OnMouseMove(UINT nFlags, CPoint point) {
SetCursor(LoadCursor(NULL, IDC_CROSS)); // 設置鼠標為十字
if (m_bLButtonDown) { // 左鼠標鍵按下為真
CDC* pDC = GetDC(); // 獲取設備上下文
if (m_bErase) { // 需要擦除為真
pDC->MoveTo(p0); pDC->LineTo(pm); // 擦除原直線
else // 需要擦除為假
pDC->MoveTo(p0); pDC->LineTo(point); // 繪制新直線
pm = point; // 記錄老終點
ReleaseDC(pDC); // 釋放設備上下文
CView::OnMouseMove(nFlags, point);
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point) {
ReleaseCapture(); // 釋放鼠標捕獲
if (m_bLButtonDown) { // 左鼠標鍵按下為真
CDC* pDC = GetDC(); // 獲取設備上下文
pDC->MoveTo(p0); pDC->LineTo(pm); // 擦除原直線
pDC->MoveTo(p0); pDC->LineTo(point); // 繪制最終的直線
m_bLButtonDown = FALSE; // 重設左鼠標鍵按下為假
m_bErase = FALSE; // 重需要擦除為假
ReleaseDC(pDC); // 釋放設備上下文
CView::OnLButtonUp(nFlags, point);
posted on 2009-05-17 16:22 極品垃圾 閱讀(33813) 評論(0) 編輯 收藏 引用 所屬分類: vc