VC中的简单绘图

本文介绍如何在VC6中基于CView类创建一个名为CDrawPicView的视图,用于实现基本的图形绘制功能。包括左键点击开始绘图、移动鼠标绘制线条、右键点击绘制矩形和扇形等操作。通过OnDraw、OnLButtonDown、OnMouseMove等消息处理函数,结合CDC和GDI进行图形绘制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在VC6中建立了一个名为CDrawPicView的基于单文档的工程,相关的知识在后面的程序及注释中

// DrawPicView.h中的主要内容如下:
class CDrawPicView : public CView
{
protected: // create from serialization only
 CDrawPicView();
 DECLARE_DYNCREATE(CDrawPicView)

// Attributes
public:
 CDrawPicDoc* GetDocument();

// Operations
public:

// Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CDrawPicView)
 public:
 virtual void OnDraw(CDC* pDC);  // overridden to draw this view
 virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
 protected:
 virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
 virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
 virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
 //}}AFX_VIRTUAL

// Implementation
public:
 virtual ~CDrawPicView();
#ifdef _DEBUG
 virtual void AssertValid() const;
 virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
 //{{AFX_MSG(CDrawPicView)
 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 void OnRButtonDown(UINT nFlags, CPoint point);
 afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
private:
 CPoint m_OldPoint;
 bool m_drawflag;
 CPoint m_originalpoint;
};

 

//DrawPicView.cpp中的核心代码如下

// DrawPicView.cpp : implementation of the CDrawPicView class
//

#include "stdafx.h"
#include "DrawPic.h"

#include "DrawPicDoc.h"
#include "DrawPicView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CDrawPicView

IMPLEMENT_DYNCREATE(CDrawPicView, CView)

BEGIN_MESSAGE_MAP(CDrawPicView, CView)
 //{{AFX_MSG_MAP(CDrawPicView)
 ON_WM_LBUTTONDOWN()
 ON_WM_LBUTTONUP()
 ON_WM_MOUSEMOVE()
 ON_WM_RBUTTONDOWN()
 ON_WM_RBUTTONUP()
 //}}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()

/
// CDrawPicView construction/destruction

CDrawPicView::CDrawPicView()
{
 // TODO: add construction code here
    m_originalpoint=0;
 m_OldPoint=0;
 m_drawflag=false;
}

CDrawPicView::~CDrawPicView()
{
}

BOOL CDrawPicView::PreCreateWindow(CREATESTRUCT& cs)
{
 // TODO: Modify the Window class or styles here by modifying
 //  the CREATESTRUCT cs

 return CView::PreCreateWindow(cs);
}

/
// CDrawPicView drawing

void CDrawPicView::OnDraw(CDC* pDC)
{
 CDrawPicDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 // TODO: add draw code for native data here
}

/
// CDrawPicView printing

BOOL CDrawPicView::OnPreparePrinting(CPrintInfo* pInfo)
{
 // default preparation
 return DoPreparePrinting(pInfo);
}

void CDrawPicView::OnBeginPrinting(CDC* , CPrintInfo* )
{
 // TODO: add extra initialization before printing
}

void CDrawPicView::OnEndPrinting(CDC* , CPrintInfo* )
{
 // TODO: add cleanup after printing
}

/
// CDrawPicView diagnostics

/
// CDrawPicView message handlers

void CDrawPicView::OnLButtonDown(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 m_originalpoint=point;//点击鼠标左键就获取一个起始点
 m_drawflag=true;
 CView::OnLButtonDown(nFlags, point);
}

void CDrawPicView::OnLButtonUp(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 //利用SDK的全局函数实现画线功能
 //获得窗口的设备描述表
 HDC hdc=::GetDC(m_hWnd);//若不加冒号,会默认为CWnd类的成员函数
 //移动到线条的起点
 MoveToEx(hdc,m_originalpoint.x,m_originalpoint.y,NULL);
 //画线
 LineTo(hdc,point.x,point.y);
 //释放设备描述表
 ::ReleaseDC(m_hWnd,hdc);
 m_drawflag=false;
 CView::OnLButtonUp(nFlags, point);
}

void CDrawPicView::OnMouseMove(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 
 //利用MFC的CDC类实现画带边框的扇形功能,需添加一个CPoint类型的变量m_OldPoint
 CDC *pDC=GetDC();
 pDC->SetROP2(R2_MASKNOTPEN);//设置绘图模式的函数,(final pixel = (NOT pen) AND screen pixel).
 CPen pen(PS_SOLID,2,RGB(255,0,0));//构造一个GDI对象,虚线线性只在画笔宽度不大于1时才有效
 CPen* poldpen=pDC->SelectObject(&pen);//返回先前被选对象的指针
 pDC->MoveTo(m_originalpoint);
 pDC->LineTo(point);
 pDC->LineTo(m_OldPoint);
 m_OldPoint=point;
 pDC->SelectObject(poldpen);//将先前的GDI对象选人设备描述表,以便恢复先前的状态
 ReleaseDC(pDC);
 
   
 CView::OnMouseMove(nFlags, point);
}

