chenluhua1980
7 天以前 9b2e7cdd1d3bf2e10135c675a6b5b176a57747bf
1.完善连接示意图。
已修改4个文件
237 ■■■■■ 文件已修改
SourceCode/Bond/Servo/CPageGraph2.cpp 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGraph2.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/EqsGraphWnd.cpp 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/EqsGraphWnd.h 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGraph2.cpp
@@ -15,6 +15,8 @@
#include "CPageCassetteCtrlCmd.h"
#include "CJobDataB.h"
#define WM_MANUAL_ROUTE_REAPPLY (WM_APP + 105)
// CPageGraph2 对话框
@@ -44,6 +46,7 @@
    ON_WM_DESTROY()
    ON_WM_SIZE()
    ON_WM_TIMER()
    ON_MESSAGE(WM_MANUAL_ROUTE_REAPPLY, &CPageGraph2::OnManualRouteMsg)
END_MESSAGE_MAP()
@@ -120,6 +123,7 @@
    };
    listener.onEqItemPosChanged = [&](EQITEM* pItem, int x, int y) -> void {
        ASSERT(pItem);
        PostMessage(WM_MANUAL_ROUTE_REAPPLY, 0, 0);
    };
    listener.onDblckEqItem = [&](EQITEM* pItem) -> bool {
        ASSERT(pItem);
@@ -397,6 +401,55 @@
    }
}
void CPageGraph2::ApplyManualRoutes()
{
    if (m_pEqsGraphWnd == nullptr) {
        return;
    }
    auto pMeasurement = (SERVO::CEquipment*)theApp.m_model.m_master.getEquipment(EQ_ID_MEASUREMENT);
    auto pLoadPort1 = (SERVO::CEquipment*)theApp.m_model.m_master.getEquipment(EQ_ID_LOADPORT1);
    auto pLoadPort3 = (SERVO::CEquipment*)theApp.m_model.m_master.getEquipment(EQ_ID_LOADPORT3);
    auto pLoadPort4 = (SERVO::CEquipment*)theApp.m_model.m_master.getEquipment(EQ_ID_LOADPORT4);
    if (pMeasurement == nullptr || pLoadPort1 == nullptr || pLoadPort3 == nullptr) {
        return;
    }
    SERVO::CPin* pOut1 = pMeasurement->getPin("Out1");
    SERVO::CPin* pOut2 = pMeasurement->getPin("Out2");
    SERVO::CPin* pIn1 = pLoadPort1->getPin("In");
    SERVO::CPin* pIn3 = pLoadPort3->getPin("In");
    if (pOut1 == nullptr || pOut2 == nullptr || pIn1 == nullptr || pIn3 == nullptr) {
        return;
    }
    if (pOut1->getConnectedPin() == pIn1) {
        PIN* pGraphOut1 = m_pEqsGraphWnd->GetPin((DWORD_PTR)pMeasurement, (DWORD_PTR)pOut1);
        PIN* pGraphIn1 = m_pEqsGraphWnd->GetPin((DWORD_PTR)pLoadPort1, (DWORD_PTR)pIn1);
        if (pGraphOut1 != nullptr && pGraphIn1 != nullptr) {
            m_pEqsGraphWnd->SetManualRoute(pGraphOut1, pGraphIn1, TRUE);
        }
    }
    if (pOut2->getConnectedPin() == pIn3) {
        PIN* pGraphOut2 = m_pEqsGraphWnd->GetPin((DWORD_PTR)pMeasurement, (DWORD_PTR)pOut2);
        PIN* pGraphIn3 = m_pEqsGraphWnd->GetPin((DWORD_PTR)pLoadPort3, (DWORD_PTR)pIn3);
        if (pGraphOut2 != nullptr && pGraphIn3 != nullptr) {
            m_pEqsGraphWnd->SetManualRoute(pGraphOut2, pGraphIn3, FALSE);
            if (pLoadPort4 != nullptr && pGraphOut2->nLinePtCount >= 6) {
                EQITEM* pGraphPort4 = m_pEqsGraphWnd->GetItem((DWORD_PTR)pLoadPort4);
                if (pGraphPort4 != nullptr) {
                    int yTarget = pGraphPort4->rect.bottom + 20;
                    if (pGraphOut2->ptConnectedLine[2].y < yTarget) {
                        pGraphOut2->ptConnectedLine[2].y = yTarget;
                        pGraphOut2->ptConnectedLine[3].y = yTarget;
                    }
                }
            }
        }
    }
}
void CPageGraph2::OnTimer(UINT_PTR nIDEvent)
{
    if (1 == nIDEvent) {
@@ -415,11 +468,23 @@
                }
            }
        }
        ApplyManualRoutes();
    }
    CDialogEx::OnTimer(nIDEvent);
}
LRESULT CPageGraph2::OnManualRouteMsg(WPARAM wParam, LPARAM lParam)
{
    ApplyManualRoutes();
    CWnd* pGraphWnd = GetDlgItem(IDC_EQSGRAPHWND1);
    if (pGraphWnd != nullptr) {
        pGraphWnd->Invalidate(FALSE);
    }
    return 0;
}
void CPageGraph2::SaveEqsGraphData()
{
    char szFilepath[MAX_PATH];
SourceCode/Bond/Servo/CPageGraph2.h
@@ -19,6 +19,7 @@
    void UpdateItemIndicators(SERVO::CEquipment* pEquipment);
    void SaveEqsGraphData();
    void GetItemDataFormIni(const char* pszItemName, int& left, int& top);
    void ApplyManualRoutes();
private:
    IObserver* m_pObserver;
@@ -42,4 +43,5 @@
    afx_msg void OnDestroy();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnTimer(UINT_PTR nIDEvent);
    afx_msg LRESULT OnManualRouteMsg(WPARAM wParam, LPARAM lParam);
};
SourceCode/Bond/Servo/EqsGraphWnd.cpp
@@ -764,6 +764,64 @@
    return 0;
}
void CEqsGraphWnd::SetManualRoute(PIN* pOutPin, PIN* pInPin, BOOL bUp)
{
    if (pOutPin == NULL || pInPin == NULL) {
        return;
    }
    if (pOutPin->pItem == NULL || pInPin->pItem == NULL) {
        return;
    }
    if (pOutPin->pConnectedPin != pInPin) {
        pOutPin->pConnectedPin = pInPin;
        pInPin->pConnectedPin = pOutPin;
    }
    POINT pt1, pt2;
    if (!GetPinPoint(pOutPin, &pt1) || !GetPinPoint(pInPin, &pt2)) {
        return;
    }
    RECT rc1, rc2;
    GetItemRect(pOutPin->pItem, &rc1);
    GetItemRect(pInPin->pItem, &rc2);
    ::OffsetRect(&rc1, +m_nOffsetX, +m_nOffsetY);
    ::OffsetRect(&rc2, +m_nOffsetX, +m_nOffsetY);
    pt1.x += m_nOffsetX;
    pt1.y += m_nOffsetY;
    pt2.x += m_nOffsetX;
    pt2.y += m_nOffsetY;
    int nMargin = 12;
    int x1 = pt1.x + 10 + pOutPin->nIndex * nMargin;
    int xEnd = pt2.x - 5;
    int x2 = xEnd - (PINWIDTH + 12);
    int y1;
    if (bUp) {
        int topY = min(rc1.top, rc2.top);
        y1 = topY - 30 - pOutPin->nIndex * 6;
    }
    else {
        int bottomY = max(rc1.bottom, rc2.bottom);
        y1 = bottomY + 30 + pOutPin->nIndex * 6;
    }
    pOutPin->ptConnectedLine[0].x = pt1.x;
    pOutPin->ptConnectedLine[0].y = pt1.y;
    pOutPin->ptConnectedLine[1].x = x1;
    pOutPin->ptConnectedLine[1].y = pt1.y;
    pOutPin->ptConnectedLine[2].x = x1;
    pOutPin->ptConnectedLine[2].y = y1;
    pOutPin->ptConnectedLine[3].x = x2;
    pOutPin->ptConnectedLine[3].y = y1;
    pOutPin->ptConnectedLine[4].x = x2;
    pOutPin->ptConnectedLine[4].y = pt2.y;
    pOutPin->ptConnectedLine[5].x = xEnd;
    pOutPin->ptConnectedLine[5].y = pt2.y;
    pOutPin->nLinePtCount = 6;
}
// 删除Item, 如果pin有连接,注意先断开
int CEqsGraphWnd::DeleteItem(EQITEM* pItem)
{
@@ -990,6 +1048,8 @@
    // 如果没有缓存线条的POINT,则先计算并缓存
    ASSERT(pOwnerPin);
    bool canDraw = (pGraphics != nullptr && pPen != nullptr);
    int nPinCount = ((CPtrArray*)pOwnerPin->pItem->pOutPins)->GetSize();
    int nArrowLen = 8;
    int nStartMinX = 8;
@@ -1042,8 +1102,9 @@
                pOwnerPin->nLinePtCount = 6;
            }
            else {
                int baseY = max(lpRect1->bottom, lpRect2->bottom) + 30;
                y1 = baseY + pOwnerPin->nIndex * nMargin;
                x2 = min(lpRect1->left, lpRect2->left) - 30;
                y1 = max(lpRect1->bottom, lpRect2->bottom) + 30;
                pOwnerPin->ptConnectedLine[0].x = lpPt1->x;
                pOwnerPin->ptConnectedLine[0].y = lpPt1->y;
                pOwnerPin->ptConnectedLine[1].x = x1;
@@ -1061,10 +1122,69 @@
        }
    }
    if (!canDraw) {
        return;
    }
    if (pOwnerPin->nLinePtCount >= 2) {
        const int kJumpRadius = 6;
        for (int i = 0; i < pOwnerPin->nLinePtCount - 1; i++) {
            pGraphics->DrawLine(pPen, pOwnerPin->ptConnectedLine[i].x - m_nOffsetX, pOwnerPin->ptConnectedLine[i].y - m_nOffsetY,
                pOwnerPin->ptConnectedLine[i + 1].x - m_nOffsetX, pOwnerPin->ptConnectedLine[i + 1].y - m_nOffsetY);
            POINT a = pOwnerPin->ptConnectedLine[i];
            POINT b = pOwnerPin->ptConnectedLine[i + 1];
            bool isHorizontal = (a.y == b.y);
            bool jumped = false;
            if (isHorizontal) {
                int y = a.y;
                int xMin = min(a.x, b.x);
                int xMax = max(a.x, b.x);
                bool found = false;
                int hitX = 0;
                int x1 = 0;
                int x2 = 0;
                for (const auto& seg : m_verticalSegments) {
                    bool segVertical = (seg.a.x == seg.b.x);
                    if (!segVertical) {
                        continue;
                    }
                    int vx = seg.a.x;
                    int vyMin = min(seg.a.y, seg.b.y);
                    int vyMax = max(seg.a.y, seg.b.y);
                    if (vx > xMin + 1 && vx < xMax - 1
                        && y > vyMin + 1 && y < vyMax - 1) {
                        hitX = vx;
                        found = true;
                        break;
                    }
                }
                if (found) {
                    x1 = hitX - kJumpRadius;
                    x2 = hitX + kJumpRadius;
                    if (x1 <= xMin) x1 = xMin + 1;
                    if (x2 >= xMax) x2 = xMax - 1;
                    if (x2 <= x1) {
                        found = false;
                    }
                }
                if (found) {
                    pGraphics->DrawLine(pPen, a.x - m_nOffsetX, a.y - m_nOffsetY,
                        x1 - m_nOffsetX, y - m_nOffsetY);
                    Gdiplus::Rect arcRect(x1 - m_nOffsetX, y - kJumpRadius - m_nOffsetY, kJumpRadius * 2, kJumpRadius * 2);
                    pGraphics->DrawArc(pPen, arcRect, 180.0f, -180.0f);
                    pGraphics->DrawLine(pPen, x2 - m_nOffsetX, y - m_nOffsetY,
                        b.x - m_nOffsetX, b.y - m_nOffsetY);
                    jumped = true;
                }
            }
            if (!jumped) {
                pGraphics->DrawLine(pPen, a.x - m_nOffsetX, a.y - m_nOffsetY,
                    b.x - m_nOffsetX, b.y - m_nOffsetY);
            }
        }
        DrawArrow(pGraphics, pBrush, pPen, pOwnerPin->ptConnectedLine[pOwnerPin->nLinePtCount-1].x - m_nOffsetX,
@@ -2080,6 +2200,42 @@
            ::SelectObject(hMemDC, hFontOld);
        }
        // 预先计算所有连接线的点并收集垂直线段,用于跳线判断
        m_verticalSegments.clear();
        for (int i = 0; i < nItemCount; i++) {
            EQITEM* pItem = (EQITEM*)m_arItem.GetAt(i);
            if (pItem->nFlashFlag == 1) {
                continue;
            }
            PIN* pPin = NULL;
            CPtrArray* pPins = (CPtrArray*)pItem->pOutPins;
            RECT rcItem1, rcItem2;
            for (int j = 0; j < pPins->GetSize(); j++) {
                pPin = (PIN*)pPins->GetAt(j);
                if (pPin->pConnectedPin != NULL) {
                    POINT pt1, pt2;
                    if (GetPinPoint(pPin, &pt1) && GetPinPoint(pPin->pConnectedPin, &pt2)) {
                        GetItemRect(pItem, &rcItem1);
                        GetItemRect(pPin->pConnectedPin->pItem, &rcItem2);
                        DrawPinConnectedLine(nullptr, nullptr, nullptr, &pt1, &pt2, &rcItem1, &rcItem2, pPin);
                        if (pPin->nLinePtCount >= 2) {
                            for (int k = 0; k < pPin->nLinePtCount - 1; k++) {
                                POINT a = pPin->ptConnectedLine[k];
                                POINT b = pPin->ptConnectedLine[k + 1];
                                if (a.x == b.x) {
                                    LineSeg seg;
                                    seg.a = a;
                                    seg.b = b;
                                    m_verticalSegments.push_back(seg);
                                }
                            }
                        }
                    }
                }
            }
        }
        // 再绘制连接线
        for (int i = 0; i < nItemCount; i++) {
            EQITEM* pItem = (EQITEM*)m_arItem.GetAt(i);
SourceCode/Bond/Servo/EqsGraphWnd.h
@@ -1,5 +1,6 @@
#pragma once
#include <functional>
#include <vector>
#ifndef EQSGRAPHWND_TAG
@@ -157,6 +158,7 @@
    void ShowItemIndicator(DWORD_PTR dwItemData, int state, int nIndex = 0);
    void SetIndicatorSize(int nSize);
    void SetIndicatorMargin(int nMargin);
    void SetManualRoute(PIN* pOutPin, PIN* pInPin, BOOL bUp);
private:
    void Init();
@@ -199,6 +201,11 @@
    LRESULT OnNitify(WPARAM wParam, LPARAM lParam);
private:
    struct LineSeg {
        POINT a;
        POINT b;
    };
    EQITEM*        m_pCurItem;
    int            m_nFlashCount;
    EQITEM*        m_pFlashItem;
@@ -248,5 +255,6 @@
    BOOL m_bEnableScroll;
    int m_nMagneticLinHoz;
    int m_nMagneticLinVer;
    std::vector<LineSeg> m_verticalSegments;
};