设为首页 加入收藏

TOP

14.4.3 使用鼠标绘图(6)
2013-10-07 16:12:21 来源: 作者: 【 】 浏览:63
Tags:14.4.3 使用 鼠标 绘图

14.4.3  使用鼠标绘图(6)

在初始化列表中调用CElement构造函数,以初始化钢笔的颜色和线宽。CElement构造函数还初始化了m_StartPoint,但后面要替换它。可以只绘制宽度和高度至少是2的CRect对象,在安排了定义规范化矩形的点后,在必要时调整两个定义点的坐标。由于调整了这些定义点,所以不需要调用NormalizeRect()。std::min()和std::max()是algorithm头文件中定义的模板函数,它们分别返回其参数的最小和最大值。在Rectangle.cpp中给algorithm头文件添加一个#include指令。

代码中围绕std::min和std::max的圆括号是必需的。在其他C++(www.cppentry.com)编译器中,这不常见,但它是Visual C++(www.cppentry.com)中的一种特殊情况。windows.h头文件为min和max定义了宏,且不带括号,在编译器启动之前,预处理器会替代这些宏。这会使编译器生成错误消息。圆括号可防止预处理器替代宏。

绘制矩形

CDC类的Rectangle()成员可以绘制矩形。这个函数将绘制闭合图形,然后利用当前画笔进行填充。您可能只想绘制矩形的轮廓,这时只要将NULL_BRUSH选入设备上下文即可。CDC还有一个函数PolyLine(),它根据一组点绘制由多条线段组成的形状,也可以使用LineTo()绘制矩形的4条边,但是最容易的方法是使用Rectangle()函数:
 

  1. // Draw a CRectangle object  
  2. void CRectangle::Draw(CDC* pDC)  
  3. {  
  4. // Create a pen for this object and initialize it  
  5. CPen aPen;  
  6. CreatePen(aPen);  
  7. // Select the pen and the null brush  
  8. CPen* pOldPen = pDC->SelectObject(&aPen);  
  9. CBrush* pOldBrush = dynamic_cast<CBrush*>(pDC->SelectStockObject(NULL_BRUSH));  
  10. // Now draw the rectangle  
  11. pDC->Rectangle(m_StartPoint.x, m_StartPoint.y,  
  12. m_BottomRight.x, m_BottomRight.y);  
  13. pDC->SelectObject(pOldBrush);                           // Restore the old brush  
  14. pDC->SelectObject(pOldPen);                                 // Restore the old pen  
  15. }  

在设置了钢笔和画笔以后,就调用Rectangle()函数,绘制矩形。其参数是矩形的左下角和右上角坐标。这个函数有一个重载版本,它把CRect对象作为参数来指定矩形。剩下的工作就是在绘制结束后,还原设备上下文的旧钢笔和画笔。

7. CCircle类

CCircle类的接口类似于CRectangle类。使用CDC类的Ellipse()成员可以绘制圆,这个成员绘制用一个矩形来界定的椭圆。只要该边界矩形是正方形,该椭圆就是圆。圆用两个定义点来定义,分别是圆心和圆周上的一点。所以这个类的定义是:

  1. class CCircle: public CElement  
  2. {  
  3. public:  
  4. virtual ~CCircle(void);  
  5. virtual void Draw(CDC* pDC) override;               // Function to display a circle  
  6. // Constructor for a circle object  
  7. CCircle(const CPoint& start, const CPoint& end, COLORREF color);  
  8. protected:  
  9. CPoint m_BottomRight;                                       // Bottom-right point for defining rectangle  
  10. CCircle(void);                                                              // Default constructor - should not be used  
  11. };  

这段代码定义了一个公共构造函数,它使用绘图颜色,根据两个点创建圆,并且把无参数构造函数设置为protected,以防止外界使用它。另外在这个类定义中还添加了这个绘制圆的重载函数的声明。

实现CCircle类

在创建圆时,按下鼠标左键时的点将成为圆心,移动光标后,释放鼠标左键时的点将是圆周上的一个点。构造函数的工作是从这些点中获得边界矩形的角点。

CCircle类构造函数

释放鼠标左键时的点可以位于圆周上的任何地方,所以需要计算指定封闭矩形的点的坐标,如图14-15所示。
 

由图14-15可以看出,我们可以计算封闭矩形的左上角和右下角相对于圆心(x1,y1)的坐标。假设映射模式是MM_TEXT,计算(left,top)点的坐标时,只需要要从圆心的坐标中减去半径。类似地,把圆心的x和y坐标分别加上半径,就可以得到(right,bottom)点的坐标。半径可以计算为图14-15中表达式的平方根。因此,可以把CCircle类构造函数的代码编写为:

  1. // Constructor for a circle object  
  2. CCircle::CCircle(const CPoint& start, const CPoint& end, COLORREF color) :  
  3. CElement(start, color)  
  4. {  
  5. // Calculate the radius using floating-point values  
  6. // because that is required by sqrt() function (in cmath)  
  7. long radius = static_cast<long> (sqrt(  
  8. static_cast<double>((end.x-start.x)*(end.x-start.x)+  
  9. (end.y-start.y)*(end.y-start.y))));  
  10. if(radius < 1Lradius = 1L;                            // Circle radius must be >= 1  
  11. // Define left-top and right-bottom points of rectangle for MM_TEXT mode  
  12. m_StartPoint = CPoint(start.x - radius, start.y - radius);  
  13. m_BottomRight = CPoint(start.x + radius, start.y + radius);  
  14. // Define the enclosing rectangle  
  15. m_EnclosingRect = CRect(m_StartPoint.x, m_StartPoint.y,  
  16. m_BottomRight.x, m_BottomRight.y);  
  17. m_EnclosingRect.InflateRect(m_PenWidth, m_PenWidth);  
  18. }  

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇14.4.3 使用鼠标绘图(5) 下一篇14.4.3 使用鼠标绘图(7)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·数据库:推荐几款 Re (2025-12-25 12:17:11)
·如何最简单、通俗地 (2025-12-25 12:17:09)
·什么是Redis?为什么 (2025-12-25 12:17:06)
·对于一个想入坑Linux (2025-12-25 11:49:07)
·Linux 怎么读? (2025-12-25 11:49:04)