mfc数轴实现

  1 #pragma once
  2 #include <afxwin.h>
  3 #include <memory>
  4 #include "project_scjd/YwEmpDataControl.h"
  5 #include "cg/fyq_interpreter.h"
  6 #include "cg/File_TbCatalog2017.h"
  7 class CFyqEntity;
  8 class CRuleNodeEntity;
  9 class CPositionNodeEntity;
 10 class CArrowEntity;
 11 class CNodeEntity;
 12 typedef shared_ptr<CFyqEntity>      EntityPtr;
 13 typedef shared_ptr<CRuleNodeEntity>     RuleNodePtr;
 14 typedef shared_ptr<CPositionNodeEntity>  PointNodePtr;
 15 typedef shared_ptr<CArrowEntity>    ArrowPtr;
 16 typedef shared_ptr<CNodeEntity>        BaseNodeEntity;
 17 
 18 typedef std::vector<EntityPtr>        VecEntity;
 19 typedef std::vector<RuleNodePtr> VecRule;
 20 typedef std::vector<PointNodePtr> VecPointNode;
 21 #define radius 7
 22 #define SelectedColor RGB(111, 111, 0)
 23 #define NoSelectedColor RGB(118, 238, 0)
 24 enum EntityGrade {
 25     EG_Arrow, EG_Axis, EG_RuleNode, EG_PositionNode
 26 };
 27 enum MenuID { MI_Edit = 1, MI_Delete, MI_AddPositionNode };
 28 
 29 #define MI_Edit_Tip  "编辑"  
 30 #define MI_Delete_Tip  "删除"  
 31 #define MI_AddPositionNode_Tip  "添加坐标"  
 32 
 33 class CFyqEntity
 34 {
 35 
 36 public:
 37     CFyqEntity();
 38     ~CFyqEntity();
 39     virtual int GetGrade() 
 40     {
 41         return -1;
 42     }
 43     virtual CRect GetBoundingBox()
 44     {
 45         return m_rect;
 46     }
 47     virtual void  OnDraw(CDC* pDC);
 48     virtual    void  DrawBoundingBox(CDC* pDC);
 49     virtual bool UpdateInfo(CWnd* pWnd); 
 50     virtual vecInt GetMenuIDvec()
 51     {
 52         vecInt vec;
 53         return vec;
 54     }
 55 public:
 56     void    SetSelected(bool val);
 57     bool    bSelected();
 58     bool    m_bSelected;
 59     CPoint        m_Origin;//原点
 60     CRect        m_rect;//轮廓
 61     CString        m_sContent;//显示内容
 62 };
 63 
 64 
 65 class CArrowEntity : public CFyqEntity
 66 {
 67 public:
 68     CArrowEntity(CPoint& origin, CPoint& uppoint, CPoint& downpoint)
 69     {
 70         m_originPoint = origin;
 71         m_upPoint = uppoint;
 72         m_downPoint = downpoint;
 73     }
 74     void SetPoint(CPoint& origin, CPoint& uppoint, CPoint& downpoint)
 75     {
 76         m_originPoint = origin;
 77         m_upPoint = uppoint;
 78         m_downPoint = downpoint;
 79         m_rect.SetRect(m_upPoint.x, m_upPoint.y, m_originPoint.x, m_downPoint.y);
 80     }
 81 public:
 82     virtual int GetGrade() { return EG_Arrow; }
 83     virtual CRect GetBoundingBox();
 84     virtual void  OnDraw(CDC* pDC);
 85 public:
 86     CPoint   m_upPoint;
 87     CPoint   m_downPoint;
 88     CPoint     m_originPoint;
 89 
 90 };
 91 
 92 class CAxisEntity : public CFyqEntity
 93 {
 94 public:
 95     CAxisEntity(CPoint& start, CPoint& end);
 96     virtual int GetGrade() { return EG_Axis; }
 97     virtual CRect GetBoundingBox();
 98     virtual void  OnDraw(CDC* pDC);
 99     virtual vecInt GetMenuIDvec();
100     
101 public:
102     void SetStartPoint(CPoint &pt);
103     void SetEndPoint(CPoint &pt);
104     void SetArrow(ArrowPtr arrow);
105 private:
106     CPoint   m_start;
107     CPoint   m_end;
108     ArrowPtr m_Arrow;
109 };
110 
111 class CNodeEntity : public CFyqEntity
112 {
113 public:
114     CNodeEntity();
115 public:
116     virtual int GetGrade() = 0;
117     virtual CRect GetBoundingBox();
118     virtual void  OnDraw(CDC* pDC);
119 public:
120     void SetRect(CPoint pt1, CPoint pt2);
121     void SetContent(CString val);
122     CString GetContent();
123     CRect GetRect();
124     bool GetUpdate()
125     {
126         return m_bupdate;
127     }
128     void SetUpdate(int flag)
129     {
130         m_bupdate = flag;
131     }
132 protected:
133     bool m_bupdate;
134 };
135 
136 class CRuleNodeEntity : public CNodeEntity
137 {
138 public:
139     CRuleNodeEntity();
140     CRuleNodeEntity(PointNodePtr leftnode,PointNodePtr rightnode,CString& str,int high, int low,int SheetMaxH);
141     ~CRuleNodeEntity();
142     virtual int GetGrade() { return EG_RuleNode; }
143     virtual void OnDraw(CDC* pDC);
144     virtual bool UpdateInfo(CWnd* pWnd); 
145     virtual vecInt GetMenuIDvec();
146     PointNodePtr GetleftNode() {
147         return m_pleftNode;
148     }
149     PointNodePtr GetRightNode() {
150         return m_pRightNode;
151     }
152     void Sethigh(int x)
153     {
154         m_nhigh = x;
155         m_sContent.Format("%d高,%d低", m_nhigh, m_nlow);
156     }
157     void Setlow(int x)
158     {
159         m_nlow = x;
160         m_sContent.Format("%d高,%d低", m_nhigh, m_nlow);
161     }
162     int Gethigh()
163     {
164         return m_nhigh;
165     }
166     int Getlow()
167     {
168         return m_nlow;
169     }
170     void SetSheetHigh(int high)
171     {
172         m_nsheetHigh = high;
173     }
174 public:
175     PointNodePtr m_pleftNode;
176     PointNodePtr m_pRightNode;
177 private:
178     int m_nhigh;
179     int m_nlow;
180     int m_nsheetHigh;
181 };
182 
183 class CPositionNodeEntity : public CNodeEntity
184 {
185 public:
186     CPositionNodeEntity(CPoint& point,int number,int flag);
187     CPositionNodeEntity(int number, int flag);
188     virtual int GetGrade() { return EG_PositionNode; }
189     virtual void OnDraw(CDC* pDC);
190     virtual bool UpdateInfo(CWnd* pWnd); 
191     virtual vecInt GetMenuIDvec();
192 
193     void SetPointx(int x)
194     {
195         m_nx = x;
196     }
197     void SetRealX(int x)
198     {
199         m_Origin.x = x;
200         m_rect.TopLeft().x = m_Origin.x - radius;
201         m_rect.BottomRight().x = m_Origin.x + radius;
202     }
203     void SetRealY(int y)
204     {
205         m_Origin.y = y;
206         m_rect.TopLeft().y = m_Origin.y - radius;
207         m_rect.BottomRight().y = m_Origin.y + radius;
208     }
209     int GetPointx()
210     {
211         return m_nx;
212     }
213     void SetNextNode(PointNodePtr node)
214     {
215         m_pNextNode = node;
216     }
217     void SetLastNode(PointNodePtr node)
218     {
219         m_pLastNode = node;
220     }
221 
222     PointNodePtr GetNextNode()
223     {
224         return m_pNextNode;
225     }
226     PointNodePtr GetLastNode()
227     {
228         return m_pLastNode;
229     }
230 
231     void SetLastRule(RuleNodePtr node)
232     {
233         m_pLastRule = node;
234     }
235     void SetRule(RuleNodePtr node)
236     {
237         m_pRule = node;
238     }
239     int GetX()
240     {
241         return m_nx;
242     }
243 private:
244     int m_nx;
245     PointNodePtr m_pNextNode;
246     PointNodePtr m_pLastNode;
247     RuleNodePtr m_pLastRule;
248     RuleNodePtr m_pRule;
249     int m_flag;
250 
251 };
252 
253 
254 class CFyqEnityMgr
255 {
256 public:
257     CFyqEnityMgr();
258 
259     bool CreateEntities(Cfyq_expression* exp,CRect& rect);
260     void OnDraw(CDC* pDC, CRect& rect);
261     CRect GetBoundingBox();
262     EntityPtr SelectEntity(CPoint pt);
263     void SetSelected(bool val);
264     bool IsEmpty();
265     void SetScopeToExpression(Cfyq_expression* exp);
266 public://编辑
267     bool EditEntity(CPoint pt, CWnd* pWnd);
268     bool EditNodeBackGround(CPoint pt, CWnd* pWnd);
269     bool DeleteEntity(EntityPtr pEnt);
270     bool AddPositionNode(CPoint &point);
271     void AddPositionNode(int numx);
272     void DeleteRule(PointNodePtr start, PointNodePtr end);
273     PointNodePtr ExistPointNode(int nNum);
274     RuleNodePtr ExistRule(int nNum);
275 public:
276     void findRule();
277     void findPosition();
278 protected:
279     VecEntity        m_Entities;
280     VecRule            m_VecRule;
281     VecPointNode    m_VecPoint;
282     PointNodePtr    m_lastNode;
283 
284     BaseNodeEntity    m_LastSelected;
285 
286     int                m_nPointCount;
287     int                m_nNowHigh;
288     //CFile_TbCatalogTreeCtrl *m_pCtrl;
289 };
290 
291 
292 
293 
294 /////////////////////////////////////////////////////////////////////////////
295 //去高去低编辑框
296 class FLY_DBASE_API CD_EditHighLowDlg : public CXTPResizeDialog
297 {
298 public:
299     CD_EditHighLowDlg(CWnd* pParent = NULL);
300     ~CD_EditHighLowDlg();
301 
302     void SetValue(CString str, int nHighNum, int nLowNum,int max,CPoint& point);
303 public:
304     virtual BOOL OnInitDialog();
305     virtual void DoDataExchange(CDataExchange* pDX);
306     virtual void OnOK();
307     DECLARE_MESSAGE_MAP()
308 public:
309     CString m_sHighNum;
310     CString m_sLowNum;
311     CString m_sShowAdd;
312     int        m_nHighNum;
313     int        m_nLowNum;
314     int        m_Max;
315     CPoint  m_point;
316 };
317 //修改已存在的点
318 class FLY_DBASE_API CD_EditPointDlg : public CXTPResizeDialog
319 {
320 public:
321     CD_EditPointDlg(CWnd* pParent = NULL);
322     ~CD_EditPointDlg();
323 
324     void SetValue(CString str, int max, int min,CPoint &point);
325 public:
326     virtual BOOL OnInitDialog();
327     virtual void DoDataExchange(CDataExchange* pDX);
328     virtual void OnOK();
329     DECLARE_MESSAGE_MAP()
330 public:
331     CString m_sShowPoint;
332     CString m_sEditPoint;
333     int m_nMax;
334     int m_nMin;
335     int m_nNum;
336     CPoint m_point;
337 };
338 
339 
340 
341 class FLY_DBASE_API CD_AddPointDlg : public CXTPResizeDialog
342 {
343 public:
344     CD_AddPointDlg(CWnd* pParent = NULL);
345     ~CD_AddPointDlg();
346 
347 public:
348     virtual BOOL OnInitDialog();
349     virtual void DoDataExchange(CDataExchange* pDX);
350     void SetValue(CPoint& point);
351     virtual void OnOK();
352     DECLARE_MESSAGE_MAP()
353 public:
354     CString m_sAddPoint;
355     int        m_nNum;
356     CPoint  m_point;
357 };
#include "stdafx.h"
#include <afxwin.h>
#include <memory>

