客户区坐标转换成逻辑坐标或其它你想要的坐标。
转换坐标核心代码如下,其中最关键的一步为pDC->SetMapMode(MM_LOMETRIC);设置映射模式
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CPen pen(1,5,RGB(0x7A,0x7A,0x7A));
CClientDC *pDC = new CClientDC(this);
//设置映射模式,单位为0.1mm,引时窗口坐标系以客户区左上角为原点,
//X轴的方向为从左往右,Y轴的方向为从下往上
pDC->SetMapMode(MM_LOMETRIC);
pDC->SelectObject(&pen);
//获得客户区域
CRect rect;
GetClientRect(&rect);
//将客户坐标转换为逻辑坐标,
pDC->DPtoLP(&rect);
//在逻辑坐标下,意图将视口原点所置的位置
CSize org(200,-rect.bottom-200);
//将该位置转换为设置坐标,方便移动视口坐标原点
pDC->LPtoDP(&org);
以上是绘制直角坐标系的部分代码,全部cpp文件代码如下。
// 直角坐标系View.cpp : implementation of the CMyView class
//
#include "stdafx.h"
#include "直角坐标系.h"
#include "直角坐标系Doc.h"
#include "直角坐标系View.h"
#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)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}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
}
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* pD)
{
int x_min=10;// x轴起始座标
int x_step=10;// 显示间隔
int y_min=10;// y轴起始座标
int y_step=10;// 显示间隔
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CPen pen(1,5,RGB(0x7A,0x7A,0x7A));
CClientDC *pDC = new CClientDC(this);
//设置映射模式,单位为0.1mm,引时窗口坐标系以客户区左上角为原点,
//X轴的方向为从左往右,Y轴的方向为从下往上
pDC->SetMapMode(MM_LOMETRIC);
pDC->SelectObject(&pen);
//获得客户区域
CRect rect;
GetClientRect(&rect);
//将客户坐标转换为逻辑坐标,
pDC->DPtoLP(&rect);
//在逻辑坐标下,意图将视口原点所置的位置
CSize org(200,-rect.bottom-200);
//将该位置转换为设置坐标,方便移动视口坐标原点
pDC->LPtoDP(&org);
//移动视口坐标原点,整个坐标尺在可见区域
pDC->SetViewportOrg(org.cx,org.cy);
//在逻辑坐标系下画X轴,起点为逻辑坐标系下的原点,终点为自定的
pDC->MoveTo(0,0);
//X轴的长度为客户区的宽度减去5厘米(一个象素单位为0.1mm),此时X轴终点距右边框的距离将为3cm(视口原点已经移
//动到距左边框2cm处)
pDC->LineTo(rect.right*2/3,0);
pDC->MoveTo(rect.right*2/3,0);
pDC->LineTo(rect.right*2/3-50,20);
pDC->MoveTo(rect.right*2/3,0);
pDC->LineTo(rect.right*2/3-50,-20);
pDC->TextOut(rect.right*2/3,0,L"X");
//在逻辑坐标系下画Y轴,起点为逻辑坐标系下的原点,终点为自定的
pDC->MoveTo(0,0);
//Y轴的长度为客户区的高度减去5厘米(一个象素单位为0.1mm),此时Y轴终点距上边框的距离将为3cm(视口原点已经移
//动到距下边框2cm处)
pDC->LineTo(0,-rect.bottom-500);
//以下代码用来画Y轴的终点箭头
pDC->MoveTo(-20,-rect.bottom-540);
pDC->LineTo(0,-rect.bottom-500);
pDC->MoveTo(20,-rect.bottom-540);
pDC->LineTo(0,-rect.bottom-500);
pDC->TextOut(0,-rect.bottom-400,_T("Y"));
//在画标尺时,刻度的最大单位为cm,最小单位为mm,坐标轴上只画有整数个cm段,并在相应的位置标明cm刻度
//计算X轴可以画出多少个cm刻度
int num = (rect.right+1000)/200;
//利用循环画X轴上的刻度,i表示第多少个mm刻度,总共为num*10个毫米刻度
int k=x_min;
for(int i = 0;i<=num*10; i++)
{
//刻度能为5整除,此时的可能值为:5,10,15……
if(i%5==0)
{
//刻度为10的倍数时,画出刻度标记,它的长度为4mm,并在刻度的下方标明刻度值,单位为cm
if((i ==0)&&(k%x_step==0)) // 间隔为step,默认为20
{
pDC->MoveTo(i*10,0);
pDC->LineTo(i*10,40);
CString str;
str.Format(_T("%d"),k); // 显示刻度
pDC->TextOut(i*10-10,-10,str);
k+=x_step;
}
else//刻度为5,15等时,画出刻度标记,它的长度为2mm
{
pDC->MoveTo(i*10,0);
pDC->LineTo(i*10,20);
}
}
}
//计算Y轴可以画出多少个cm刻度
num = (-rect.bottom-500)/100;
k=y_step;
//相用画X轴上的坐标相同的方法来绘制Y轴坐标,此时注意绘画点的改变
for(int j = 1;j<=num*10; j++)
{
if(j%5==0)
{
if((j ==0)&&(k%y_step==0))
{
pDC->MoveTo(0,j*10);
pDC->LineTo(40,j*10);
CString str;
str.Format(_T("%d"),k);
pDC->TextOut(-45,j*10+10,str);
k+=y_step;
}
else
{
pDC->MoveTo(0,j*10);
pDC->LineTo(20,j*10);
}
}
}
delete pDC;
// TODO: add draw code for native data here
}
/
// CMyView printing
BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CMyView::OnBeginPrinting(CDC* , CPrintInfo* )
{
// TODO: add extra initialization before printing
}
void CMyView::OnEndPrinting(CDC* , CPrintInfo* )
{
// 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
程序运行结果图如下:
欢迎访问我的小站 船长旅游网,百度搜索 船长旅游网