第四章-简单绘图

来源:互联网 发布:课程表软件 编辑:程序博客网 时间:2024/05/16 09:24

1.在单文档中view挡在MainFrame的前面。此时如果编写针对MainFrame的mouseClick事件,将不会有反应。

 

2.消息响应会在3处修改代码,1处是在头文件中,

//{{AFX_MSG(CDrawView)

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

afx_msg void OnLButtonUp(UINT nFlags, CPoint point);

afx_msg void OnMouseMove(UINT nFlags, CPoint point);

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

另一处是cpp文件的begin MessageMap和End MessageMap之间,

BEGIN_MESSAGE_MAP(CDrawView, CView)

//{{AFX_MSG_MAP(CDrawView)

ON_WM_LBUTTONDOWN()

ON_WM_LBUTTONUP()

ON_WM_MOUSEMOVE()

//}}AFX_MSG_MAP

// Standard printing commands

ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)

ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)

ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)

END_MESSAGE_MAP()

最后是要有函数实现的代码。

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

{

// TOD Add your message handler code here and/or call default

m_ptOrigin=m_ptOld=point;

m_bDraw=TRUE;

CView::OnLButtonDown(nFlags, point);

}

 

3.画线:定义一个成员变量保存mouseDown的点m_Point

 1)API函数方法画线用HDC

 2)用CDC类成员函数画线。此时别忘记ReleaseDC

 3)用CClientDC

 4)用CWindowDC,用它甚至可以整个屏幕区域画线。

下面是上面4种方法的代码

/*HDC hdc;

hdc=::GetDC(m_hWnd);

MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);

LineTo(hdc,point.x,point.y);

::ReleaseDC(m_hWnd,hdc);必须成对使用。*/


/*CDC *pDC=GetDC();

pDC->MoveTo(m_ptOrigin);

pDC->LineTo(point);

ReleaseDC(pDC);必须成对使用。*/


//CClientDC dc(this);

/*CClientDC dc(GetParent());

dc.MoveTo(m_ptOrigin);

dc.LineTo(point);此处不需要ReleaseDC,因为CClientDC会自动释放DC*/


//CWindowDC dc(this);

//CWindowDC dc(GetParent());

/*CWindowDC dc(GetDesktopWindow());//此时可以在整个屏幕上画线。

dc.MoveTo(m_ptOrigin);

dc.LineTo(point);*/


/*CPen pen(PS_DOT,1,RGB(0,255,0));

CClientDC dc(this);

CPen *pOldPen=dc.SelectObject(&pen);

dc.MoveTo(m_ptOrigin);

dc.LineTo(point);

dc.SelectObject(pOldPen);*/

 

 5)用Bitmap填充所画的矩形。

CBitmap bitmap;

bitmap.LoadBitmap(IDB_BITMAP1);

CBrush brush(&bitmap);

CClientDC dc(this);

dc.FillRect(CRect(m_ptOrigin,point),&brush);

//CBRUSH::FromHandle是静态成员函数,所以可以用下面的方法调用。

CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));

CBrush *pOldBrush=dc.SelectObject(pBrush);

dc.Rectangle(CRect(m_ptOrigin,point));

dc.SelectObject(pOldBrush);

m_bDraw=FALSE;

 

 6)用其它颜色画线

CClientDC dc(this);

CPen pen(PS_SOLID,1,RGB(255,0,0));

CPen *pOldPen=dc.SelectObject(&pen);//选中红色画笔

if(m_bDraw==TRUE)

{

 dc.SetROP2(R2_BLACK);//设置绘画模式

 dc.MoveTo(m_ptOrigin);

 //dc.LineTo(point);

 dc.LineTo(m_ptOld);

 //dc.MoveTo(m_ptOrigin);

 dc.MoveTo(m_ptOld);

 dc.LineTo(point);

 //m_ptOrigin=point;

 m_ptOld=point;

}

dc.SelectObject(pOldPen);

4.MFC中隐式的包含了windows.h。为什么?

因为在AFXV_W32.h文件中:

// This is a part of the Microsoft Foundation Classes C++ library.

// Copyright (C) 1992-1998 Microsoft Corporation

