(10)一步一步开发一个简单CAD之捕捉

   

以以上三个标记为例,三个捕捉标记表现形式都不同,但本质上是一样的

都可以归结为矩形标记,所以在探测点是否落在标记内,都可以测试是否

落在矩形内,如果实体的端点落在矩形内,则就用矩形的中心点替换鼠标

点击的点,就实现了捕捉

 

同时由有三个标记本质上一样,都可以从矩形标记派生,只要改写一下画标记的

虚函数即可,可以用模版的设计模式实现捕捉

 

class CMyrect//端点,使用模版设计模式,直接仅仅需要改写画矩形的函数即可
{
public:
 CMyrect(){ m_br = FALSE;};
 CMyrect(CPosition pos);
 virtual ~CMyrect(){};
 BOOL PisRect(CPosition pos);
 void DrawRect(CDC *pDC, BOOL b, int Mode, CPosition pos, CPosition *center);
 void GetRect(const CPosition &pos);
 virtual void Solid(CPoint pt[4], CDC *pDC);//矩形四个点
static void DrawMRect(CDC *pDC, int Num, CPosition *Numpos, CPosition *pos, CPosition *bpos, CMyrect *rect);
public:
 CPosition m_left_up, m_left_down;
 CPosition m_right_up, m_right_down;
 CPosition m_center;
 BOOL m_br;//判断点是在矩形内还是在矩形外
};

class CMyCircle : public CMyrect//圆心标记,直接改写solid虚函数即可
{
public:
 CMyCircle(){};
 CMyCircle(CPosition pos);
 virtual ~CMyCircle(){};
public:
 void Solid(CPoint pt[4], CDC *pDC);
};

class CMyTri : public CMyrect//中点标记,直接改写solid虚函数即可
{
public:
 CMyTri(){};
 CMyTri(CPosition pos);
 virtual ~CMyTri(){};
public:
 void Solid(CPoint pt[4], CDC *pDC);
};

class CCros : public CMyrect //中点标记,直接改写solid虚函数即可
{
public:
 CCros (){};
 CCros (CPosition pos);
 virtual ~CCros (){};
public:
 void Solid(CPoint pt[4], CDC *pDC);
};

CMyrect::CMyrect(CPosition pos)//边长为5个像素的正方形
{


   GetRect(pos);
   m_br = FALSE;

}

void CMyrect::GetRect(const CPosition &pos)
{
    m_right_up = CPosition(0.707,0.707) * 8 * g_pView->m_scale + pos;


 m_left_up =  CPosition(-0.707,0.707) * 8 * g_pView->m_scale + pos;
 m_right_down =  CPosition(0.707,-0.707) * 8 * g_pView->m_scale + pos;
    m_left_down =  CPosition(-0.707,-0.707) * 8 * g_pView->m_scale + pos;
 m_center = pos;
}

BOOL CMyrect::PisRect(CPosition pos)
{
 if (pos.m_x >= m_left_down.m_x && pos.m_x <= m_right_down.m_x
  && pos.m_y <= m_left_up.m_y && pos.m_y >= m_left_down.m_y)
 {
  return TRUE;
 }
 else
 {
  return FALSE;
 }
}

void CMyrect::DrawRect(CDC *pDC, BOOL b, int Mode, CPosition pos, CPosition *center)
{

   CPoint pt[4]; 
      g_pView->WPTODP(m_left_up, pt[0]);
   g_pView->WPTODP(m_right_down, pt[1]);

   g_pView->WPTODP(m_left_down, pt[2]);
   g_pView->WPTODP(m_right_up, pt[3]);

    if(PisRect(pos))//打开或者关闭标记的开关
    {
 
 m_br = TRUE; 
 CPen pen;
 
 pen.CreatePen(PS_SOLID, 1, RGB(225,144,0));

  
 int n = pDC->GetROP2();
  CPen *Oldpen = NULL;
  Oldpen = pDC->SelectObject(&pen);

    Solid(pt,pDC);

 pDC->SetROP2(n);
 pDC->SelectObject(Oldpen);

   if (center)//如果选中,则得到中心点,只有用特种艳色的时候,才能选中点
      {
   *center = m_center;
      }

   return;
    }
 else if(m_br)
 {
       
 CPen pen;
 
 pen.CreatePen(PS_SOLID, 1, RGB(0,0,0));

  
 int n = pDC->GetROP2();
  CPen *Oldpen = NULL;
  Oldpen = pDC->SelectObject(&pen);

    Solid(pt,pDC);

 pDC->SetROP2(n);
 pDC->SelectObject(Oldpen);

 m_br = FALSE;


 }
   
}

void CMyrect::DrawMRect(CDC *pDC, int Num, CPosition *Numpos, CPosition *pos, CPosition *bpos, CMyrect *rect)//画出多个矩形标记
{
  
  for (int i = 0; i < Num; i++)
  {
   rect[i].GetRect(Numpos[i]);
   rect[i].DrawRect(pDC, rect[i].PisRect(*pos), 1, *pos, bpos);
  }

  

}

void CMyrect::Solid(CPoint pt[4], CDC *pDC)
{
     pDC->MoveTo(pt[0]);
  pDC->LineTo(pt[3]);
  pDC->LineTo(pt[1]);
  pDC->LineTo(pt[2]);
  pDC->LineTo(pt[0]);
}

CMyCircle::CMyCircle(CPosition pos) : CMyrect(pos)
{
 
}

void CMyCircle::Solid(CPoint pt[4], CDC *pDC)
{

    CBrush brush;
 LOGBRUSH logbrush;
 logbrush.lbStyle = BS_NULL;
 
 brush.CreateBrushIndirect(&logbrush);

 int n = pDC->GetROP2();
  CPen *Oldpen = NULL;
 CBrush *Oldbrush = NULL;
 Oldbrush = pDC->SelectObject(&brush);
 

    pDC->Ellipse(&CRect(pt[0], pt[1]));

 pDC->SetROP2(n);

 pDC->SelectObject(Oldbrush);
}

CMyTri::CMyTri(CPosition pos) : CMyrect(pos)
{
 
}

void CMyTri::Solid(CPoint pt[4], CDC *pDC)
{
  CPoint pos =  pt[0] + pt[3] ;
     pos.x *= 0.5;
  pos.y *= 0.5;
 
     pDC->MoveTo(pos);
  pDC->LineTo(pt[2]);
  pDC->LineTo(pt[1]);
  pDC->LineTo(pos);

}

CCros::CCros(CPosition pos) : CMyrect(pos)
{
 
}

void CCros::Solid(CPoint pt[4], CDC *pDC)
{
     CPoint pos[4];

  pos[0] = pt[0] + pt[3];
  pos[0].x *= 0.5;
  pos[0].y *= 0.5;

  pos[1] = pt[0] + pt[2];
  pos[1].x *= 0.5;
  pos[1].y *= 0.5;

  pos[2] = pt[2] + pt[1];
  pos[2].x *= 0.5;
  pos[2].y *= 0.5;

  pos[3] = pt[1] + pt[3];
  pos[3].x *= 0.5;
  pos[3].y *= 0.5;


 
     pDC->MoveTo(pos[0]);
  pDC->LineTo(pos[1]);
  pDC->LineTo(pos[2]);
  pDC->LineTo(pos[3]);
  pDC->LineTo(pos[0]);

}

 

原文地址:https://www.cnblogs.com/lizhengjin/p/1289758.html