首页 > 代码库 > MFC 绘制坐标系

MFC 绘制坐标系

主要讨论映射模式:MM_ANISOTROPIC,MM_ISOTROPIC.及相关方法的应用。

1,先建立一个MFC单文档,过程不再赘述。

2,在View类中找到CMainFrame::PreCreateWindow函数,在其中设置默认窗口大小为400 pixel*300 pixel:

 

1 BOOL CTestView::PreCreateWindow(CREATESTRUCT& cs)
2 {
3     // TODO: 在此处通过修改
4     //  CREATESTRUCT cs 来修改窗口类或样式
5     cs.cx=400;
6     cs.cy=300;
7     return CView::PreCreateWindow(cs);
8 }

 

3,给CTestView在类向导里面,给WM_PAINT添加OnPaint()处理程序:

void CCausalityInterfaceView::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    // TODO: 在此处添加消息处理程序代码
    // 不为绘图消息调用 CView::OnPaint()
    OnPrepareDC(&dc);
    OnDraw(&dc);
    CRect cr;//矩形结构
    GetClientRect(&cr);//获得客户区窗口
    int cx=cr.right;//
    int cy=cr.bottom;//
    dc.SetMapMode(MM_ISOTROPIC);//X=Y
    dc.SetWindowExt(1000,1000);//设置逻辑窗口,默认窗口原点为(0,0)
    dc.SetViewportExt(cx,-cy);//定义输出视口,X右Y上为正
    dc.SetViewportOrg(cx/2,cy/2);//定义视口原点为客户区中心
    dc.Ellipse(-500,500,500,-500);//绘制椭圆与客户区外切的椭圆
    //绘制水平垂直的四条半径
    dc.MoveTo(0,0);     dc.LineTo(500,0);
    dc.MoveTo(0,0);     dc.LineTo(-500,0);
    dc.MoveTo(0,0);     dc.LineTo(0,500);
    dc.MoveTo(0,0);     dc.LineTo(0,-500);
    //执行F5进行Debug,在底端Output窗口中可以观察ClientRect
    TRACE( "ClientRect.x = %d, ClientRect.y = %d\n", cx, cy );
}
MM_ISOTROPIC:逻辑单位被映射为具有等刻度轴的任意单位:x轴上的一个单位等于y轴上的一个单位。
SetWindowExt(int cx, int cy): cx表示水平方向逻辑坐标的范围,cy表示垂直方向逻辑坐标的范围,
当改变窗口的大小时,以窗口的宽度或高度较小的方向为标准,比较下面两个图

图(1)图(2)

图(1)和图(2)为运行结果,改变窗口大小时的结果。无论怎么改变大小,客户区内始终显示的是一个圆,不会变成椭圆。

当宽度>高度时,高度(y方向)达到1000的逻辑范围,所以宽度(x方向)的逻辑范围超过1000,

当宽度<高度时,宽度(x方向)达到1000的逻辑范围,所以高度(y方向)的逻辑范围超过1000.

将dc.SetWindowExt(1000,1000);改为:dc.SetWindowExt(1000,500);会出现如下情况:

图(3)图(4),原因得自己思考了。

将模式改为MM_ANISOTROPIC:逻辑单位被转换为任意单位,其中轴可以被随意缩放。客户区的圆会根据窗口的大小变为椭圆:

图(5),椭圆会始终和客户区边界相切。

4,当进行如下设置时:

dc.SetMapMode(MM_ISOTROPIC);//X=Y
dc.SetWindowExt(1000,1000);//设置逻辑窗口,默认窗口原点为(0,0)
dc.SetViewportExt(500,-600);
dc.SetViewportOrg(cx/2,cy/2);//定义视口原点为客户区中心

图(6)图(7)

客户区的圆的大小不会随客户区改变,原因是逻辑单位 与 像素的映射已经固定,根据圆的半径的逻辑单位得出圆占多少像素,而像素是固定的,所以圆的大小不在改变。

设置为:

dc.SetMapMode(MM_ANISOTROPIC);//X!=Y
dc.SetWindowExt(1000,1000);//设置逻辑窗口,默认窗口原点为(0,0)
dc.SetViewportExt(500,-600);
dc.SetViewportOrg(cx/2,cy/2);//定义视口原点为客户区中心

图(8),圆显示为椭圆,且大小不改变。