CCanvas - 用于绘制简单图形的可重用类






4.71/5 (21投票s)
一个用于绘制简单图形的可重用类

引言
实际上,我有点紧张地介绍这篇文章。这是我第一次使用MFC。在这里,我制作了一个可复用的类,能够通过使用GDI设备上下文编程来绘制诸如矩形、椭圆、圆和线等对象。这些对象是可选择、可移动和可调整大小的。它被命名为CCanvas
。我希望它对您有所帮助。您可以在需要简单图形编辑器的项目中使用它。
Using the Code
类方法
这里有一些public
方法
-
bool loadFile(char *fileName);
加载文件。
-
bool saveFile(char *fileName);
保存文件。
-
void set(CPoint ptStart, CPoint ptEnd);
检索鼠标拖动时的起始和结束位置。
-
set(int tool);
设置活动工具:绘制矩形、绘制椭圆、绘制圆或擦除。
-
int update(CDC *dc);
更新窗口。
-
void store();
将对象存储到内存中。
-
void drawGrid(CDC *dc, HWND hwnd, int gridsizeX, int gridsizeY)();
在指定大小内绘制网格。
-
void setSnapToGrid(bool setting, int gridsizeX, int gridsizeY);
在指定的网格大小内设置吸附到网格选项。
工作原理
它通过处理这三个重要的消息来工作
WM_LBUTTONDOWN
- 开始绘图,记住鼠标指针的原始位置WM_MOUSEMOVE
- 在这里它跟踪鼠标移动,记住其当前位置WM_LBUTTONUP
- 完成绘图,将新创建的对象存储到内存中
如何使用
假设您有一个名为Demo
的SDI项目。
-
将文件"canvas.h"添加到您的DemoView.h
#include "canvas.h"
-
将这些变量添加到您的DemoView.h
private: CCanvas m_canvas; CPoint m_ptStart; CPoint m_ptEnd;
-
将这些窗口消息添加到您的DemoView.cpp
BEGIN_MESSAGE_MAP(CDemoView, CView) //{{AFX_MSG_MAP(CDemoView) ON_WM_MOUSEMOVE() ON_WM_LBUTTONUP() ON_WM_LBUTTONDOWN() //}}AFX_MSG_MAP END_MESSAGE_MAP()
-
将这些代码添加到您的DemoView.cpp 以处理那些窗口消息
void CDemoView::OnDraw(CDC* dc) { CNiceDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); m_canvas.update(dc); } BOOL CDemoView::PreCreateWindow(CREATESTRUCT& cs) { m_canvas.setSnapToGrid(true, 10, 10); return CView::PreCreateWindow(cs); } void CDemoView::OnMouseMove(UINT nFlags, CPoint point) { CView::OnMouseMove(nFlags, point); // Update end point while mouse is moving if (GetCapture() == this){ m_ptEnd = point; Invalidate(); m_canvas.set(m_ptStart, m_ptEnd); } } void CDemoView::OnLButtonDown(UINT nFlags, CPoint point) { CView::OnLButtonDown(nFlags, point); // Get start point for drawing m_ptStart = m_ptEnd = point;SetCapture(); m_canvas.set(m_ptStart, m_ptEnd); } void CDemoView::OnLButtonUp(UINT nFlags, CPoint point) { CView::OnLButtonUp(nFlags, point); // Get end point for drawing if (GetCapture() == this) { ReleaseCapture(); m_ptEnd = point; Invalidate(); m_canvas.store(); } }
加载和保存文档
用于加载和保存文档的函数成员在类CDemoDoc
中调用,该类存在于文件DemoDoc.h和DemoDoc.cpp中。这是一个很长的解释。您可以在演示源代码中自己查看。基本上,它只是一个“您如何处理CDocument
”的问题。
闪烁问题 - 双缓冲
为了摆脱闪烁问题,我们可以使用双缓冲方法。看这里。按照步骤操作,您将看到闪烁问题消失。与本文一起提供的演示项目使用了此方法。
关注点
这是我的第一个MFC项目,我仍在改进它。我计划添加更多功能,例如
- 更多对象形状
- 旋转
- 排序(向后和向前)
- 选择和移动多个对象
- 着色
- 等等。
第1次更新
我修复了创建垂直线时的主要错误。您无法对垂直线执行任何操作,它似乎被冻结了。这是因为我在代码中使用了不完整的数学方程式。我还添加了两个新功能:setSnapToGrid
和drawGrid
。我从Johan Rosengren那里改编了用于drawGrid
函数的代码。别担心,其余的仍然是原始的,并且保持尽可能简单。除此之外,现在当您进行调整大小时,鼠标光标将根据调整方向而改变。该源代码也已转换为VC++ 2005。我认为VC++6.0已经被放弃了。
历史
- 2009年1月31日:初始版本
- 2009年2月25日:第1次更新