求助,MFC鼠标绘图的onDraw()函数怎么写

sigfield 2009-11-02 10:04:33

void CdrawDlgDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO:
static CPoint oldPoint; //上一个点的位置记录
static bool firstPressed = true;

CClientDC dc(this);

if(nFlags & MK_LBUTTON) //鼠标移动时如果左键被按下,则绘图
{
if(firstPressed == true) //鼠标第一次被点下的时候,在原地画个点
{
firstPressed = false;
dc.SetPixel(point, RGB(255, 255, 255));
oldPoint = point;
}
else //鼠标不是第一次被点下的时候,当前点和上个点之间连一条线
{
dc.MoveTo(oldPoint);
dc.LineTo(point);
oldPoint = point;
}
}
else
{
firstPressed = true;
}
CDialog::OnMouseMove(nFlags, point);
}





上面这段是绘图的代码,完整起见贴上来,其实没什么可说的。

关键是下面的问题:
当窗口部分移出屏幕时,已绘的线会消失——要写onDraw()/onPaint()函数
问题是:如何写?
我的想法是,各点坐标都存到一个队列里,onDraw()的时候一个一个提取,一条线一条线的重画。
但是,感觉很难看,是否有更好的方法?
我的图都画在一个Picture Control控件里,能否直接对控件进行存取操作?
...全文
668 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
如果你想实现类似画图板的功能,我有如下建议:

1、折线可以保存在一个链表中(便于添加、删除),每次有点加入或删除就更新链表数据。
2、如果图案所占面积不是特别大(大到无法创建那么大的位图),可以考虑创建一个内存DC,选入一个CBitmap,每次需要刷新时只要bitblt就行了。
3、MOUSE事件里,添加更新列表以及重画内存DC的代码。

例如:

class CMyClass
{
.............
CDC m_memDC;
CBitmap m_memBMP;
List m_points;
void DrawLine();
}

int CMyClass::OnInitDialog(...)
{
......................
//初始化类的成员,内存DC和CBitmap
CDC* pDC = GetDC();
m_memDC.CreateCompatibleDC(pDC);
m_memBMP.CreateCompatibleBitmap( pDC, 2048, 2048);
m_memDC.SelectObject( &m_memBMP );
.....................
}

void CMyClass::DrawLine()
{
//顺序按链表在内存DC上画图
m_memDC.MoveTo( 第一个点 )
while( m_points没到末尾 ){ m_memDC.LineTo(下一个点); }
Invalidate();
}

void CMyClass::OnMouseMove(UINT nFlags, CPoint point)
{
如果左键处于按下状态,添加新点到链表末尾。
DrawLine();
}

CMyClass::OnPaint()
{
CPaintDC dc(this);
dc.Bitblt(.......m_memDC,..........);
}

天鹅梦 2009-11-03
  • 打赏
  • 举报
回复
一般都是在OnMouseMove中改变某个具有程序分支控制的值,然后在OnDraw函数中根据相应的值进行分支处理
  • 打赏
  • 举报
回复
孙新教程很详细的
fandh 2009-11-03
  • 打赏
  • 举报
回复
onmousemove里面需要画线的数据,保存成视图或者对话框的成员变量,这样,你直接在ondraw或者onpaint里面使用就可以了!

楼主的想法是对的!
hhwei1985 2009-11-03
  • 打赏
  • 举报
回复
onDraw()/onPaint()是窗口重绘函数,可以解决因为移动覆盖而导致图形消失的问题;
所以
绘图工作要在onDraw()/onPaint()函数中进行,在OnMouseMove里边设置一些变量,
传递到onDraw()/onPaint()里面即可;
loop_k 2009-11-03
  • 打赏
  • 举报
回复
你要的答案就是上面那个兄弟贴的代码
要是想实现“橡皮筋”效果
参考http://blog.csdn.net/loop_k/archive/2009/08/24/4480034.aspx
zyq5945 2009-11-02
  • 打赏
  • 举报
回复
建议你看下孙鑫VC视频的11课
// GraphicView.h : interface of the CGraphicView class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_GRAPHICVIEW_H__A0E2AC83_7DFB_4989_9276_209F79BAEDC3__INCLUDED_)
#define AFX_GRAPHICVIEW_H__A0E2AC83_7DFB_4989_9276_209F79BAEDC3__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


class CGraphicView : public CScrollView
{
protected: // create from serialization only
CGraphicView();
DECLARE_DYNCREATE(CGraphicView)

// Attributes
public:
CGraphicDoc* GetDocument();

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CGraphicView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual void OnInitialUpdate();
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 ~CGraphicView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
//{{AFX_MSG(CGraphicView)
afx_msg void OnDot();
afx_msg void OnLine();
afx_msg void OnRectangle();
afx_msg void OnEllipse();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnPaint();
afx_msg void OnFileSave();
afx_msg void OnFileOpen();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
CDC m_dcCompatible;
CMetaFileDC m_dcMetaFile;
CPtrArray m_ptrArray;
CPoint m_ptOrigin;
UINT m_nDrawType;
};

#ifndef _DEBUG // debug version in GraphicView.cpp
inline CGraphicDoc* CGraphicView::GetDocument()
{ return (CGraphicDoc*)m_pDocument; }
#endif

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_GRAPHICVIEW_H__A0E2AC83_7DFB_4989_9276_209F79BAEDC3__INCLUDED_)

// GraphicView.cpp : implementation of the CGraphicView class
//

#include "stdafx.h"
#include "Graphic.h"

#include "GraphicDoc.h"
#include "GraphicView.h"

#include "Graph.h"

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

/////////////////////////////////////////////////////////////////////////////
// CGraphicView

IMPLEMENT_DYNCREATE(CGraphicView, CScrollView)

