已有程序能完成画线,矩形,弧等功能(原程序运行正常),因还要求绕不对称逻辑坐标(x:-300,500;y:-200,400)原点旋转和对称等,所以我在OnDraw()里加了一个这样的坐标系,因为ONLBUTTON()所得坐标是相对于物理坐标系,所以在其中做了一个坐标变换但是结果却运行不正常,现把画LINE的关键代码列下,请帮我看看,如果谁有时间,我想把整个工程发给你看看,谢谢!另:1。我对二维坐标系的变换还是无法弄清,有没有人可以解释一下。 2。想寻找VC伙伴,有问题了可以交流一下,.
// draw1vw.cpp : implementation of the CDraw1View class
//#include "stdafx.h"
#include "draw1.h"#include "draw1doc.h"
#include "draw1vw.h"class CDraw1View : public CView
{
protected: // create from serialization only
CDraw1View();
DECLARE_DYNCREATE(CDraw1View)
enum Shapes { Line, Arc, Chord, Circle, Ellipse, Pie, Rect, Square };
enum Actions { None, Outline, Draw };
// Attributes
public:
CDraw1Doc* GetDocument();
COLORREF rgbColor;
Shapes nShape;
Actions nAction;
int nLineStyle;
int nFillStyle;
POINT ptNew;
RECT rFrame;
// CDraw1ViewCDraw1View::CDraw1View()
{
// TODO: add construction code here
nAction = None;
nShape = Line;
rgbColor = 0x00000000;
nLineStyle = PS_SOLID;
nFillStyle = -1;
}CDraw1View::~CDraw1View()
{
}/////////////////////////////////////////////////////////////////////////////
// CDraw1View drawingvoid CDraw1View::OnDraw(CDC* pDC)
{
CDraw1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CRect cRect;
CPen *pOldPen,cNewPen(PS_SOLID, 5, 0x02ff0000);
int OldDC; OldDC=pDC->SaveDC();
pDC->SetMapMode(MM_ISOTROPIC); 加的坐标系
pDC->SetWindowExt(800,600); AfxGetMainWnd()->GetClientRect(cRect);
pDC->SetViewportExt(cRect.Width(),-cRect.Height());
pDC->SetViewportOrg(cRect.Width()*3/8,cRect.Height()*4/6);
pOldPen=pDC->SelectObject(&cNewPen);
pDC->MoveTo( -300, 0); 画坐标系
pDC->TextOut(-300, 0, "-300");
pDC->LineTo(500,0);
pDC->TextOut(500, 10, "500"); pDC->MoveTo( 0, 400);
pDC->TextOut(0, 400, "400");
pDC->LineTo(0,-200);
pDC->TextOut(0, -150, "-200");
pDC->TextOut(0, 0, "0"); switch( nAction )
{
case Outline: //not OnLButtomUp,ButtomDown and move
if( nShape == Line )
DrawDotLine( pDC );
rFrame.right = ptNew.x;
rFrame.bottom = ptNew.y;
pDC->DPtoLP(&rFrame); rFrame取的是相对于DP if( nShape == Line )
DrawDotLine( pDC ); // erase new line
else
DrawOutline( pDC ); // erase new frame
break; case Draw:
if( nShape == Line )
DrawDotLine(pDC ); // erase prior line); // erase prior frame
nAction = None;
break;
}
// TODO: add draw code for native data here
}
void CDraw1View::DrawDotLine( CDC *pDC )
{
CPen cPen;
pDC->MoveTo( rFrame.left, rFrame.top ); pDC->SetROP2( R2_XORPEN );
cPen.CreatePen( PS_DOT, 1, RGB(0,0,0) );
pDC->SelectObject( &cPen );
pDC->LineTo( rFrame.right, rFrame.bottom );
}/////////////////////////////////////////////////////////////////////////////
// CDraw1View printing// CDraw1View message handlersvoid CDraw1View::OnMouseMove(UINT nFlags, CPoint point)
{
if( nAction == Outline )
{
ptNew=point; 关于物理坐标的点
Invalidate( FALSE );
}
}void CDraw1View::OnLButtonDown(UINT nFlags, CPoint point)
{
nAction = Outline;
rFrame.left = point.x; //DP
rFrame.right = point.x;
rFrame.top = point.y;
rFrame.bottom = point.y;
ptNew = point;
Invalidate( FALSE );
// CView::OnLButtonDown(nFlags, point);
}void CDraw1View::OnLButtonUp(UINT nFlags, CPoint point)
{
nAction = Draw;
Invalidate( FALSE );
// CView::OnLButtonUp(nFlags, point);
}
// draw1vw.cpp : implementation of the CDraw1View class
//#include "stdafx.h"
#include "draw1.h"#include "draw1doc.h"
#include "draw1vw.h"class CDraw1View : public CView
{
protected: // create from serialization only
CDraw1View();
DECLARE_DYNCREATE(CDraw1View)
enum Shapes { Line, Arc, Chord, Circle, Ellipse, Pie, Rect, Square };
enum Actions { None, Outline, Draw };
// Attributes
public:
CDraw1Doc* GetDocument();
COLORREF rgbColor;
Shapes nShape;
Actions nAction;
int nLineStyle;
int nFillStyle;
POINT ptNew;
RECT rFrame;
// CDraw1ViewCDraw1View::CDraw1View()
{
// TODO: add construction code here
nAction = None;
nShape = Line;
rgbColor = 0x00000000;
nLineStyle = PS_SOLID;
nFillStyle = -1;
}CDraw1View::~CDraw1View()
{
}/////////////////////////////////////////////////////////////////////////////
// CDraw1View drawingvoid CDraw1View::OnDraw(CDC* pDC)
{
CDraw1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CRect cRect;
CPen *pOldPen,cNewPen(PS_SOLID, 5, 0x02ff0000);
int OldDC; OldDC=pDC->SaveDC();
pDC->SetMapMode(MM_ISOTROPIC); 加的坐标系
pDC->SetWindowExt(800,600); AfxGetMainWnd()->GetClientRect(cRect);
pDC->SetViewportExt(cRect.Width(),-cRect.Height());
pDC->SetViewportOrg(cRect.Width()*3/8,cRect.Height()*4/6);
pOldPen=pDC->SelectObject(&cNewPen);
pDC->MoveTo( -300, 0); 画坐标系
pDC->TextOut(-300, 0, "-300");
pDC->LineTo(500,0);
pDC->TextOut(500, 10, "500"); pDC->MoveTo( 0, 400);
pDC->TextOut(0, 400, "400");
pDC->LineTo(0,-200);
pDC->TextOut(0, -150, "-200");
pDC->TextOut(0, 0, "0"); switch( nAction )
{
case Outline: //not OnLButtomUp,ButtomDown and move
if( nShape == Line )
DrawDotLine( pDC );
rFrame.right = ptNew.x;
rFrame.bottom = ptNew.y;
pDC->DPtoLP(&rFrame); rFrame取的是相对于DP if( nShape == Line )
DrawDotLine( pDC ); // erase new line
else
DrawOutline( pDC ); // erase new frame
break; case Draw:
if( nShape == Line )
DrawDotLine(pDC ); // erase prior line); // erase prior frame
nAction = None;
break;
}
// TODO: add draw code for native data here
}
void CDraw1View::DrawDotLine( CDC *pDC )
{
CPen cPen;
pDC->MoveTo( rFrame.left, rFrame.top ); pDC->SetROP2( R2_XORPEN );
cPen.CreatePen( PS_DOT, 1, RGB(0,0,0) );
pDC->SelectObject( &cPen );
pDC->LineTo( rFrame.right, rFrame.bottom );
}/////////////////////////////////////////////////////////////////////////////
// CDraw1View printing// CDraw1View message handlersvoid CDraw1View::OnMouseMove(UINT nFlags, CPoint point)
{
if( nAction == Outline )
{
ptNew=point; 关于物理坐标的点
Invalidate( FALSE );
}
}void CDraw1View::OnLButtonDown(UINT nFlags, CPoint point)
{
nAction = Outline;
rFrame.left = point.x; //DP
rFrame.right = point.x;
rFrame.top = point.y;
rFrame.bottom = point.y;
ptNew = point;
Invalidate( FALSE );
// CView::OnLButtonDown(nFlags, point);
}void CDraw1View::OnLButtonUp(UINT nFlags, CPoint point)
{
nAction = Draw;
Invalidate( FALSE );
// CView::OnLButtonUp(nFlags, point);
}
[email protected]
pDC->DPtoLP(&rFrame); //rFrame取的是相对于DP
将rFrame转换为逻辑坐标, 第一次转换rFrame中记录的确实是设备坐标, 但是以后rFrame中记录的就是逻辑坐标了, 所以rFrame.left, rFrame.top的位置将不对;可以改正如下:
1. 去掉OnDraw中的pDC->DPtoLP(&rFrame)一行;
2. 可以如下来写
void DrawDotLine(CDC *pDC)
{
RECT rc = rFrame; // 拷贝rFrame
pDC->DPtoLP(&rc); //转换为逻辑坐标不会改变rFrame中的值
CPen cPen;
pDC->MoveTo( rc.left, rc.top ); pDC->SetROP2( R2_XORPEN );
cPen.CreatePen( PS_DOT, 1, RGB(0,0,0) );
pDC->SelectObject( &cPen );
pDC->LineTo( rc.right, rc.bottom ); }3. 另外如果你的OnDraw代码是完整的话, 记得将恢复DC的画笔
pDC->SelectObject(pOldPen); 要不98下运行可能情况不大妙.
case Outline: //not OnLButtomUp,ButtomDown and move
if( nShape == Line )
DrawDotLine( pDC );
rFrame.right = ptNew.x;
rFrame.bottom = ptNew.y;
**********这一行 pDC->DPtoLP(&rFrame); rFrame取的是相对于DP
十分谢谢你的帮助,后来我发现在OutLine时是对的,但Draw 时不对,把DrawShape( CDC *pDC )按你说的方式改了,就对了,再次感谢你,我如何给你加分?