void CDrawPicView::OnRButtonDown(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 
 //透明画刷
 //CBrush并没有提供创建透明画刷的功能
 CWindowDC dc(this);
 //创建一个空画刷
 //GetObject函数返回的是一个画刷句柄,返回类型是HGDIOBJECT,需强制转为HBRUSH类型
 //CBrush类提供了一个将画刷句柄转换为画刷对象的静态成员函数
 CBrush *pbrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
 //将空画刷选人设备描述表
 CBrush *poldbrush=dc.SelectObject(pbrush);
 //绘制一个矩形
 dc.Rectangle(CRect(m_originalpoint,point));
 //恢复先前的画刷
 dc.SelectObject(poldbrush);
 CView::OnRButtonDown(nFlags, point);
}

void CDrawPicView::OnRButtonUp(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 

 //创建一个简单的蓝色画刷,设备描述表中有一个默认的白色画刷
 //CBrush brush(RGB(0,0,255));
 //创建位图对象
 CBitmap bitmap;
 //CBitmap类提供了LoadBitmap、CreateBitmap、CreateBitmIndirect等初始化函数
 bitmap.LoadBitmap(IDB_BITMAP);
 //创建位图画刷
 CBrush brush(&bitmap);
 //创建并获得设备描述表
 CClientDC dc(this);
 //利用红色画刷填充矩形区域
 //FillRect直接利用指定画刷填充矩形,因此不需将画刷提前选人设备描述表
 dc.FillRect(CRect(m_originalpoint,point),&brush);
 CView::OnRButtonUp(nFlags, point);
}

可以作为课程设计的程序,实现简单绘图,移动图形的功能。 使用vc框架实现。 GHpaint程序的几个重点 程序的基本功能: 程序提供绘图、删除已绘图形、移动已绘图形。 可以选择绘图颜色、形状、线粗。 重点问题: 1、 程序设计基于面向对象。 程序中所有图形都从基类CShapebase派生,大部分工作(例如:删除、移动等)都在这个基类中完成。此类中的两个纯需函数: //纯需函数DrawShape,每个基类都必须实现的函数。 //指定不同图形的绘制方法。 virtual void DrawShape(CDC* pdc) = 0; //橡皮筋效果的算法函数 virtual void ZoomShape(CDC *pdc) = 0; 这两个函数需要在派生类中重载。这两个函数中主要实现不同图形的绘制方法。 也就是说,不同图形的不同点只有绘制方法不同,其他所有属性和行为都可以统一处理。 这里的继承体现了面向对象的设计,论文中可以体现这一点。 2、 动态模板库对象CPtList的使用,动态模板库基础知识。 CPtList是动态模板库的一个实例化类。功能是以链表形式保存指针,至于指针类型不做要求,需要程序员自己设计。 本程序CPtList对象中保存所有图形对象指针,由于所有图形都从CShapebase派生,所以所有图形指针都可以转化为基类CShapebase指针后保存在CPtList中。以后再遍历列表,调用图形对象函数时出现了多态调用。这里体现面向对象程序的多态,论文中可以说明。 至于CPtList的使用,可以在网上查查,可以看看程序代码,比较简单。 多态:是一种函数调用形式。出现在类继承情况下。详细的多态定义到网上查查。 程序中的多态体现在CShapebase类的虚函数,在使用CShapebase指针调用这两个虚函数,实际调用的使子类的重载函数体。这里实际上是不知道函数怎样工作,但是知道函数功能。 例如:使用CShapebase指针调用DrawShape函数,因为不知道子类是什么图形,所以不知道DrawShape怎样画这个图,但是直到DrawShape函数会把这个图画好,这就达到了要求。 3、 Windows窗口绘图基本知识。 3.1 Windows GUI绘图基本知识。使用MFC类库之后,每个窗口都有一个CDC指针量。这个变量提供图形绘制。CDC类说明查查网络,内容比较多。CDC及提供图形绘制算法,也提供各种绘制模式(单色、异或色等),提供画笔和画刷的功能。 3.2 窗口绘图基本思想: 图形绘制在窗口中,windows不会帮助程序员让图形“长在”窗口上,当窗口被遮挡,最小化后,图形绘消失。程序需要在合适的时机把图形重新画在窗口上。所以窗口上画的内容需要程序员自己思考怎样保存。在本程序中所有图形保存在CPtList对象中。 3.2 Windows为窗口提供了一个重绘消息:OnPaint,在winxp系统中,这个消息会在窗口被遮挡部分从新出现、窗口从最小化恢复时调用。在win7种只有窗口从屏幕外移动进屏幕时调用。具体情况可以查查网络,这里是我的发现,并不是主要内容。 在OnPaint消息中重新绘制所有图形是一个保证图形不消失的好办法。 4、 Windows颜色控制基本知识。 4.1 windows使用RGB三原色(红绿蓝)提供颜色控制,本程序使用24位颜色,在内存中占用4字节,所以用int型表示,但是int型的最高位字节不使用,这样每一种颜色就有一个字节表示,每种颜色级别从0-255。系统提供RGB宏帮助定义颜色,例如:RGB(255,0,0)是红色,RGB(0,0,0)黑色,RGB(255,255,255)白色。 4.2 windows绘图提供多种颜色混合模式,本程序中使用异或模式实现图形的“橡皮筋”效果和移动效果,使用纯色模式定位图形。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值