BEGIN_MESSAGE_MAP(CGraphicView, CScrollView)
//{{AFX_MSG_MAP(CGraphicView)
ON_COMMAND(IDM_DOT, OnDot)
ON_COMMAND(IDM_LINE, OnLine)
ON_COMMAND(IDM_RECTANGLE, OnRectangle)
ON_COMMAND(IDM_ELLIPSE, OnEllipse)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_PAINT()
ON_COMMAND(ID_FILE_SAVE, OnFileSave)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGraphicView construction/destruction

CGraphicView::CGraphicView()
{
// TODO: add construction code here
m_nDrawType=0;
m_ptOrigin=0;
m_dcMetaFile.Create();
}

CGraphicView::~CGraphicView()
{
}

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

return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CGraphicView drawing

void CGraphicView::OnDraw(CDC* pDC)
{
CGraphicDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
/* CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
pDC->SelectObject(pBrush);

for(int i=0;i<m_ptrArray.GetSize();i++)
{
switch(((CGraph*)m_ptrArray.GetAt(i))->m_nDrawType)
{
case 1:
pDC->SetPixel(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd,RGB(0,0,0));
break;
case 2:
pDC->MoveTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin);
pDC->LineTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd);
break;
case 3:
pDC->Rectangle(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin,
((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd));
break;
case 4:
pDC->Ellipse(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin,
((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd));
break;
}
}*/
/* HMETAFILE hmetaFile;
hmetaFile=m_dcMetaFile.Close();
pDC->PlayMetaFile(hmetaFile);
m_dcMetaFile.Create();
m_dcMetaFile.PlayMetaFile(hmetaFile);
DeleteMetaFile(hmetaFile);*/
CRect rect;
GetClientRect(&rect);
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&m_dcCompatible,0,0,SRCCOPY);
}

/////////////////////////////////////////////////////////////////////////////
// CGraphicView printing

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CGraphicView diagnostics

#ifdef _DEBUG
void CGraphicView::AssertValid() const
{
CScrollView::AssertValid();
}

void CGraphicView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}

CGraphicDoc* CGraphicView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGraphicDoc)));
return (CGraphicDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CGraphicView message handlers

void CGraphicView::OnDot()
{
// TODO: Add your command handler code here
m_nDrawType=1;
}

void CGraphicView::OnLine()
{
// TODO: Add your command handler code here
m_nDrawType=2;
}

void CGraphicView::OnRectangle()
{
// TODO: Add your command handler code here
m_nDrawType=3;
}

void CGraphicView::OnEllipse()
{
// TODO: Add your command handler code here
m_nDrawType=4;
}

void CGraphicView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_ptOrigin=point;
CScrollView::OnLButtonDown(nFlags, point);
}

void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
//dc.SelectObject(pBrush);
m_dcMetaFile.SelectObject(pBrush);

if(!m_dcCompatible.m_hDC)
{
m_dcCompatible.CreateCompatibleDC(&dc);
CRect rect;
GetClientRect(&rect);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
m_dcCompatible.SelectObject(&bitmap);
m_dcCompatible.BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);
m_dcCompatible.SelectObject(pBrush);
}
switch(m_nDrawType)
{
case 1:
//dc.SetPixel(point,RGB(0,0,0));
//m_dcMetaFile.SetPixel(point,RGB(0,0,0));
m_dcCompatible.SetPixel(point,RGB(0,0,0));
break;
case 2:
//dc.MoveTo(m_ptOrigin);
//dc.LineTo(point);
//m_dcMetaFile.MoveTo(m_ptOrigin);
//m_dcMetaFile.LineTo(point);
m_dcCompatible.MoveTo(m_ptOrigin);
m_dcCompatible.LineTo(point);
break;
case 3:
//dc.Rectangle(CRect(m_ptOrigin,point));
//m_dcMetaFile.Rectangle(CRect(m_ptOrigin,point));
m_dcCompatible.Rectangle(CRect(m_ptOrigin,point));
break;
case 4:
//dc.Ellipse(CRect(m_ptOrigin,point));
//m_dcMetaFile.Ellipse(CRect(m_ptOrigin,point));
m_dcCompatible.Ellipse(CRect(m_ptOrigin,point));
break;
}
//CGraph graph(m_nDrawType,m_ptOrigin,point);
//m_ptrArray.Add(&graph);
/* OnPrepareDC(&dc);
dc.DPtoLP(&m_ptOrigin);
dc.DPtoLP(&point);
CGraph *pGraph=new CGraph(m_nDrawType,m_ptOrigin,point);
m_ptrArray.Add(pGraph);*/
CScrollView::OnLButtonUp(nFlags, point);
}

void CGraphicView::OnPaint()
{
CPaintDC dc(this); // device context for painting

// TODO: Add your message handler code here
OnPrepareDC(&dc);
OnDraw(&dc);
// Do not call CScrollView::OnPaint() for painting messages
}

void CGraphicView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();

// TODO: Add your specialized code here and/or call the base class
SetScrollSizes(MM_TEXT,CSize(800,600));
}

void CGraphicView::OnFileSave()
{
// TODO: Add your command handler code here
HMETAFILE hmetaFile;
hmetaFile=m_dcMetaFile.Close();
CopyMetaFile(hmetaFile,"meta.wmf");
m_dcMetaFile.Create();
DeleteMetaFile(hmetaFile);
}

void CGraphicView::OnFileOpen()
{
// TODO: Add your command handler code here
HMETAFILE hmetaFile;
hmetaFile=GetMetaFile("meta.wmf");
m_dcMetaFile.PlayMetaFile(hmetaFile);
DeleteMetaFile(hmetaFile);
Invalidate();
}

19,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