#include "ZbFile_Add_MaxMin.h"
#include "Resource.h"
CString GetMenuStringByID(int nID)
{
    switch (nID)
    {
    case MI_Edit:
        return MI_Edit_Tip;
    case MI_Delete:
        return MI_Delete_Tip;
    case MI_AddPositionNode:
        return MI_AddPositionNode_Tip;
    default:
        break;
    }
    return _T("");
}

CFyqEntity::CFyqEntity()
{
    m_bSelected = false;
}

CFyqEntity::~CFyqEntity()
{

}
void CFyqEntity::OnDraw(CDC* pDC)
{
    if (m_bSelected)
    {
        DrawBoundingBox(pDC);
    }
}
void CFyqEntity::DrawBoundingBox(CDC* pDC)
{
    CRect rt = GetBoundingBox();
    if (this->GetGrade() == EG_PositionNode)
    {
        pDC->Ellipse(m_Origin.x - radius, m_Origin.y - radius, m_Origin.x + radius, m_Origin.y + radius);
    }
    else
    {
        if (this->GetGrade() == EG_RuleNode)
        {
            pDC->SelectStockObject(NULL_BRUSH);
            pDC->SelectStockObject(NULL_PEN);
        }
        pDC->Rectangle(rt);
    }
}
bool CFyqEntity::UpdateInfo(CWnd* pWnd)
{
    return true;
}