// All rights reserved.

在AFXWIN.h中

// Note: WINDOWS.H already included from AFXV_W32.H

 

5.如何从句柄获得对象的指针?

答FromHandle

 

6.类的静态成员函数可以由类名直接调用,也可以由对象调用。可以认为静态成员函数并不属于某个对象,它属于类本身。程序运行伊始,即使没有实例化类的对象,静态成员函数和静态成员变量已然有其内存空间。静态成员函数不能访问非静态成员变量!静态成员变量必须在类的外部初始化。当然如果并不打算用到静态成员变量,此时你可以不初始它。

 

7.理解代码区,数据区,堆,栈!

请见下面的简介:

对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数据区。动态数据区一般就是“堆栈”。“栈(stack)”和“堆(heap)”是两种不同的动态数据区,栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”,所以每个线程虽然代码一样,但本地变量的数据都是互不干扰。一个堆栈可以通过“基地址”和“栈顶”地址来描述。全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。

 

 


具体的代码如下,

其中添加了WM_LBUTTONDOWN,WN_LBUTTONUP,WM_MOUSEMOVE的消息

在CXXView中添加了数据成员CPoint m_orgpt,CPoint m_oldpt,CPoint m_movept

[html] view plain copy
  1. CDrawView::CDrawView()  
  2. {  
  3.     // TODO: add construction code here  
  4.     m_orgpt=0;  
  5.     m_movept=0;  
  6.     flag=FALSE;  
  7. }  

[html] view plain copy
  1. void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)   
  2. {  
  3.     // TODO: Add your message handler code here and/or call default  
  4.     m_orgpt=m_oldpt=point;  
  5.     flag=TRUE;  
  6.     CView::OnLButtonDown(nFlags, point);  
  7. }  

