VC++画椭圆的例子

 

1,首先来看看相关的一些知识

1)RECT structure [MSDN]

     The RECT structure defines the coordinates(坐标) of the upper-left(左上角) and lower-right(右下角) corners of a rectangle.    

typedef struct tagRECT { 
   LONG left;     //Specifies the x-coordinate of the upper-left corner of a rectangle.左上角x的坐标
   LONG top;    //Specifies the y-coordinate of the upper-left corner of a rectangle. 左上角y的坐标
   LONG right;   //Specifies the x-coordinate of the lower-right corner of a rectangle. 右下角x的坐标
   LONG bottom;  //Specifies the y-coordinate of the lower-right corner of a rectangle. 右下角y的坐标
} RECT;
2)RECT结构和类CRect
   CRect Similar to a Windows RECT structure.  
   class CRect : public tagRECT
   This class is derived from the tagRECT structure. (The name tagRECT is a less-commonly-used name for the RECT 
structure.) This means that the data members (left, top, right, and bottom) of the RECT structure are accessible 
data members of CRect. CRect类派生于RECT结构,因此其对象也可以访问RECT结构的数据成员。
3)如何确定矩形(rectangle)和椭圆(ellipse)
   矩形是通过左上角和右下角两个点来确定
   椭圆则是在确定好矩形后,做一个内切椭圆。每一个矩形可唯一确定一个内接椭圆。因此椭圆也是由两个点确定,左上角和右下角点。

4)基类的指针虽然指向派生类对象,除了虚函数情况,无法访问派生类的成员函数。相反派生类的指针可以访问基类的成员。

   以下面例子为例:

   当我们定义RECT *rect时,由于rect=new CRect(cp,cp),即基类的指针指向了派生类对象。而在ondraw函数中,width()和height()是类CRect的函数,此时rect无法访问width()和height()。因此这里用派生类的指针 CRect *rect

 

5)CWnd::Invalidate 

   该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,因此会通过发送wm_paint消息调用ondraw函数实现重绘。

   CWnd::Invalidate()和CWnd::UpdateWindow()。

   关于两者的一个讨论见:http://topic.csdn.net/t/20020719/14/886666.html。简单的说,invalidate会使客户区域马上无效,从而调用ondraw函数,而undatewindown不会马上使客户区无效从而调用ondraw函数,它会在发现客户区存在无效时调用ondraw函数,比如用另一个从窗口覆盖时。

 

2,本例子的功能是 在 view 上画一个椭圆。通过鼠标拖动自动画,每次画椭圆之前都删除以前画的椭圆 。


一 . 首先建立一个单文档程序,名字为:DrawEllipse

二 . 然后在CDrawEllipseView 类中添加成员变量:

public:

RECT *rect;     //正确的是CRect *rect;当然也可以直接CRect rect,那就不用在构造函数中初始化了。
BOOL m_flag;

三 . 在CDrawEllipseView 类构造器中添加初始化代码:

CDrawEllipseView::CDrawEllipseView()
{
    // TODO: add construction code here
     CPoint cp(0,0);
     rect=new CRect(cp,cp);  
     m_flag=false;
}

四 . 添加 消息映射代码

 ON_WM_MOUSEMOVE:

void CDrawEllipseView::OnMouseMove(UINT nFlags, CPoint point) 
{
 // TODO: Add your message handler code here and/or call default
 if(m_flag)
 {
  rect.right=point.x;
  rect.bottom=point.y;
  Invalidate();
 }
 CView::OnMouseMove(nFlags, point);
}


 ON_WM_LBUTTONDOWN:

void CDrawEllipseView::OnLButtonDown(UINT nFlags, CPoint point) 
{
 // TODO: Add your message handler code here and/or call default
 
 CView::OnLButtonDown(nFlags, point);
 m_flag=true;
 rect.left=point.x;
 rect.top=point.y;
}


 ON_WM_LBUTTONUP:

void CDrawEllipseView::OnLButtonUp(UINT nFlags, CPoint point) 
{
 // TODO: Add your message handler code here and/or call default
 m_flag=false;
 CView::OnLButtonUp(nFlags, point);
}

五 . 重写OnDraw

void CDrawEllipseView::OnDraw(CDC* pDC)
{
 CDrawEllipseDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
    if(rect.Width()>10 && rect.Height()>10)
 {
  CPen penA(PS_DOT,1,RGB(255,0,0));
  CPen * pOldPen=NULL;
  pOldPen=pDC->SelectObject(&penA);

  pDC->SelectStockObject(NULL_BRUSH);
  pDC->Ellipse(rect);
  pDC->SelectObject(pOldPen);
 }

 // TODO: add draw code for native data here
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值