重建坐标系后BeginPath和EndPath之间使用的是什么坐标?逻辑坐标?设备坐标?

wal199005 2015-06-16 04:28:49
部分代码如下
	//设置映射模式和坐标系
pDC->SetMapMode(MM_ISOTROPIC);
pDC->SetWindowExt(rc.Width(),rc.Height());
pDC->SetViewportExt(rc.Width(),-rc.Height());
pDC->SetViewportOrg(50,rc.Height()-50);

MemDC->SetMapMode(MM_ISOTROPIC); //内存DC中的映射模式
MemDC->SetWindowExt(rc.Width(),rc.Height());
MemDC->SetViewportExt(rc.Width(),-rc.Height());
MemDC->SetViewportOrg(50,rc.Height()-50);

MemDC->SetBkMode(TRANSPARENT); //透明背景
MemDC->SetTextColor(RGB(0,0,0)); //黑色

if(isOpen)
{
}
else
{
MemDC->Rectangle(0,0,50,50);

MemDC->BeginPath();
MemDC->MoveTo(0,0);
MemDC->LineTo(50,0);
MemDC->LineTo(25,50);
MemDC->LineTo(0,0);
MemDC->EndPath();

CRgn rgn;
rgn.CreateFromPath(MemDC);
MemDC->InvertRgn(&rgn);
}
pDC->BitBlt(-50,-50,rc.Width(),rc.Height(),MemDC,-50,-50,SRCCOPY);

我的坐标系设定是:客户区左下角的斜上方(右50上50)为坐标原点,X轴向右为正,Y轴向上为正。
运行结果:

请问为什么BeginPath和EndPath之间画的三角形不在客户区左下角?

...全文
139 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
zgl7903 2015-06-19
  • 打赏
  • 举报
回复
充分利用SaveDC 和 RestoreDC 维护DC栈 BitBlt之前恢复映射

void OnDraw2(CDC *pDstDC, int nWidth, int nHeight)
{
  CDC memDC, *pDC = &memDC;
  pDC->CreateCompatibleDC(pDstDC);
  
 pDC->SaveDC();  
  
  CBitmap memBmp;  
  memBmp.CreateCompatibleBitmap(pDstDC, nWidth, nHeight);
  pDC->SelectObject(&memBmp);
  pDC->FillSolidRect(0, 0, nWidth, nHeight, RGB(255, 255, 255)); //填充背景色
  
  {
   pDC->SaveDC();
   
    int iMapMode = pDC->SetMapMode(MM_ISOTROPIC);
    CSize wndExt = pDC->SetWindowExt(nWidth, nHeight);    
    CSize vptExt = pDC->SetViewportExt(min(nWidth, nHeight), -min(nWidth, nHeight));    
    CPoint vptOrg = pDC->SetViewportOrg(nWidth/2, nHeight/2);    

    pDC->SetBkMode(TRANSPARENT);
    CPen linePen(PS_SOLID, 2, RGB(255, 0, 0));
    pDC->SelectObject( &linePen );

    pDC->MoveTo(0, 0);
    pDC->LineTo(400,  0);
    pDC->MoveTo(0, 0);
    pDC->LineTo(0, 400);
    pDC->MoveTo(0, 0);
    pDC->LineTo(300, 300);
        
   pDC->RestoreDC(-1);
  }

  pDstDC->BitBlt(0, 0, nWidth, nHeight, pDC, 0, 0, SRCCOPY);

  //结束清理
 pDC->RestoreDC(-1);
}
wal199005 2015-06-19
  • 打赏
  • 举报
回复
好啦 我解决啦
不用CRgn这个类和InvertRgn了。用FillPath()这个函数
坐标系映射方式不变


MemDC->Rectangle(0,0,50,50);

CBrush brush1;
brush1.CreateSolidBrush(RGB(0,0,0));
MemDC->SelectObject(&brush1); //把画刷选择到设备描述表中

MemDC->BeginPath();
MemDC->MoveTo(0,0);
MemDC->LineTo(50,0);
MemDC->LineTo(25,50);
MemDC->LineTo(0,0);
MemDC->EndPath();
MemDC->FillPath();


运行结果如下:


感谢大家的回复!谢谢!
wal199005 2015-06-19
  • 打赏
  • 举报
回复
引用 8 楼 zgl7903 的回复:
充分利用SaveDC 和 RestoreDC 维护DC栈 BitBlt之前恢复映射

