void CC3aView::OnLButtonDown(UINT nFlags, CPoint point) 
{
        CRect rect=m_rectEllipse;
CClientDC dc(this); dc.SetMapMode(MM_LOENGLISH); dc.LPtoDP(rect); if(rect.PtInRect(point))
{ MessageBox("in the rect!",NULL,MB_OK);
}
        CView::OnLButtonDown(nFlags, point);
}
上面这段代码是书上的,我碰到问题很纳闷。书上说OnLButtonDown获得的point坐标是设备坐标。可是当获得point的时候,映射模式还没有被改变过,应该是默认的映射模式,所以获得的设备坐标就是逻辑坐标。而画矩形rect的时候用的是逻辑坐标,那么使用PtInRect()的时候应该可是直接使用,因为现在的point和rect的坐标都是在逻辑坐标的值,不用进行映射模式转化。可是这儿它用到了SetMapMode,把rect变成了在MM_LOENGLISH下的设备坐标,他说是point是在设备坐标下的,所以要把rect也转到设备坐标下才能用PtInRect()。可是point的坐标应该在映射模式变的成MM_LOENGLISH之前就已经获得了,所以这样point和rect就使用了不同映射模式下的设备坐标,然后就有问题。 我想知道的是 OnLButtonDown获得的point坐标到底是设备坐标还是逻辑坐标? 如果是设备坐标,那他获得设备坐标后,映射模式发生改变,那point值是也变成新的模式下的设备坐标,还是保持原来的值不变?

解决方案 »

  1.   

    我换了一台新台式机上网,VISTA系统,资料不在这,记不得了。1、反正坐标是从屏幕的左上角开始,管它是逻辑坐标还是设备坐标。
    2、这段代码不用 dc.SetMapMode(MM_LOENGLISH);dc.LPtoDP(rect); 
    3、取得的坐标是整个屏幕的,要转换成视图的piont,这很重要。
      

  2.   

    可以认为CDC的所有成员函数都以逻辑坐标为参数;
    可以认为CWnd的成员函数都以设备坐标为参数;
    所有选中测试操作都应该考虑设备坐标,区域的定义该采用设备坐标,如Crect::PtInRect之类的函数只有在采用设备坐标参数时才会保证有正确的结果;
    将一些需要长期使用的值用逻辑坐标来保存,如果采用设备坐标来保存某点的坐标的话,那么只要用户对窗口进行以下滚动,该点的坐标就不再有效了