[html] view plain copy
  1. void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)   
  2. {  
  3.     // TODO: Add your message handler code here and/or call default  
  4.     /*HDC hdc;  
  5.     hdc=::GetDC(m_hWnd);  
  6.     ::MoveToEx(hdc,m_orgpt.x,m_orgpt.y,NULL);  
  7.     ::LineTo(hdc,point.x,point.y);  
  8.     ::ReleaseDC(m_hWnd,hdc);*/  
  9.   
  10.     /*CDC *pcdc=GetDC();  
  11.     pcdc->MoveTo(m_orgpt);  
  12.     pcdc->LineTo(point.x,point.y);  
  13.     ReleaseDC(pcdc);*/  
  14.   
  15.     //CClientDC ccdc(this);  
  16. /*  CClientDC ccdc(GetParent());  
  17.     ccdc.MoveTo(m_orgpt);  
  18.     ccdc.LineTo(point);*/  
  19.   
  20.     //CWindowDC cwdc(this);  
  21.     //CWindowDC cwdc(GetParent());  
  22.     /*CWindowDC cwdc(GetDesktopWindow());  
  23.     cwdc.MoveTo(m_orgpt);  
  24.     cwdc.LineTo(point);*/  
  25.   
  26.     /*CPen cp(PS_SOLID,10,RGB(255,0,0));  
  27.     CDC *pcdc=GetDC();  
  28.     pcdc->SelectObject(&cp);  
  29.     pcdc->MoveTo(m_orgpt);  
  30.     pcdc->LineTo(point);  
  31.     ReleaseDC(pcdc);*/  
  32.   
  33.     /*CPen cp(PS_DOT,1,RGB(0,255,0));  
  34.     CClientDC ccdc(this);  
  35.     CPen *pcp=ccdc.SelectObject(&cp);  
  36.     ccdc.MoveTo(m_orgpt);  
  37.     ccdc.LineTo(point);  
  38.     ccdc.SelectObject(pcp);*/  
  39.   
  40.     //CBrush cb(RGB(255,0,0));  
  41.     /*CBrush cb(HS_DIAGCROSS  ,RGB(255,0,0));  
  42.     CClientDC ccdc(this);  
  43.     CBrush *pcb=ccdc.SelectObject(&cb);  
  44.     ccdc.Rectangle(&CRect(m_orgpt,point));  
  45.     ccdc.SelectObject(pcb);*/  
  46.   
  47.     /*CBitmap cbmp;  
  48.     cbmp.LoadBitmap(MAKEINTRESOURCE(BITMAPID));  
  49.     CBrush cbh(&cbmp);  
  50.     CClientDC ccdc(this);  
  51.     //CBrush *pcbh=ccdc.SelectObject(&cbh);//如果下面用Rectangle的话,这一句还有点作用  
  52.     ccdc.FillRect(CRect(m_orgpt,point),&cbh);  
  53.     //ccdc.SelectObject(pcbh);//如果上面使用了Rectangle来填充颜色,则要把原来的画刷设置回来*/  
  54.   
  55.     /*CClientDC ccdc(this);  
  56.     ccdc.Rectangle(&CRect(m_orgpt,point));//这里使用默认白画刷*/  
  57.   
  58.     /*CClientDC ccdc(this);  
  59.     CBrush *pcbr;  
  60.     pcbr=(CBrush *)ccdc.SelectStockObject(NULL_BRUSH);//SelectStockObject(NULL_BRUSH)返回的是一个GDI指针  
  61.   
  62.     ccdc.Rectangle(&CRect(m_orgpt,point));  
  63.   
  64.     ccdc.SelectObject(pcbr);*/  
  65.   
  66.     /*CClientDC ccdc(this);  
  67.     LOGBRUSH logb;  
  68.     ::GetObject((HBRUSH)::GetStockObject(NULL_BRUSH),sizeof(LOGBRUSH),&logb);  
  69.     CBrush cbr;  
  70.     cbr.CreateBrushIndirect(&logb);  
  71.     ccdc.Rectangle(&CRect(m_orgpt,point));*/ //这段注释的代码不成功,理论上可行  
  72.   
  73.     /*CClientDC ccdc(this);  
  74.     CBrush *oldpcbr;  
  75.     CBrush *newpcbr;  
  76.     newpcbr=CBrush::FromHandle((HBRUSH)::GetStockObject(NULL_BRUSH));  
  77.     oldpcbr=ccdc.SelectObject(newpcbr);  
  78.     ccdc.Rectangle(&CRect(m_orgpt,point));  
  79.     ccdc.SelectObject(oldpcbr);*/  
  80.   
  81.   
  82.     flag=FALSE;  
  83.       
  84.   
  85.     CView::OnLButtonUp(nFlags, point);  
  86. }  

[html] view plain copy
  1. void CDrawView::OnMouseMove(UINT nFlags, CPoint point)   
  2. {  
  3.     // TODO: Add your message handler code here and/or call default  
  4.   
  5.     /*m_movept=point;//画图程序  
  6.     CClientDC ccdc(this);  
  7.     ccdc.MoveTo(m_orgpt);  
  8.     if(flag)  
  9.     {  
  10.         ccdc.LineTo(m_movept);  
  11.   
  12.     }  
  13.     m_orgpt=m_movept;*/  
  14.   
  15.   
  16.     /*m_movept=point;//画不带边线的扇形  
  17.     CClientDC ccdc(this);  
  18.     ccdc.MoveTo(m_orgpt);  
  19.       
  20.     if(flag)  
  21.     {  
  22.         ccdc.LineTo(m_movept);  
  23.     }  
  24.     */  
  25.   
  26.       
  27.     CClientDC ccdc(this);  
  28.       
  29.     CPen cpen(PS_SOLID,3,RGB(255,0,0));  
  30.     CPen *oldpen =ccdc.SelectObject(&cpen);  
  31.     if(flag)  
  32.     {  
  33.         ccdc.SetROP2(R2_NOT);  
  34.         ccdc.MoveTo(m_orgpt);  
  35.         ccdc.LineTo(m_oldpt);  
  36.         ccdc.MoveTo(m_oldpt);  
  37.         ccdc.LineTo(point);  
  38.         m_oldpt=point;  
  39.           
  40.     }  
  41.   
  42.     ccdc.SelectObject(oldpen);  
  43.     CView::OnMouseMove(nFlags, point);  
  44. }  

0 0
原创粉丝点击