void CFyqEntity::SetSelected(bool val)
{
    m_bSelected = val;
}

bool CFyqEntity::bSelected()
{
    return m_bSelected;
}



////////////////////////////////////////////////////////////////////

CRect CArrowEntity::GetBoundingBox()
{
    return m_rect;
}

void CArrowEntity::OnDraw(CDC* pDC)
{
    CFyqEntity::OnDraw(pDC);
        //绘制箭头  
    pDC->MoveTo(m_originPoint);
    pDC->LineTo(m_upPoint);
    pDC->MoveTo(m_originPoint);
    pDC->LineTo(m_downPoint);
}

CAxisEntity::CAxisEntity(CPoint& start, CPoint& end)
{
    m_start = start;
    m_end = end;
}

//////////////////////////////////////////////////////////////////////////////

CRect CAxisEntity::GetBoundingBox()
{
    CRect rtArrow = m_Arrow->GetBoundingBox();
    CRect Allrt;
    m_rect;
    Allrt.UnionRect(m_rect, rtArrow);
    return Allrt;
}

void CAxisEntity::OnDraw(CDC* pDC)
{
    CFyqEntity::OnDraw(pDC);
    pDC->MoveTo(m_start);
    pDC->LineTo(m_end);
}

vecInt CAxisEntity::GetMenuIDvec()
{
    vecInt  temMenu;
    temMenu.push_back(MI_AddPositionNode);
    return temMenu;
}


void CAxisEntity::SetStartPoint(CPoint &pt)
{
    m_start = pt;
}

void CAxisEntity::SetEndPoint(CPoint &pt)
{
    m_end = pt;
    m_rect.SetRect(m_start.x, m_start.y - 5, m_end.x, m_end.y + 5);
}

void CAxisEntity::SetArrow(ArrowPtr arrow)
{
    m_Arrow = arrow;
}

//////////////////////////////////////////////////////////////////////////////
CNodeEntity::CNodeEntity()
{
    m_bupdate = false;
}

CRect CNodeEntity::GetBoundingBox()
{
    return m_rect;
}

void CNodeEntity::OnDraw(CDC* pDC)
{
    CFyqEntity::OnDraw(pDC);
    pDC->MoveTo(m_rect.TopLeft());
    pDC->LineTo(m_rect.BottomRight());
}

void CNodeEntity::SetRect(CPoint pt1, CPoint pt2)
{
    m_rect.SetRect(pt1, pt2);
}

void CNodeEntity::SetContent(CString val)
{
    m_sContent = val;
}

CRect CNodeEntity::GetRect()
{
    return m_rect;
}

CString CNodeEntity::GetContent()
{
    return m_sContent;
}


///////////////////////////////////////////////////////////////////////
CRuleNodeEntity::CRuleNodeEntity()
{
    m_pleftNode = NULL;
    m_pRightNode = NULL;
    m_nhigh = -1;
    m_nlow = -1;
}

CRuleNodeEntity::CRuleNodeEntity(PointNodePtr leftnode, PointNodePtr rightnode, CString& str, int high, int low,int SheetMaxH)
{
    m_pleftNode = leftnode;
    m_pRightNode = rightnode;
    
    m_rect.SetRect(leftnode->m_Origin.x, SheetMaxH, rightnode->m_Origin.x, rightnode->m_Origin.y);

    m_sContent = str;
    m_nhigh = high;
    m_nlow = low;
    m_nsheetHigh = SheetMaxH;
}    

CRuleNodeEntity::~CRuleNodeEntity()
{

}

