// 画图View.cpp : implementation of the CMyView class
//
#include "stdafx.h"
#include "画图.h"
#include "画图Doc.h"
#include "画图View.h"
#include "SettingDlg.h"
#include
#ifdef DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE_;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMyView
IMPLEMENT_DYNCREATE(CMyView, CView)
BEGIN_MESSAGE_MAP(CMyView, CView)
//{{AFX_MSG_MAP(CMyView)
ON_COMMAND(IDM_LINE, OnLine)
ON_COMMAND(IDM_RECTANGLE, OnRectangle)
ON_COMMAND(IDM_Circle, OnCircle)
ON_COMMAND(IDM_Random_Line, OnRandomLine)
ON_COMMAND(IDM_POLYGON, OnPolygon)
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_COMMAND(IDM_SET_LINE_STYLE_WIDTH, OnSetLineStyleWidth)
ON_COMMAND(IDM_SET_COLOR, OnSetColor)
//}}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()
/////////////////////////////////////////////////////////////////////////////
// CMyView construction/destruction
CMyView::CMyView()
{
// TODO: add construction code here
m_nDrawType=0;
m_ptOrigin=0;
m_nLineStyle=0;
m_nLineWidth=1;
m_ncolor=RGB(255,0,0);
m_dcMetaFile.Create();
no1=0;
no2=0;
no3=0;
no4=0;
no5=0;
k=0;
}
CMyView::~CMyView()
{
}
BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CMyView drawing
void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CClientDC dc(this);
CPen pen(m_nLineStyle,m_nLineWidth,m_color);
CPen* pOldPen = pDC->SelectObject(&pen);
CPoint point1,point2;
int temp=k;
//vector::const_iterator i=v.begin();
if(no1 ||no2 ||no3 ||no4|| no5){
switch(m_nDrawType)
{
case 1:
pDC->MoveTo(pDoc->head);
point1.x=pDoc->head.x+5;
point1.y=pDoc->head.y+5;
point2.x=pDoc->head.x-5;
point2.y=pDoc->head.y-5;
pDC->Ellipse(CRect(point1,point2));
pDC->LineTo(pDoc->tail);
point1.x=pDoc->tail.x+5;
point1.y=pDoc->tail.y+5;
point2.x=pDoc->tail.x-5;
point2.y=pDoc->tail.y-5;
pDC->Ellipse(CRect(point1,point2));
break;
case 2:
point1.x=pDoc->m_Rect.left+5;
point1.y=pDoc->m_Rect.top+5;
point2.x=point1.x-10;
point2.y=point1.y-10;
pDC->Ellipse(CRect(point1,point2));
point1.x=pDoc->m_Rect.right+5;
point2.x=point1.x-10;
pDC->Ellipse(CRect(point1,point2));
point1.x=pDoc->m_Rect.left+5;
point1.y=pDoc->m_Rect.bottom+5;
point2.x=point1.x-10;
point2.y=point1.y-10;
pDC->Ellipse(CRect(point1,point2));
point1.x=pDoc->m_Rect.right+5;
point2.x=point1.x-10;
pDC->Ellipse(CRect(point1,point2));
pDC->Rectangle(pDoc->m_Rect);
break;
case 3:
pDC->Ellipse(pDoc->m_Rect);
break;
case 4:
for(temp=0;temp {
pDC->MoveTo(pDoc->pointduo[temp]);
point1.x=pDoc->pointduo[temp].x+5;
point1.y=pDoc->pointduo[temp].y+5;
point2.x=pDoc->pointduo[temp].x-5;
point2.y=pDoc->pointduo[temp].y-5;
pDC->Ellipse(CRect(point1,point2));
pDC->LineTo(pDoc->pointduo[temp+1]);
point1.x=pDoc->pointduo[temp+1].x+5;
point1.y=pDoc->pointduo[temp+1].y+5;
point2.x=pDoc->pointduo[temp+1].x-5;
point2.y=pDoc->pointduo[temp+1].y-5;
pDC->Ellipse(CRect(point1,point2));
}
pDC->MoveTo(pDoc->pointduo[temp]);
point1.x=pDoc->pointduo[temp].x+5;
point1.y=pDoc->pointduo[temp].y+5;
point2.x=pDoc->pointduo[temp].x-5;
point2.y=pDoc->pointduo[temp].y-5;
pDC->Ellipse(CRect(point1,point2));
pDC->LineTo(pDoc->tail);
point1.x=pDoc->tail.x+5;
point1.y=pDoc->tail.y+5;
point2.x=pDoc->tail.x-5;
point2.y=pDoc->tail.y-5;
pDC->Ellipse(CRect(point1,point2));
break;
case 5:
for(temp=0;temp {
pDC->MoveTo(pDoc->pointp[temp]);
point1.x=pDoc->pointp[temp].x+5;
point1.y=pDoc->pointp[temp].y+5;
point2.x=pDoc->pointp[temp].x-5;
point2.y=pDoc->pointp[temp].y-5;
pDC->Ellipse(CRect(point1,point2));
pDC->LineTo(pDoc->pointp[temp+1]);
point1.x=pDoc->pointp[temp+1].x+5;
point1.y=pDoc->pointp[temp+1].y+5;
point2.x=pDoc->pointp[temp+1].x-5;
point2.y=pDoc->pointp[temp+1].y-5;
pDC->Ellipse(CRect(point1,point2));
}
pDC->MoveTo(pDoc->pointp[temp]);
point1.x=pDoc->pointp[temp].x+5;
point1.y=pDoc->pointp[temp].y+5;
point2.x=pDoc->pointp[temp].x-5;
point2.y=pDoc->pointp[temp].y-5;
pDC->Ellipse(CRect(point1,point2));
pDC->LineTo(pDoc->tail);
point1.x=pDoc->tail.x+5;
point1.y=pDoc->tail.y+5;
point2.x=pDoc->tail.x-5;
point2.y=pDoc->tail.y-5;
pDC->Ellipse(CRect(point1,point2));
pDC->MoveTo(pDoc->tail);
point1.x=pDoc->tail.x+5;
point1.y=pDoc->tail.y+5;
point2.x=pDoc->tail.x-5;
point2.y=pDoc->tail.y-5;
pDC->Ellipse(CRect(point1,point2));
pDC->LineTo(pDoc->pointp[0]);
point1.x=pDoc->pointp[0].x+5;
point1.y=pDoc->pointp[0].y+5;
point2.x=pDoc->pointp[0].x-5;
point2.y=pDoc->pointp[0].y-5;
pDC->Ellipse(CRect(point1,point2));
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CMyView printing
BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CMyView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CMyView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CMyView diagnostics
#ifdef _DEBUG
void CMyView::AssertValid() const
{
CView::AssertValid();
}
void CMyView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMyDoc* CMyView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
return (CMyDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMyView message handlers
//DEL void CMyView::OnUpdateLine(CCmdUI* pCmdUI)
//DEL {
//DEL // TODO: Add your command update UI handler code here
//DEL
//DEL }
void CMyView::OnLine()
{
// TODO: Add your command handler code here
m_nDrawType=1;
}
void CMyView::OnRectangle()
{
// TODO: Add your command handler code here
m_nDrawType=2;
}
void CMyView::OnCircle()
{
// TODO: Add your command handler code here
m_nDrawType=3;
}
void CMyView::OnRandomLine()
{
// TODO: Add your command handler code here
m_nDrawType=4;
}
void CMyView::OnPolygon()
{
// TODO: Add your command handler code here
m_nDrawType=5;
}
void CMyView::OnLButtonUp(UINT nFlags, CPoint point)
{
CView::OnLButtonUp(nFlags, point);
}
void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
CPoint point1,point2;
m_ptOrigin=point;
CMyDoc* pDoc = GetDocument();
if(m_nDrawType==4)
{
pDoc->pointduo[k]=point;
k++;
}
if(m_nDrawType==5)
{
pDoc->pointp[k]=point;
k++;
}
if(no1||no2||no3)
{
switch(m_nDrawType)
{
case 1:if(no1==1)no1=0;break;
case 2:if(no2==1)no2=0;break;
case 3:if(no3==1)no3=0;break;
}
}
else if(m_nDrawType!=0)
{
if(m_nDrawType!=3)
{
CPen pen(0,1,m_color);
CPen* pOldPen = dc.SelectObject(&pen);
point1.x=point.x+5;
point1.y=point.y+5;
point2.x=point.x-5;
point2.y=point.y-5;
dc.Ellipse(CRect(point1,point2));
}
switch(m_nDrawType)
{
case 1:no1=1;
break;
case 2:no2=1;
break;
case 3:no3=1;
break;
case 4:no4=1;
break;
case 5:no5=1;
break;
}
}
CView::OnLButtonDown(nFlags, point);
}
void CMyView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CPoint m_ptEnd=point;
CPoint point1,point2,point3,point4;
CMyDoc* pDoc = GetDocument();
CClientDC dc(this);
switch(m_nDrawType)
{
case 1:
pDoc->head=m_ptOrigin;
pDoc->tail=m_ptEnd;
if(no1) Invalidate();
break;
case 2:case 3:
pDoc->m_Rect.left=m_ptOrigin.x;
pDoc->m_Rect.top=m_ptOrigin.y;
pDoc->m_Rect.right=m_ptEnd.x;
pDoc->m_Rect.bottom=m_ptEnd.y;
if(no2 || no3) Invalidate();
case 4:case 5:
pDoc->tail=m_ptEnd;
if(no5 || no4) Invalidate();
break;
}
CView::OnMouseMove(nFlags, point);
}
void CMyView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CView::OnRButtonDown(nFlags, point);
}
void CMyView::OnRButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_nDrawType==4)
{
no4=0;
k=0;
}
if(m_nDrawType==5)
{
no5=0;
k=0;
}
CView::OnRButtonUp(nFlags, point);
}
void CMyView::OnSetLineStyleWidth()
{
// TODO: Add your command handler code here
CSettingDlg dlg;
//dlg.DoModal();
dlg.m_nLineWidth=m_nLineWidth;
dlg.m_nLineStyle=m_nLineStyle;
if(IDOK==dlg.DoModal())
{
m_nLineWidth=dlg.m_nLineWidth ;
m_nLineStyle=dlg.m_nLineStyle ;
}
}
void CMyView::OnSetColor()
{
// TODO: Add your command handler code here
CColorDialog dlg;
dlg.m_cc.Flags |=CC_RGBINIT | CC_FULLOPEN;
dlg.m_cc.rgbResult=m_color;
if(IDOK==dlg.DoModal())
{
m_color=dlg.m_cc.rgbResult;
}
}
双缓存去闪就是将图形绘制到一个内存DC中,然后再将内存DC的图形拷贝到屏幕上,这样就不会出现闪烁的情况。
下面是一个简单的例子:
void CMyView::OnDraw(CDC* pDC)
{
// 创建内存DC
CDC memDC;
memDC.CreateCompatibleDC(pDC);
// 创建内存DC的位图
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC, GetClientRect().Width(), GetClientRect().Height());
// 将位图选入内存DC
CBitmap* pOldBmp = memDC.SelectObject(&bmp);
// 在内存DC中绘图
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CPen pen(m_nLineStyle, m_nLineWidth, m_color);
CPen* pOldPen = memDC.SelectObject(&pen);
CPoint point1, point2;
int temp = k;
//vector::const_iterator i=v.begin();
if (no1 || no2 || no3 || no4 || no5) {
switch (m_nDrawType)
{
case 1:
memDC.MoveTo(pDoc->head);
point1.x = pDoc->head.x + 5;
point1.y = pDoc->head.y + 5;
point2.x = pDoc->head.x - 5;
point2.y = pDoc->head.y - 5;
memDC.Ellipse(CRect(point1, point2));
memDC.LineTo(pDoc->tail);
point1.x = pDoc->tail.x + 5;
point1.y = pDoc->tail.y + 5;
point2.x = pDoc->tail.x - 5;
point2.y = pDoc->tail.y - 5;
memDC.Ellipse(CRect(point1, point2));
break;
// 其他的绘图操作
}
}
// 将内存DC的图形拷贝到屏幕上
pDC->BitBlt(0, 0, GetClientRect().Width(), GetClientRect().Height(), &memDC, 0, 0, SRCCOPY);
// 恢复原来的画笔
memDC.SelectObject(pOldPen);
// 释放内存DC的位图
memDC.SelectObject(pOldBmp);
bmp.DeleteObject();
}