Dragon  
Dragon
日历
<2008年10月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
统计
  • 随笔 - 58
  • 文章 - 0
  • 评论 - 55
  • 引用 - 0

导航

常用链接

留言簿(3)

随笔分类(58)

随笔档案(58)

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 

对SetViewportOrg和SetWindowOrg的理解:
void CMainWindow::OnLButtonDown(UINT nFlags,CPoint point)
{
 CRect rect;
 GetClientRect(&rect);
        CClientDC dc(this);
 dc.SetViewportOrg(0,rect.Height());//把原点移至视口的左下角
 dc.Rectangle(0,0,200,-200);
 
 dc.SetViewportOrg(rect.Width(),rect.Height());//把原点移至视口的右下角
 dc.Rectangle(0,0,-200,-200);


 dc.SetViewportOrg(rect.Width(),0);//把原点移至视口的右上角
 dc.Rectangle(0,0,-200,200);

 dc.SetViewportOrg(0,0);//移回原来的位置
 dc.Rectangle(0,0,200,200);
}
     由于SetViewportOrg的参数是设备坐标,与逻辑坐标无关,所以当它移动坐标轴时与上一次的坐标轴的位置无
关的,并且GetClientDC获得的是设备坐标,更加可以相信它每一次设置的坐标的正确性,它的主要作用是:将原点
(左上角)移至参数指定的点.


    至于SetWindowOrg是采用逻辑坐标进行设置坐标原点的,它可以在对应的逻辑映射模式下进行设置原点,除了
默认的坐标系是原点在左上角,向为正,向右为正外,其它非自定义模式都是原点在左上角,向下为负,向右为正的,
和我们数学的二维坐标系一样,为了更好的体现出SetWindowOrg我将窗口分别变成我们数学上四个像限!它的
作用是这样的:有一点point1,先将它从设备坐标变成该映射模式下的逻辑坐标(注意:一般设备坐标点是+,+ 逻辑
坐标转换后是+,-的,由映射模式决定),然后它移动它的奇对称点使得坐标系跟着移动,当它的奇对称点到达原点
时,原来的原点就到达point1的位置!(SetWindowOrg的参数就是point1的奇对称点)

 

 CRect rect;
 GetClientRect(&rect);
没设置前已经是第四象限了!

第一象限:
 CClientDC dc(this);
 dc.SetMapMode(MM_LOENGLISH);
 CPoint point1(0,rect.Height());//把原点移到左下角
 dc.DPtoLP(&point1);//先将设备坐标变成逻辑坐标!SetWindowOrg要求的!
 dc.SetWindowOrg(-point1.x,-point1.y);//两个负号取奇对称点!移对称点使得整个坐标跟着移使对称点移到原点
 CRect rect1(0,0,200,200);
 dc.Rectangle(&rect1);
第二象限:
 CClientDC dc(this);
 dc.SetMapMode(MM_LOENGLISH);
 CPoint point1(rect.Width(),rect.Height());//把原点移到右下角
 dc.DPtoLP(&point1);//逻辑坐标是相对于MM_LOENGLISH进行转换的,得到的坐标肯定是(+,-)
 dc.SetWindowOrg(-point1.x,-point1.y);
 dc.Rectangle(0,0,-200,200);
第三象限:
 CClientDC dc(this);
 dc.SetMapMode(MM_LOENGLISH);
 CPoint point1(rect.Width(),0);//把原点移到右上角
 dc.DPtoLP(&point1);
 dc.SetWindowOrg(-point1.x,-point1.y);
 dc.Rectangle(0,0,-200,-200);


上面的SetWindowOrg分开画的,我要的效果是要像上面的SetViewportOrg这样连着画:
其实在移完一个原点后,把原点移回(0,0)再移过就可以做到了:(第四象限忽略)
 CRect rect;
 GetClientRect(&rect);
        int width=rect.Width();
 int height=rect.Height();
 
 CClientDC dc(this);
 dc.SetMapMode(MM_LOENGLISH);
 CPoint point1(0,height);
 dc.DPtoLP(&point1);
 dc.SetWindowOrg(-point1.x,-point1.y);
 CRect rect1(0,0,200,200);
 dc.Rectangle(&rect1);
 
 
        dc.SetWindowOrg(0,0);
 point1=CPoint(width,height);
 dc.DPtoLP(&point1);
 dc.SetWindowOrg(-point1.x,-point1.y);
 dc.Rectangle(0,0,-200,200);

 dc.SetWindowOrg(0,0);
 point1=CPoint(width,0);
 dc.DPtoLP(&point1);
 dc.SetWindowOrg(-point1.x,-point1.y);
 dc.Rectangle(0,0,-200,-200);


如果我中间没有用dc.SetWindowOrg(0,0);就要思考了!
 CClientDC dc(this);
 dc.SetMapMode(MM_LOENGLISH);
 CPoint point1(0,height);
 dc.DPtoLP(&point1);
 dc.SetWindowOrg(-point1.x,-point1.y);
 CRect rect1(0,0,200,200);
 dc.Rectangle(&rect1);
 
 //先明确上一步我们的坐标原点在左下角,要把原点移到右下角,此时右下角相对当时的坐标系是(width,0)
 point1=CPoint(width,0);//移至(width,0)
 dc.DPtoLP(&point1);//变换成为逻辑坐标,但符号变为(+,-),因为在MM_LOENGLISH映射模式下
 dc.SetWindowOrg(-point1.x,point1.y);//(width,0)为(+,0)则它的对称点应为(-,0)才对,
                                     //只要将point1前一个变号即可,第二个为0不用变!
 dc.Rectangle(0,0,-200,200);

 
 //先明确上一步我们的坐标原点在右下角,要把原点移到右上角,此时右上角相对当时的坐标系是(0,height)
 point1=CPoint(0,height);//移至(0,height)
 dc.DPtoLP(&point1);//变换成为逻辑坐标,但符号变为(+,-),因为在MM_LOENGLISH映射模式下
 dc.SetWindowOrg(point1.x,point1.y);//(0,height)为(0,+)则它的对称点应为(0,-)才对,和逻辑坐标同号,不用变!
 dc.Rectangle(0,0,-200,-200);

可以看出SetWindowOrg每一次执行都改变一次坐标系的位置!!

posted on 2008-10-15 10:01 Dragon 阅读(5602) 评论(1)  编辑 收藏 引用 所属分类: VC
评论:
  • # re: 对SetViewportOrg和SetWindowOrg的理解  王小亮 Posted @ 2012-09-07 16:56
    嗯。。学习了。。  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


 
Copyright © Dragon Powered by: 博客园 模板提供:沪江博客