void CRuleNodeEntity::OnDraw(CDC* pDC)
{
    CFyqEntity::OnDraw(pDC);
    CBrush brush;
    if (m_bupdate)
        brush.CreateSolidBrush(SelectedColor);
    else
        pDC->SelectStockObject(NULL_BRUSH);
    m_bupdate = 0;

    pDC->SelectStockObject(NULL_PEN);

    CBrush* pOldbrush = pDC->SelectObject(&brush);
    pDC->Rectangle(((m_pleftNode->m_Origin.x + m_pRightNode->m_Origin.x) / 2) - 25, m_nsheetHigh,
        ((m_pleftNode->m_Origin.x + m_pRightNode->m_Origin.x) / 2) + 25, m_pRightNode->m_Origin.y);
    if (pOldbrush)
        pDC->SelectObject(pOldbrush);

    pDC->SetTextColor(RGB(25, 155, 12));
    m_rect.SetRect(((m_pleftNode->m_Origin.x+ m_pRightNode->m_Origin.x)/2) - 30,m_nsheetHigh,
        ((m_pleftNode->m_Origin.x + m_pRightNode->m_Origin.x) / 2) + 30, m_pRightNode->m_Origin.y);
    pDC->DrawText(m_sContent, m_rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
    pDC->SetTextColor(RGB(0, 0, 0));
}

bool CRuleNodeEntity::UpdateInfo(CWnd* pWnd)
{
    CString str;
    str.Format("当大于等于%d家,小于%d家时", m_pleftNode->GetPointx(), m_pRightNode->GetPointx());

    int x1 = m_rect.TopLeft().x;
    int y2 = m_rect.BottomRight().y;
    CPoint point(x1, y2);
    ClientToScreen(pWnd->GetSafeHwnd(), &point);



    CD_EditHighLowDlg dlg;
     dlg.SetValue(str, m_nhigh, m_nlow, m_pRightNode->GetPointx(),point);
    if (IDOK == dlg.DoModal())
    {
        Sethigh(dlg.m_nHighNum);
        Setlow(dlg.m_nHighNum);
    }
    return true;
}

vecInt CRuleNodeEntity::GetMenuIDvec()
{
    vecInt  temMenu;
    temMenu.push_back(MI_Edit);
    return temMenu;
}

////////////////////////////////////////////////////////////////////////////////////////

CPositionNodeEntity::CPositionNodeEntity(CPoint& point, int number,int flag)
{
    m_bupdate = false;
    m_Origin = point;
    m_flag = flag;
    if (!flag)
    {

    }
    else
    {
        m_rect.TopLeft().x = m_Origin.x - radius;
        m_rect.TopLeft().y = m_Origin.y - radius;

        m_rect.BottomRight().x = m_Origin.x + radius;
        m_rect.BottomRight().y = m_Origin.y + radius;
    }

    m_nx = number;
    CString str;
    str.Format("%d", number);
    m_sContent = str;
}

CPositionNodeEntity::CPositionNodeEntity(int number, int flag)
{
    m_flag = flag;
    m_nx = number;
    CString str;
    str.Format("%d", number);
    m_sContent = str;
}

void CPositionNodeEntity::OnDraw(CDC* pDC)
{
    if (!m_flag)
    {
        return;
    }

    CFyqEntity::OnDraw(pDC);
    //设半径为8
    CBrush brush;
     if(m_bupdate)
         brush.CreateSolidBrush(SelectedColor);
    else
        brush.CreateSolidBrush(NoSelectedColor);
    m_bupdate = 0;
    
    CBrush * pOldbrush = pDC->SelectObject(&brush);
    HPEN hPen = CreatePen(PS_SOLID,1, RGB(0, 0, 0));
    pDC->SelectObject(hPen);
    pDC->Ellipse(m_Origin.x - radius, m_Origin.y - radius, m_Origin.x + radius, m_Origin.y + radius);
    if (pOldbrush)
        pDC->SelectObject(pOldbrush);
    
    CRect rect(m_Origin.x - radius, m_Origin.y - radius, m_Origin.x + radius, m_Origin.y + radius);
    CString str;
    str.Format("%d", m_nx);
    m_sContent = str;
    pDC->DrawText(str, &rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
    DeleteObject(hPen);
}

bool CPositionNodeEntity::UpdateInfo(CWnd* pWnd)
{
    CString str;
    str.Format("当前为%d,修改为:", m_nx);
    CD_EditPointDlg dlg;
    int min, max;
    if (m_pLastNode)
    {
        min = m_pLastNode->GetPointx();
    }
    else
    {
        min = 3;
    }
    if (m_pNextNode)
    {
        max = m_pNextNode->GetPointx();
    }
    else
    {
        max = 10000;
    }
    int x1 = m_rect.TopLeft().x;
    int y2 = m_rect.BottomRight().y;
    CPoint point(x1, y2);
    ClientToScreen(pWnd->GetSafeHwnd(), &point);
    dlg.SetValue(str,max,min, point);
    if (IDOK == dlg.DoModal())
    {
        SetPointx(dlg.m_nNum);
    }
    return true;
}

vecInt CPositionNodeEntity::GetMenuIDvec()
{
    vecInt  temMenu;
    temMenu.push_back(MI_Edit);
    temMenu.push_back(MI_Delete);
    return temMenu;
}

////////////////////////////////////////////////////////////////////////////////////////
CFyqEnityMgr::CFyqEnityMgr()
{
    m_nPointCount = 0;

}


bool CFyqEnityMgr::CreateEntities(Cfyq_expression* exp, CRect& rect)
{
    //该函数里面所有的坐标限于第一次初始化 修改到ondraw里面修改


/*    m_pCtrl = pCtrl;*/
    m_Entities.clear();
    std::vector<std::vector<int>> vecScope;
    vecScope = exp->GetScopeMinMax();
    CPoint leftupPoint = rect.TopLeft();
    CPoint rightdownPoint = rect.BottomRight();
    int SheetMaxH = rightdownPoint.y - 10;            //一开始起始y
    int TextAreaWidth = leftupPoint.x; //一开始起始x 因为是横着画的
    int MaxX = rightdownPoint.x;        // 最远x
    //坐标轴
    CPoint pstart(rect.TopLeft().x, SheetMaxH);
    CPoint pend(MaxX, SheetMaxH);
    auto ptrAxis = make_shared<CAxisEntity>(pstart, pend);
    m_Entities.push_back(ptrAxis);
    //箭头
    CPoint puppoint(pend.x - 10, pend.y - 5);
    CPoint pdownpoint(pend.x - 10, pend.y + 5);
    auto ptrArrow = make_shared<CArrowEntity>(pend, puppoint, pdownpoint);
    m_Entities.push_back(ptrArrow);
    ptrAxis->SetArrow(ptrArrow);
    int xMaxGrad = 5; //步进为5,目前动态计算还未完成
    //坐标点

    for (int i = 0; i < vecScope.size(); ++i)
    {
        int nBegin = vecScope[i][0];
        int nEnd = vecScope[i][1];
        int nhigh = vecScope[i][2];
        int nlow = vecScope[i][3];
        if (nBegin == 0)
        {
            continue;
        }
        CPoint pointend;
        CPoint pointstart(rect.TopLeft().x + nBegin * xMaxGrad * 10 - xMaxGrad * 25, SheetMaxH);
        pointend.x = rect.TopLeft().x + nEnd * xMaxGrad * 10 - xMaxGrad * 25;
        if (pointend.x > MaxX)
        {
            pointend.x = MaxX;
        }
        pointend.y = SheetMaxH;
        
        CString str;
        str.Format("%d高,%d低", nhigh, nlow);

        RuleNodePtr ptrLastRule = ExistRule(nBegin);
        PointNodePtr ptrPositionstart = ExistPointNode(nBegin);
        
        if (ptrPositionstart == NULL)
        {
            ptrPositionstart = make_shared<CPositionNodeEntity>(pointstart, nBegin,1);
            m_Entities.push_back(ptrPositionstart);
        }
        PointNodePtr ptrPositionend;
        if(pointend.x == MaxX)
                ptrPositionend = make_shared<CPositionNodeEntity>(pointend, nEnd,0);
        else
                ptrPositionend = make_shared<CPositionNodeEntity>(pointend, nEnd, 1);

        auto ptrCRuleNodeEnitiy = make_shared<CRuleNodeEntity>(ptrPositionstart, ptrPositionend,str, nhigh, nlow, leftupPoint.y);
        
        ptrPositionstart->SetRule(ptrCRuleNodeEnitiy);
        if (ptrLastRule != NULL)
        {
            ptrPositionstart->SetLastRule(ptrLastRule);
        }
        
        
        m_Entities.push_back(ptrPositionend);
        m_Entities.push_back(ptrCRuleNodeEnitiy);
        ptrPositionstart->SetNextNode(ptrPositionend);
        ptrPositionend->SetLastNode(ptrPositionstart);
        if (i == vecScope.size() - 1)
        {
            m_lastNode = ptrPositionend;
        }
    }
    return true;
}
void CFyqEnityMgr::OnDraw(CDC* pDC, CRect& rect)
{
    CPoint leftupPoint = rect.TopLeft();
    m_nNowHigh = leftupPoint.y;
    
    int TextAreaWidth = leftupPoint.x; //一开始起始x 因为是横着画的
    m_nPointCount = 0;
    CPoint rightdownPoint = rect.BottomRight();
    int SheetMaxH = rightdownPoint.y - 10;            //一开始起始y
    int MaxX = rightdownPoint.x;        // 最远x
    CPoint pStart(leftupPoint.x, SheetMaxH);
    CPoint pend(MaxX, SheetMaxH);
    CPoint puppoint(pend.x - 10, pend.y - 5);
    CPoint pdownpoint(pend.x - 10, pend.y + 5);
    m_lastNode->m_Origin = pend;
    for (auto it = m_Entities.begin(); it != m_Entities.end(); it++)
    {
        if ((*it)->GetGrade() == EG_Arrow)
        {
            std::dynamic_pointer_cast<CArrowEntity>(*it)->SetPoint(pend, puppoint, pdownpoint);
        }
        if ((*it)->GetGrade() == EG_Axis)
        {
            std::dynamic_pointer_cast<CAxisEntity>(*it)->SetStartPoint(pStart);
            std::dynamic_pointer_cast<CAxisEntity>(*it)->SetEndPoint(pend);
        }
        if ((*it)->GetGrade() == EG_PositionNode)
        {
            ++m_nPointCount;
        }
    }
    //根据点的个数动态计算步进
    findPosition();
    sort(m_VecPoint.begin(), m_VecPoint.end(), [](PointNodePtr node1, PointNodePtr node2)
    {
        return node1->GetX() < node2->GetX();
    });
    int xMaxGrad = -1;
    if(m_VecPoint.size() > 1)
        xMaxGrad = (MaxX - 100 - TextAreaWidth) / (10 * m_VecPoint[m_VecPoint.size() - 2]->GetX());

    for (auto it = m_Entities.begin(); it != m_Entities.end(); it++)
    {
        if ((*it)->GetGrade() == EG_PositionNode && (*it) != m_lastNode)
        {
            CPoint point;
            int number = std::dynamic_pointer_cast<CPositionNodeEntity>(*it)->GetX();
            point.x = TextAreaWidth + xMaxGrad * number * 10 - xMaxGrad * 20;
            point.y = SheetMaxH;
            std::dynamic_pointer_cast<CPositionNodeEntity>(*it)->SetRealX(point.x);
            std::dynamic_pointer_cast<CPositionNodeEntity>(*it)->SetRealY(point.y);
        }
        if ((*it)->GetGrade() == EG_RuleNode)
        {
            std::dynamic_pointer_cast<CRuleNodeEntity>(*it)->SetSheetHigh(m_nNowHigh);
        }
    }
    for (auto it = m_Entities.begin(); it != m_Entities.end(); it++)
    {
        (*it)->OnDraw(pDC);
    }
}

EntityPtr CFyqEnityMgr::SelectEntity(CPoint pt)
{
    vecInt  SelOrder;
    SelOrder.push_back(EG_RuleNode);
    SelOrder.push_back(EG_PositionNode);
    SelOrder.push_back(EG_Axis);

    for (int i = 0; i < SelOrder.size(); i++)
    {
        int order = SelOrder[i];
        auto it = find_if(m_Entities.begin(), m_Entities.end(), [=](EntityPtr ptr)
        {
            if (order == ptr->GetGrade())
            {
                CRect rt = ptr->GetBoundingBox();
                if (rt.PtInRect(pt))
                    return true;
            }
            return false;
        });
        if (it != m_Entities.end())
        {
            return (*it);
        }
    }
    return nullptr;
}

void CFyqEnityMgr::SetSelected(bool val)
{
    for (auto it = m_Entities.begin(); it != m_Entities.end(); it++)
    {
        (*it)->SetSelected(val);
    }
}

bool CFyqEnityMgr::IsEmpty()
{
    return m_Entities.empty();
}

void CFyqEnityMgr::SetScopeToExpression(Cfyq_expression* exp)
{
    m_VecRule.clear();
    for (int i = 0; i < m_Entities.size(); ++i)
    {
        if (m_Entities[i]->GetGrade() == EG_RuleNode)
        {
            auto ptr = std::dynamic_pointer_cast<CRuleNodeEntity>(m_Entities[i]);
            m_VecRule.push_back(ptr);
        }
    }
    sort(m_VecRule.begin(), m_VecRule.end(), [&](RuleNodePtr node1, RuleNodePtr node2)
    {
        return node1->GetleftNode()->GetPointx() < node2->GetleftNode()->GetPointx();
    });

    int dMinCount;
    int dMaxCount;
    int dMaxNumber;
    int dMinNumber;
    CString str;
    if (m_VecRule.size() == 1)
    {
        dMinCount = m_VecRule[0]->GetleftNode()->GetPointx();
        dMaxCount = m_VecRule[0]->GetRightNode()->GetPointx();
        dMaxNumber = m_VecRule[0]->Gethigh();
        dMinNumber = m_VecRule[0]->Getlow();
        str.Format("%d,%d,%d,%d", dMinCount, dMaxCount, dMaxNumber, dMinNumber);
        exp->GetScopeFromTree();
        exp->m_vecScope[0]->ReplaceScope(str);
    }
    else if (m_VecRule.size() > 1)
    {
        CString ans;
        for (int i = 0; i < m_VecRule.size(); ++i)
        {
            dMinCount = m_VecRule[i]->GetleftNode()->GetPointx();
            dMaxCount = m_VecRule[i]->GetRightNode()->GetPointx();
            dMaxNumber = m_VecRule[i]->Gethigh();
            dMinNumber = m_VecRule[i]->Getlow();
            if (i == m_VecRule.size() - 1)
            {
                str.Format("%d,%d,%d,%d", dMinCount, dMaxCount, dMaxNumber, dMinNumber);
            }
            else
            {
                str.Format("%d,%d,%d,%d;", dMinCount, dMaxCount, dMaxNumber, dMinNumber);
            }
            ans += str;
        }
        exp->GetScopeFromTree();
        exp->m_vecScope[0]->ReplaceScope(ans);
    }
}

CRect CFyqEnityMgr::GetBoundingBox()
{
    CRect rt;
    for (auto it = m_Entities.begin(); it != m_Entities.end(); it++)
    {
        CRect temrt = (*it)->GetBoundingBox();
        rt.UnionRect(rt, temrt);
    }
    return rt;
}
// bool CFyqEnityMgr::LButtonDraw(CPoint pt, CWnd* pWnd)
// {
//     pWnd->InvalidateRect(GetBoundingBox());
//     return true;
// }
bool CFyqEnityMgr::EditEntity(CPoint pt, CWnd* pWnd)
{
    EntityPtr pEnt = SelectEntity(pt);
    SetSelected(false);

    if (nullptr != pEnt)
    {
        pEnt->SetSelected(true);
        pWnd->InvalidateRect(GetBoundingBox());
        vecInt menuid = pEnt->GetMenuIDvec();
        CMenu menu;
        VERIFY(menu.CreatePopupMenu());
        for (int i = 0; i < menuid.size(); i++)
        {
            menu.AppendMenu(MF_STRING, menuid[i], GetMenuStringByID(menuid[i]));
        }
        //除了增加点在数轴上 其他都是在矩形的正下方
        int nCmd;
        CPoint point;
        point.y = pEnt->m_rect.BottomRight().y;
        if (pEnt->GetGrade() == EG_Axis || pEnt->GetGrade() == EG_Arrow)
        {
            point.x = pt.x;
        }
        else
        {
            point.x = pEnt->m_rect.TopLeft().x;
        }
        ClientToScreen(pWnd->GetSafeHwnd(), &point);
        nCmd = TrackPopupMenu(menu.GetSafeHmenu(), TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL | TPM_RETURNCMD,
            point.x, point.y, 0, pWnd->GetSafeHwnd(), 0);
        switch (nCmd)
        {
        case MI_Edit:
        {
            pEnt->UpdateInfo(pWnd);
        }
        break;
        case MI_Delete:
        {
            DeleteEntity(pEnt);
        }
        break;
        case MI_AddPositionNode:
        {
            AddPositionNode(point);
        }
        break;
        default:
            break;
        }
        return true;
    }
    return false;
}
bool CFyqEnityMgr::EditNodeBackGround(CPoint pt, CWnd* pWnd)
{
    auto it = find_if(m_Entities.begin(), m_Entities.end(), [=](EntityPtr ptr)
    {
        if (EG_PositionNode == ptr->GetGrade() || EG_RuleNode == ptr->GetGrade())
        {
            CRect rt = ptr->GetBoundingBox();
            if (rt.PtInRect(pt))
                return true;
        }
        return false;
    });
    if (it == m_Entities.end())
    {
        for (auto it = m_Entities.begin(); it != m_Entities.end(); ++it)
        {
            if ((*it)->GetGrade() == EG_PositionNode || (*it)->GetGrade() == EG_RuleNode)
            {
                std::dynamic_pointer_cast<CNodeEntity>(*it)->SetUpdate(false);
            }
        }
        if (m_LastSelected)
        {
            pWnd->InvalidateRect(&m_LastSelected->GetBoundingBox());
            m_LastSelected = nullptr;
        }
            
        return false;
    }
    else
    {
        std::dynamic_pointer_cast<CNodeEntity>(*it)->SetUpdate(true);
        if ((*it) != m_LastSelected)
        {
            if (m_LastSelected)
            {
                std::dynamic_pointer_cast<CNodeEntity>(m_LastSelected)->SetUpdate(false);
                pWnd->InvalidateRect(&(m_LastSelected)->GetBoundingBox());
            }
            m_LastSelected = std::dynamic_pointer_cast<CNodeEntity>(*it);
            pWnd->InvalidateRect(&(*it)->GetBoundingBox());
        }
        return true;
    }

}
bool CFyqEnityMgr::DeleteEntity(EntityPtr pEnt)
{
    //数据中的
    //不能存在已有的点
    PointNodePtr nowNode = std::dynamic_pointer_cast<CPositionNodeEntity>(pEnt);
    if (nowNode == NULL)
    {
        return false;
    }
    PointNodePtr leftnode = nowNode->GetLastNode();
    PointNodePtr rightnode = nowNode->GetNextNode();
    if (leftnode)
        leftnode->SetNextNode(rightnode);
    rightnode->SetLastNode(leftnode);
    for (auto it = m_Entities.begin(); it != m_Entities.end();)
    {
        if ((*it)->GetGrade() == EG_RuleNode)
        {
            if (std::dynamic_pointer_cast<CRuleNodeEntity>((*it))->GetleftNode() == nowNode ||
                std::dynamic_pointer_cast<CRuleNodeEntity>((*it))->GetRightNode() == nowNode)
            {
                it = m_Entities.erase(it);
            }
            else
            {
                ++it;
            }
        }
        else
        {
            ++it;
        }
    }
    for (auto it = m_Entities.begin(); it != m_Entities.end();)
    {
        if ((*it) == pEnt)
        {
            it = m_Entities.erase(it);
        }
        else
        {
            ++it;
        }
    }
    CString str;
    str.Format("0高,0低");
    if (leftnode)
    {
        auto PtrRule = make_shared<CRuleNodeEntity>(leftnode, rightnode, str, 0, 0, m_nNowHigh);
        m_Entities.push_back(PtrRule);
    }
    return true;
}
//&& -> & 
bool CFyqEnityMgr::AddPositionNode(CPoint &point)
{
    CD_AddPointDlg dlg;
    dlg.SetValue(point);
    if (IDOK == dlg.DoModal())
    {
        AddPositionNode(dlg.m_nNum);
    }
    return true;
}
void CFyqEnityMgr::DeleteRule(PointNodePtr start, PointNodePtr end)
{
    findRule();
    for (auto it = m_Entities.begin(); it != m_Entities.end();)
    {
        if ((*it)->GetGrade() == EG_RuleNode)
        {
            if (std::dynamic_pointer_cast<CRuleNodeEntity>(*it)->GetleftNode() == start
                && std::dynamic_pointer_cast<CRuleNodeEntity>(*it)->GetRightNode() == end)
            {
                it = m_Entities.erase(it);
            }
            else
            {
                ++it;
            }
        }
        else
        {
            ++it;
        }
    }
}
void CFyqEnityMgr::AddPositionNode(int numx)
{
    findPosition();
    //不能存在已有的点
    PointNodePtr ptr;
    CString str;
    str.Format("%d高,%d低", 0, 0);
    sort(m_VecPoint.begin(), m_VecPoint.end(), [](PointNodePtr node1, PointNodePtr node2)
    {
        return node1->GetX() < node2->GetX();
    });
    for (int i = 0; i < m_VecPoint.size() - 1; ++i)
    {
        if (numx > m_VecPoint[i]->GetX() && numx < m_VecPoint[i + 1]->GetX())
        {
            ptr = make_shared<CPositionNodeEntity>(numx,1);
            ptr->SetLastNode(m_VecPoint[i]);
            ptr->SetNextNode(m_VecPoint[i + 1]);
            //删除已有的矩形
            DeleteRule(m_VecPoint[i], m_VecPoint[i + 1]);
            //创建已有矩形
            
            auto PtrFirstRule = make_shared<CRuleNodeEntity>(m_VecPoint[i], ptr, str, 0, 0, m_nNowHigh);
            auto PtrSecondRule = make_shared<CRuleNodeEntity>(ptr, m_VecPoint[i+1], str, 0, 0, m_nNowHigh);
            m_Entities.push_back(ptr);
            m_Entities.push_back(PtrFirstRule);
            m_Entities.push_back(PtrSecondRule);
            return;
        }
    }
    ptr = make_shared<CPositionNodeEntity>(numx, 1);
    ptr->SetNextNode(m_VecPoint[0]);
    auto PtrFirstRule = make_shared<CRuleNodeEntity>(ptr, m_VecPoint[0], str, 0, 0, m_nNowHigh);
    m_Entities.push_back(ptr);
    m_Entities.push_back(PtrFirstRule);
    
}



PointNodePtr CFyqEnityMgr::ExistPointNode(int nNum)
{
    findPosition();
    auto it = find_if(m_VecPoint.begin(), m_VecPoint.end(), [nNum](PointNodePtr node)
    {
        return node->GetX() == nNum;
    });
    if (it != m_VecPoint.end())
    {
        return *it;
    }
    else
    {
        return NULL;
    }
}

RuleNodePtr CFyqEnityMgr::ExistRule(int nNum)
{
    findRule();
    auto it = find_if(m_VecRule.begin(), m_VecRule.end(), [&](RuleNodePtr node)
    {
        return node->GetRightNode()->GetX() == nNum;
    });
    if (it != m_VecRule.end())
    {
        return *it;
    }
    else
    {
        return NULL;
    }
}

void CFyqEnityMgr::findRule()
{
    m_VecRule.clear();
    for (int i = 0; i < m_Entities.size(); ++i)
    {
        if (m_Entities[i]->GetGrade() == EG_RuleNode)
        {
            auto ptr = std::dynamic_pointer_cast<CRuleNodeEntity>(m_Entities[i]);
            m_VecRule.push_back(ptr);
        }
    }
}

void CFyqEnityMgr::findPosition()
{
    m_VecPoint.clear();
    for (int i = 0; i < m_Entities.size(); ++i)
    {
        if (m_Entities[i]->GetGrade() == EG_PositionNode)
        {
            auto ptr = std::dynamic_pointer_cast<CPositionNodeEntity>(m_Entities[i]);
            m_VecPoint.push_back(ptr);
        }
    }
}

///////////////////////////////////////////////////////////////////
CD_EditHighLowDlg::CD_EditHighLowDlg(CWnd* pParent /*= NULL*/)
    :CXTPResizeDialog(IDD_DLG_HighLow, pParent)
{

}

CD_EditHighLowDlg::~CD_EditHighLowDlg()
{

}

BEGIN_MESSAGE_MAP(CD_EditHighLowDlg, CXTPResizeDialog)
END_MESSAGE_MAP()

void CD_EditHighLowDlg::SetValue(CString str, int nHighNum, int nLowNum,int max,CPoint& point)
{
    m_sShowAdd = str;
    m_sHighNum.Format(_T("%d"), nHighNum);
    m_sLowNum.Format(_T("%d"), nLowNum);
    m_Max = max;
    m_point = point;
}

BOOL CD_EditHighLowDlg::OnInitDialog()
{
    __super::OnInitDialog();
    CRect rect(m_point.x, m_point.y+5, m_point.x + 225, m_point.y + 120);
    MoveWindow(&rect);
    UpdateData(FALSE);
    return TRUE;
}

void CD_EditHighLowDlg::DoDataExchange(CDataExchange* pDX)
{
    __super::DoDataExchange(pDX);
    DDX_Text(pDX, IDC_STATIC_ShowAdd, m_sShowAdd);
    DDX_Text(pDX, IDC_EDIT_High, m_sHighNum);
    DDX_Text(pDX, IDC_EDIT_Low, m_sLowNum);
}

void CD_EditHighLowDlg::OnOK()
{
    UpdateData(TRUE);
    m_nHighNum = atoi(m_sHighNum);
    m_nLowNum = atoi(m_sLowNum);
    if (m_nHighNum + m_nLowNum >= m_Max)
    {
        AfxMessageBox("去高去低的企业数不能大于等于最大企业数!");
        return;
    }
    EndDialog(IDOK);
}

////////////////////////////////////////////////////////
CD_EditPointDlg::CD_EditPointDlg(CWnd* pParent /*= NULL*/)
    :CXTPResizeDialog(IDD_Edit_Point, pParent)
{

}

CD_EditPointDlg::~CD_EditPointDlg()
{

}

BEGIN_MESSAGE_MAP(CD_EditPointDlg, CXTPResizeDialog)
END_MESSAGE_MAP()

void CD_EditPointDlg::SetValue(CString str, int max,int min,CPoint& point)
{
    m_sShowPoint = str;
    m_nMax = max;
    m_nMin = min;
    m_point = point;
}
BOOL CD_EditPointDlg::OnInitDialog()
{
    __super::OnInitDialog();
    CRect rect(m_point.x, m_point.y, m_point.x + 180, m_point.y + 80);
    MoveWindow(&rect);
    UpdateData(FALSE);
    return TRUE;
}

void CD_EditPointDlg::DoDataExchange(CDataExchange* pDX)
{
    __super::DoDataExchange(pDX);
    DDX_Text(pDX, IDC_EDIT_Point, m_sEditPoint);
    DDX_Text(pDX, IDC_STATIC_Point, m_sShowPoint);
}

void CD_EditPointDlg::OnOK()
{
    UpdateData(TRUE);
    m_nNum = atoi(m_sEditPoint);
    CString str;
    
    str.Format("输入范围需要大于%d,小于%d!", m_nMin, m_nMax);
    if (!(m_nNum < m_nMax && m_nNum >= m_nMin))
    {
        AfxMessageBox(str);
        return;
    }
    EndDialog(IDOK);
}
///////////////////////////////////////////
CD_AddPointDlg::CD_AddPointDlg(CWnd* pParent /*= NULL*/)
    :CXTPResizeDialog(IDD_ADD_Point, pParent)
{

}

CD_AddPointDlg::~CD_AddPointDlg()
{

}

BEGIN_MESSAGE_MAP(CD_AddPointDlg, CXTPResizeDialog)
END_MESSAGE_MAP()


BOOL CD_AddPointDlg::OnInitDialog()
{
    __super::OnInitDialog();
    CRect rect(m_point.x, m_point.y,m_point.x + 200,m_point.y+70);
    MoveWindow(&rect);
    UpdateData(FALSE);
    return TRUE;
}

void CD_AddPointDlg::DoDataExchange(CDataExchange* pDX)
{
    __super::DoDataExchange(pDX);
    DDX_Text(pDX, IDC_EDIT_AddPoint, m_sAddPoint);
    
}

void CD_AddPointDlg::SetValue(CPoint& point)
{
    m_point = point;
}

void CD_AddPointDlg::OnOK()
{
    UpdateData(TRUE);
    m_nNum = atoi(m_sAddPoint);
    if (m_nNum < 3 || m_nNum >= 10000)
    {
        AfxMessageBox("坐标应大于3,小于10000!");
        return;
    }
    EndDialog(IDOK);
}
原文地址:https://www.cnblogs.com/Jawen/p/12079751.html