void OnDraw2(CDC *pDstDC, int nWidth, int nHeight)
{
  CDC memDC, *pDC = &memDC;
  pDC->CreateCompatibleDC(pDstDC);
  
 pDC->SaveDC();  
  
  CBitmap memBmp;  
  memBmp.CreateCompatibleBitmap(pDstDC, nWidth, nHeight);
  pDC->SelectObject(&memBmp);
  pDC->FillSolidRect(0, 0, nWidth, nHeight, RGB(255, 255, 255)); //填充背景色
  
  {
   pDC->SaveDC();
   
    int iMapMode = pDC->SetMapMode(MM_ISOTROPIC);
    CSize wndExt = pDC->SetWindowExt(nWidth, nHeight);    
    CSize vptExt = pDC->SetViewportExt(min(nWidth, nHeight), -min(nWidth, nHeight));    
    CPoint vptOrg = pDC->SetViewportOrg(nWidth/2, nHeight/2);    

    pDC->SetBkMode(TRANSPARENT);
    CPen linePen(PS_SOLID, 2, RGB(255, 0, 0));
    pDC->SelectObject( &linePen );

    pDC->MoveTo(0, 0);
    pDC->LineTo(400,  0);
    pDC->MoveTo(0, 0);
    pDC->LineTo(0, 400);
    pDC->MoveTo(0, 0);
    pDC->LineTo(300, 300);
        
   pDC->RestoreDC(-1);
  }

  pDstDC->BitBlt(0, 0, nWidth, nHeight, pDC, 0, 0, SRCCOPY);

  //结束清理
 pDC->RestoreDC(-1);
}
谢谢你的回复,我又学习了。 我建立的坐标系必须得是左下角是原点,在这个坐标系中画图,而且很多图形(由直线和弧线构成)要先画出边缘,再填充内部。当坐标系为我设定的坐标系时,如何才能用BeginPath和EndPath实现我的功能呀?
赵4老师 2015-06-18
  • 打赏
  • 举报
回复
Coordinate Space and Transformation Functions The following functions are used with coordinate spaces and transformations. ClientToScreen CombineTransform DPtoLP GetCurrentPositionEx GetGraphicsMode GetMapMode GetViewportExtEx GetViewportOrgEx GetWindowExtEx GetWindowOrgEx GetWorldTransform LPtoDP MapWindowPoints ModifyWorldTransform OffsetViewportOrgEx OffsetWindowOrgEx ScaleViewportExtEx ScaleWindowExtEx ScreenToClient SetGraphicsMode SetMapMode SetViewportExtEx SetViewportOrgEx SetWindowExtEx SetWindowOrgEx SetWorldTransform
wal199005 2015-06-18
  • 打赏
  • 举报
回复
我在MSDN里看了一下InvertRgn()这个函数 BOOL InvertRgn( CRgn* pRgn ); Parameters pRgn Identifies the region to be inverted. The coordinates for the region are specified in device units. device units?这里是不是把BeginPath和EndPath之间所画的图形转化到设备坐标系中了?那也不对呀,设备坐标原点不是一直在客户区左上角吗?
wal199005 2015-06-16
  • 打赏
  • 举报
回复
UP UP UP 谁知道呀 BeginPath和EndPath之间到底坐标系怎么了??
wal199005 2015-06-16
  • 打赏
  • 举报
回复
引用 2 楼 happyparrot 的回复:
似乎只需要调整MemDC的投影模式,pDC的不需要调整...... 对于pDC来说,它看到的只是一张图而已......
因为要用BitBlt实现复制,如果坐标系不一样,那复制过来的图就不对了
wal199005 2015-06-16
  • 打赏
  • 举报
回复
引用 2 楼 happyparrot 的回复:
似乎只需要调整MemDC的投影模式,pDC的不需要调整...... 对于pDC来说,它看到的只是一张图而已......
MemDC的映射方式不对吗?画矩形的位置的确是我想要的,但是三角形应该在上面吗?为什么在上面呀?
快乐鹦鹉 2015-06-16
  • 打赏
  • 举报
回复
似乎只需要调整MemDC的投影模式,pDC的不需要调整...... 对于pDC来说,它看到的只是一张图而已......
wal199005 2015-06-16
  • 打赏
  • 举报
回复
isOpen是标志位,判断是否响应了OnFileOpen().

19,469

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