| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "EqsGraphWnd.h" |
| | | #include "ColorTransfer.h" |
| | | #include "MapPosWnd.h" |
| | |
| | | m_hWnd = NULL; |
| | | m_crFrame = GetSysColor(COLOR_WINDOWFRAME); |
| | | m_crBkgnd = RGB(255, 255, 255); |
| | | m_listener.onConnectPin = nullptr; |
| | | m_listener.onCheckConnectPin = nullptr; |
| | | m_listener.onDisconnectPin = nullptr; |
| | | m_listener.onDeleteEqItem = nullptr; |
| | | m_listener.onEqItemPosChanged = nullptr; |
| | | m_listener.onDblckEqItem = nullptr; |
| | | m_listener.onRclickEqItem = nullptr; |
| | | m_listener = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; |
| | | m_crItemBackground[0] = RGB(218, 218, 218); |
| | | m_crItemBackground[1] = RGB(193, 208, 227); |
| | | m_crItemFrame[0] = RGB(128, 128, 128); |
| | |
| | | m_nMagneticLinHoz = 0; |
| | | m_nMagneticLinVer = 0; |
| | | m_hFontTitle = nullptr; |
| | | m_nIndicatorSize = 10; |
| | | m_nIndicatorMargin = 3; |
| | | |
| | | } |
| | | |
| | |
| | | wc.cbClsExtra = 0; |
| | | wc.cbWndExtra = 0; |
| | | |
| | | // 注册窗口类 |
| | | // 注册窗口类 |
| | | return (::RegisterClass(&wc) != 0); |
| | | } |
| | | |
| | |
| | | |
| | | m_crItemIdText[0] = CColorTransfer::ApproximateColor(m_crItemNameText[0], -0.3f); |
| | | m_crItemIdText[1] = CColorTransfer::ApproximateColor(m_crItemNameText[1], -0.3f); |
| | | } |
| | | |
| | | void CEqsGraphWnd::SetIndicatorSize(int nSize) |
| | | { |
| | | if (nSize > 0) { |
| | | m_nIndicatorSize = nSize; |
| | | } |
| | | } |
| | | |
| | | void CEqsGraphWnd::SetIndicatorMargin(int nMargin) |
| | | { |
| | | if (nMargin >= 0) { |
| | | m_nIndicatorMargin = nMargin; |
| | | } |
| | | } |
| | | |
| | | void CEqsGraphWnd::EnableScroll(BOOL bEnable) |
| | |
| | | } |
| | | |
| | | /* |
| | | * 计算磁力线位置 |
| | | * 计算磁力线位置 |
| | | */ |
| | | void CEqsGraphWnd::CalculateMagneticLine(EQITEM* pItem, LPRECT lprcItemRect, int &hoz, int &ver) |
| | | { |
| | |
| | | ver = 0; |
| | | #define MAGNETIC_DIS 10 |
| | | |
| | | // 检测是否接近或对齐 |
| | | // 检测是否接近或对齐 |
| | | for (int i = 0; i < m_arItem.GetSize(); i++) { |
| | | EQITEM *pTemp = (EQITEM*)m_arItem.GetAt(i); |
| | | if (pTemp != pItem) { |
| | |
| | | } |
| | | |
| | | /* |
| | | * 取得In Pin的区域 |
| | | * 取得In Pin的区域 |
| | | * pItem -- EQITEM |
| | | * lpRect -- 得到的Rect |
| | | * 返回是否成功 |
| | | * lpRect -- 得到的Rect |
| | | * 返回是否成功 |
| | | */ |
| | | BOOL CEqsGraphWnd::GetItemRect(EQITEM* pItem, LPRECT lpRect) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * 取得In Pin的区域 |
| | | * 取得In Pin的区域 |
| | | * pItem -- EQITEM |
| | | * nPinIndex -- in pin索引 |
| | | * lpRect -- 得到的Rect |
| | | * 返回是否成功 |
| | | * nPinIndex -- in pin索引 |
| | | * lpRect -- 得到的Rect |
| | | * 返回是否成功 |
| | | */ |
| | | BOOL CEqsGraphWnd::GetInPinRect(EQITEM* pItem, int nPinIndex, LPRECT lpRect) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * 取得Out Pin的区域 |
| | | * 取得Out Pin的区域 |
| | | * pItem -- EQITEM |
| | | * nPinIndex -- in pin索引 |
| | | * lpRect -- 得到的Rect |
| | | * 返回是否成功 |
| | | * nPinIndex -- in pin索引 |
| | | * lpRect -- 得到的Rect |
| | | * 返回是否成功 |
| | | */ |
| | | BOOL CEqsGraphWnd::GetOutPinRect(EQITEM* pItem, int nPinIndex, LPRECT lpRect) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * 取得Pin的Point |
| | | * 取得Pin的Point |
| | | * pItem -- EQITEM |
| | | * nPinIndex -- in pin索引 |
| | | * lpRect -- 得到的Rect |
| | | * 返回是否成功 |
| | | * nPinIndex -- in pin索引 |
| | | * lpRect -- 得到的Rect |
| | | * 返回是否成功 |
| | | */ |
| | | BOOL CEqsGraphWnd::GetPinPoint(PIN *pPin, LPPOINT lpPoint) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * 清空PIN连接线缓存点,以便重新计算和绘制 |
| | | * 清空PIN连接线缓存点,以便重新计算和绘制 |
| | | */ |
| | | void CEqsGraphWnd::ClearConnectedLinePoint(EQITEM*& pItem) |
| | | { |
| | |
| | | |
| | | void CEqsGraphWnd::SetOnListener(EqsGraphListener& listener) |
| | | { |
| | | m_listener.onConnectPin = listener.onConnectPin; |
| | | m_listener.onCheckConnectPin = listener.onCheckConnectPin; |
| | | m_listener.onDisconnectPin = listener.onDisconnectPin; |
| | | m_listener.onDeleteEqItem = listener.onDeleteEqItem; |
| | | m_listener.onEqItemPosChanged = listener.onEqItemPosChanged; |
| | | m_listener.onDblckEqItem = listener.onDblckEqItem; |
| | | m_listener.onRclickEqItem = listener.onRclickEqItem; |
| | | m_listener = listener; |
| | | } |
| | | |
| | | BOOL CEqsGraphWnd::SetCurSel(int nSel) |
| | |
| | | */ |
| | | EQITEM* CEqsGraphWnd::AddItem(int id, CString strText, DWORD_PTR dwData, int nType/* = ITEM_NORMAL*/) |
| | | { |
| | | // 需要计算一个新位置,不然全部重叠在一起 |
| | | // 需要计算一个新位置,不然全部重叠在一起 |
| | | int x, y; |
| | | x = (m_arItem.GetCount() % 4) * 218; |
| | | y = (m_arItem.GetCount() / 4) * 168; |
| | |
| | | void CEqsGraphWnd::SetItemType(EQITEM* pItem, int nType) |
| | | { |
| | | pItem->nShowType = nType; |
| | | if (pItem->nShowType == ITEM_SMALL) { |
| | | pItem->rect.right = pItem->rect.left + ITEM_CX_SMALL; |
| | | pItem->rect.bottom = pItem->rect.top + ITEM_CY_SMALL; |
| | | } |
| | | else if (pItem->nShowType == ITEM_LARGE) { |
| | | pItem->rect.right = pItem->rect.left + ITEM_CX_LARGE; |
| | | pItem->rect.bottom = pItem->rect.top + ITEM_CY_LARGE; |
| | | } |
| | | else { |
| | | pItem->rect.right = pItem->rect.left + ITEM_CX_NORMAL; |
| | | pItem->rect.bottom = pItem->rect.top + ITEM_CY_NORMAL; |
| | | } |
| | | |
| | | ::InvalidateRect(m_hWnd, &pItem->rect, TRUE); |
| | | } |
| | | |
| | | void CEqsGraphWnd::SetItemPos(EQITEM* pItem, int x, int y) |
| | | { |
| | | ASSERT(pItem); |
| | | pItem->rect.left = x; |
| | | pItem->rect.top = y; |
| | | if (pItem->nShowType == ITEM_SMALL) { |
| | | pItem->rect.right = pItem->rect.left + ITEM_CX_SMALL; |
| | | pItem->rect.bottom = pItem->rect.top + ITEM_CY_SMALL; |
| | |
| | | return 0; |
| | | } |
| | | |
| | | // 删除Item, 如果pin有连接,注意先断开 |
| | | // 删除Item, 如果pin有连接,注意先断开 |
| | | int CEqsGraphWnd::DeleteItem(EQITEM* pItem) |
| | | { |
| | | for (int i = 0; i < m_arItem.GetSize(); i++) { |
| | |
| | | } |
| | | |
| | | /* |
| | | * 设置子项的选中状态 |
| | | * 设置子项的选中状态 |
| | | */ |
| | | void CEqsGraphWnd::SetItemSelectState(int nIndex, BOOL bSelect) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * 检测坐标点所在的项 |
| | | * 返回项类型, 如HT_ITEM, HT_PIN, HT_LINE |
| | | * pItem - 所在的EQITEM |
| | | * pPin --所在的pin, 如果在连线上,表示所属pin, out pin; |
| | | * 检测坐标点所在的项 |
| | | * 返回项类型, 如HT_ITEM, HT_PIN, HT_LINE |
| | | * pItem - 所在的EQITEM |
| | | * pPin --所在的pin, 如果在连线上,表示所属pin, out pin; |
| | | */ |
| | | int CEqsGraphWnd::HighTest(POINT pt, OUT EQITEM*& pItem, OUT PIN *& pPin) |
| | | { |
| | | // 检测是否在某个子项 |
| | | // 检测是否在某个子项 |
| | | int nRet = HT_NOWHERE; |
| | | pItem = NULL; |
| | | pPin = NULL; |
| | |
| | | EQITEM *pTempItem = (EQITEM*)m_arItem.GetAt(i); |
| | | GetItemRect(pTempItem, &rcItem); |
| | | if (::PtInRect(&rcItem, pt)) { |
| | | // 在Item |
| | | // 在Item |
| | | pItem = pTempItem; |
| | | nRet = HT_ITEM; |
| | | break; |
| | |
| | | CPtrArray * pPins = (CPtrArray *)pTempItem->pInPins; |
| | | for (int j = 0; j < pPins->GetSize(); j++) { |
| | | if (GetInPinRect(pTempItem, j, &rcPin) && ::PtInRect(&rcPin, pt)) { |
| | | // 在in pin上 |
| | | // 在in pin上 |
| | | pPin = (PIN *)pPins->GetAt(j); |
| | | pItem = pTempItem; |
| | | nRet = HT_PIN; |
| | |
| | | pPins = (CPtrArray *)pTempItem->pOutPins; |
| | | for (int j = 0; j < pPins->GetSize(); j++) { |
| | | if (GetOutPinRect(pTempItem, j, &rcPin) && ::PtInRect(&rcPin, pt)) { |
| | | // 在out pin |
| | | // 在out pin |
| | | pPin = (PIN *)pPins->GetAt(j); |
| | | pItem = pTempItem; |
| | | nRet = HT_PIN; |
| | | break; |
| | | } |
| | | else { |
| | | // 是否在pin连接线上,即判断点是否在线上 |
| | | // 点到直线的距离公式(先通过p1,p2用两点式求出直线的表达式,再套距离公式);abs()为取绝对值函数,sqrt()为开根号函数 |
| | | // 是否在pin连接线上,即判断点是否在线上 |
| | | // 点到直线的距离公式(先通过p1,p2用两点式求出直线的表达式,再套距离公式);abs()为取绝对值函数,sqrt()为开根号函数 |
| | | PIN *pTempPin = (PIN *)pPins->GetAt(j); |
| | | if (pTempPin->pConnectedPin != NULL && pTempPin->nLinePtCount > 1) { |
| | | for (int i = 0; i < pTempPin->nLinePtCount - 1; i++) { |
| | |
| | | } |
| | | |
| | | /* |
| | | * 绘制虚线框,代表正在拖动的item |
| | | * 绘制虚线框,代表正在拖动的item |
| | | */ |
| | | void CEqsGraphWnd::DrawDropItemRectangle(LPRECT lpRect1, LPRECT lpRect2) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * 绘制磁吸线 |
| | | * 绘制磁吸线 |
| | | */ |
| | | void CEqsGraphWnd::DrawMagneticLine(LPRECT lprcClient, int nHozLine1, int nHozLine2, int nVerLine1, int nVerLine2) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * 缓制Pin连接线 |
| | | * pBrush -- 画刷 |
| | | * pPen - 画笔 |
| | | * lpPt1, lpPt2 -- Pin脚的位置 |
| | | * lpRect1, lpRect2 -- 两个Item的Rect |
| | | * 缓制Pin连接线 |
| | | * pBrush -- 画刷 |
| | | * pPen - 画笔 |
| | | * lpPt1, lpPt2 -- Pin脚的位置 |
| | | * lpRect1, lpRect2 -- 两个Item的Rect |
| | | */ |
| | | void CEqsGraphWnd::DrawPinConnectedLine(Gdiplus::Graphics *pGraphics, Gdiplus::Brush *pBrush, Gdiplus::Pen *pPen, LPPOINT lpPt1, LPPOINT lpPt2, |
| | | LPRECT lpRect1, LPRECT lpRect2, PIN *pOwnerPin) |
| | | { |
| | | // 如果没有缓存线条的POINT,则先计算并缓存 |
| | | // 如果没有缓存线条的POINT,则先计算并缓存 |
| | | ASSERT(pOwnerPin); |
| | | |
| | | int nPinCount = ((CPtrArray*)pOwnerPin->pItem->pOutPins)->GetSize(); |
| | |
| | | int nMargin = 12; |
| | | int x1, x2, y1; |
| | | |
| | | if (pOwnerPin->nLinePtCount == 0) { // 第一个点的最小折线长 |
| | | if (pOwnerPin->nLinePtCount == 0) { // 第一个点的最小折线长 |
| | | ::OffsetRect(lpRect1, +m_nOffsetX, +m_nOffsetY); |
| | | ::OffsetRect(lpRect2, +m_nOffsetX, +m_nOffsetY); |
| | | lpPt1->x += m_nOffsetX; // 消除偏移 |
| | | lpPt1->x += m_nOffsetX; // 消除偏移 |
| | | lpPt1->y += m_nOffsetY; |
| | | lpPt2->x += m_nOffsetX; |
| | | lpPt2->y += m_nOffsetY; |
| | |
| | | } |
| | | |
| | | /* |
| | | * WindowProc,窗口过程 |
| | | * WindowProc,窗口过程 |
| | | */ |
| | | LRESULT CALLBACK CEqsGraphWnd::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | } |
| | | |
| | | |
| | | // 处理窗口消息 |
| | | // 处理窗口消息 |
| | | ASSERT(hWnd); |
| | | switch (uMsg) |
| | | { |
| | |
| | | |
| | | /* |
| | | * WM_NCCREATE |
| | | * 窗口创建 |
| | | * 窗口创建 |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | |
| | | /* |
| | | * WM_DESTROY |
| | | * 窗口销毁 |
| | | * 窗口销毁 |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnDestroy(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | |
| | | /* |
| | | * WM_MOUSEMOVE |
| | | * 鼠标滚动 |
| | | * 鼠标滚动 |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnMouseMove(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | |
| | | /* |
| | | * WM_LBUTTONDOWN |
| | | * 鼠标左键按下 |
| | | * 鼠标左键按下 |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | int nLastVerLine = 0; |
| | | |
| | | |
| | | // 检测点击坐标是否在某一子项上,如是,则高亮显示 |
| | | // 检测点击坐标是否在某一子项上,如是,则高亮显示 |
| | | EQITEM* pLastItem = m_pCurItem; |
| | | PIN *pLastPin = m_pCurPin; |
| | | PIN *pLastSelLineOutPin = m_pSelLineOutPin; |
| | | BOOL bChanged = FALSE; |
| | | BOOL bSelectChanged = FALSE; |
| | | EQITEM* pHitItem = NULL; |
| | | PIN *pHitPin = NULL; |
| | | PIN *pPin2 = NULL; |
| | |
| | | } |
| | | |
| | | if (nRet == HT_ITEM) { |
| | | m_pCurItem = pHitItem; |
| | | m_pCurItem->bHighlight = TRUE; |
| | | if (m_pCurItem != pHitItem) { |
| | | m_pCurItem = pHitItem; |
| | | m_pCurItem->bHighlight = TRUE; |
| | | bSelectChanged = TRUE; |
| | | } |
| | | } |
| | | else if (nRet == HT_PIN) { |
| | | m_pCurPin = pHitPin; |
| | |
| | | bChanged = pLastItem != m_pCurItem || pLastPin != m_pCurPin || pLastSelLineOutPin != m_pSelLineOutPin; |
| | | |
| | | |
| | | // 刷新 |
| | | // 刷新 |
| | | SetFocus(m_hWnd); |
| | | if (bChanged) { |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | |
| | | |
| | | // 捕捉鼠标消息,检测是否拖动 |
| | | // 捕捉鼠标消息,检测是否拖动 |
| | | if (nRet == HT_ITEM && m_pCurItem != NULL) { |
| | | GetItemRect(m_pCurItem, &rcItem); |
| | | |
| | |
| | | |
| | | ReleaseCapture(); |
| | | ExitLoop: |
| | | m_nMagneticLinHoz = 0; |
| | | m_nMagneticLinVer = 0; |
| | | AfxUnlockTempMaps(FALSE); |
| | | } |
| | | } |
| | | |
| | | |
| | | // 捕捉鼠标消息,检测是否连接引脚 |
| | | // 捕捉鼠标消息,检测是否连接引脚 |
| | | else if (nRet == HT_PIN && m_pCurPin != NULL) { |
| | | if (::GetCapture() == NULL) { |
| | | BOOL bLast = FALSE; |
| | |
| | | ptNew = msg.pt; |
| | | ::ScreenToClient(m_hWnd, &ptNew); |
| | | |
| | | // 擦除上一次 |
| | | // 擦除上一次 |
| | | if (bLast) { |
| | | DrawPinWillConnectLine(lineColor, &ptPin, &ptLast); |
| | | } |
| | | |
| | | // 检测是否可以连接 |
| | | // 检测是否可以连接 |
| | | bCanConnect = false; |
| | | nRet = HighTest(ptNew, pHitItem, pHitPin); |
| | | if (nRet == HT_PIN) { |
| | |
| | | ptNew = msg.pt; |
| | | ::ScreenToClient(m_hWnd, &ptNew); |
| | | |
| | | // 擦除上一次 |
| | | // 擦除上一次 |
| | | if (bLast) { |
| | | DrawPinWillConnectLine(lineColor, &ptPin, &ptLast); |
| | | } |
| | | |
| | | // 检测是否可以连接 |
| | | // 检测是否可以连接 |
| | | bCanConnect = false; |
| | | nRet = HighTest(ptNew, pHitItem, pHitPin); |
| | | if (nRet == HT_PIN) { |
| | |
| | | } |
| | | |
| | | |
| | | // 检测鼠标消息,检测是否移动画布 |
| | | // 检测鼠标消息,检测是否移动画布 |
| | | else if (nRet == HT_NOWHERE) { |
| | | if (::GetCapture() == NULL) { |
| | | int nLastOffsetX = m_nOffsetX; |
| | |
| | | } |
| | | |
| | | |
| | | if (bSelectChanged) { |
| | | if (m_listener.onSelectEqItem != nullptr) { |
| | | m_listener.onSelectEqItem(m_pCurItem); |
| | | } |
| | | } |
| | | |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_LBUTTONDBLCLK |
| | | * 鼠标左键双击 |
| | | * 鼠标左键双击 |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnLButtonDblclk(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | rcLast = { 0, 0, 0, 0 }; |
| | | |
| | | // 检测点击坐标是否在某一子项上,如是,则高亮显示 |
| | | // 检测点击坐标是否在某一子项上,如是,则高亮显示 |
| | | EQITEM* pLastItem = m_pCurItem; |
| | | BOOL bChanged = FALSE; |
| | | EQITEM* pHitItem = NULL; |
| | |
| | | |
| | | /* |
| | | * WM_MOUSEWHEEL |
| | | * 鼠标滚动 |
| | | * 鼠标滚动 |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnMouseWheel(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | |
| | | /* |
| | | * WM_MOUSEHWHEEL |
| | | * 鼠标滚动 |
| | | * 鼠标滚动 |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnMouseHWheel(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | |
| | | /* |
| | | * WM_RBUTTONDOWN |
| | | * 鼠标左键按下 |
| | | * 鼠标左键按下 |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnRButtonDown(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | rcLast = { 0, 0, 0, 0 }; |
| | | |
| | | // 检测点击坐标是否在某一子项上,如是,则高亮显示 |
| | | // 检测点击坐标是否在某一子项上,如是,则高亮显示 |
| | | EQITEM* pLastItem = m_pCurItem; |
| | | PIN *pLastPin = m_pCurPin; |
| | | PIN *pLastSelLineOutPin = m_pSelLineOutPin; |
| | |
| | | bChanged = pLastItem != m_pCurItem || pLastPin != m_pCurPin || pLastSelLineOutPin != m_pSelLineOutPin; |
| | | |
| | | |
| | | // 刷新 |
| | | // 刷新 |
| | | SetFocus(m_hWnd); |
| | | if (bChanged) { |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | |
| | | |
| | | // 捕捉鼠标消息,检测是否拖动 |
| | | // 捕捉鼠标消息,检测是否拖动 |
| | | if (nRet == HT_ITEM && m_pCurItem != NULL) { |
| | | CopyRect(&rcItem, &m_pCurItem->rect); |
| | | |
| | |
| | | |
| | | /* |
| | | * WM_KEYDOWN |
| | | * 键盘消息,按下按键 |
| | | * 键盘消息,按下按键 |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnKeyDown(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | BOOL bChanged = FALSE; |
| | | if (wParam == VK_DELETE) { |
| | | // 如果当前选择为线,则断开连接 |
| | | // 如果当前选择为线,则断开连接 |
| | | if (m_pSelLineOutPin != NULL) { |
| | | if (m_listener.onDisconnectPin != nullptr) { |
| | | if (m_listener.onDisconnectPin(m_pSelLineOutPin)) { |
| | |
| | | CString strText; |
| | | HBRUSH hBrushBK; |
| | | |
| | | |
| | | // BeginPaint |
| | | PAINTSTRUCT ps; |
| | | hDC = BeginPaint(m_hWnd, &ps); |
| | |
| | | rcClient.bottom - rcClient.top); |
| | | ::SelectObject(hMemDC, hBitmap); |
| | | |
| | | |
| | | // 背景颜色 |
| | | // 背景颜色 |
| | | hBrushBK = CreateSolidBrush(m_crBkgnd); |
| | | ::FillRect(hMemDC, &rcClient, hBrushBK); |
| | | DeleteObject(hBrushBK); |
| | | |
| | | |
| | | // 标题 |
| | | // 标题字体 |
| | | if (m_hFontTitle == nullptr) { |
| | | LOGFONT lf; |
| | | HFONT hFontDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT); |
| | |
| | | m_hFontTitle = CreateFontIndirect(&lf); |
| | | } |
| | | |
| | | // 绘制标题文本 |
| | | { |
| | | char szTitle[256]; |
| | | char szTitle[256] = { 0 }; |
| | | GetWindowText(m_hWnd, szTitle, 256); |
| | | RECT rcTitle; |
| | | rcTitle.left = rcClient.left + 5; |
| | |
| | | ::DrawText(hMemDC, szTitle, (int)strlen(szTitle), &rcTitle, DT_LEFT | DT_TOP); |
| | | } |
| | | |
| | | |
| | | // 绘制子项 |
| | | // 绘制子项 |
| | | HBRUSH hbrItemBackground[2]; |
| | | HBRUSH hbrItemFrame[2]; |
| | | HBRUSH hbrPinBackground[3]; |
| | | HBRUSH hbrIndicator; |
| | | HBRUSH hbrIndicatorGray; |
| | | |
| | | hbrItemBackground[0] = CreateSolidBrush(m_crItemBackground[0]); |
| | | hbrItemBackground[1] = CreateSolidBrush(m_crItemBackground[1]); |
| | | hbrItemFrame[0] = CreateSolidBrush(m_crItemFrame[0]); |
| | | hbrItemFrame[1] = CreateSolidBrush(m_crItemFrame[1]); |
| | | hbrIndicator = CreateSolidBrush(RGB(34, 177, 76)); // 绿色 |
| | | hbrIndicatorGray = CreateSolidBrush(RGB(192, 192, 192)); // 灰色 |
| | | |
| | | for (int i = 0; i < 3; i++) { |
| | | hbrPinBackground[i] = CreateSolidBrush(m_crPinBkgnd[i]); |
| | | } |
| | | |
| | | |
| | | // gdi+ |
| | | Gdiplus::Graphics graphics(hMemDC); |
| | |
| | | graphics.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality); |
| | | } |
| | | |
| | | |
| | | SetBkMode(hMemDC, TRANSPARENT); |
| | | { |
| | | RECT rcItem; |
| | | int nPinState; |
| | | int nItemCount = (int)m_arItem.GetCount(); |
| | | |
| | | // 先画 item、文本、pin 和指示灯 |
| | | for (int i = 0; i < nItemCount; i++) { |
| | | EQITEM* pItem = (EQITEM*)m_arItem.GetAt(i); |
| | | if (pItem->nFlashFlag == 1) { |
| | | continue; |
| | | } |
| | | |
| | | GetItemRect(pItem, &rcItem); |
| | | |
| | | |
| | | // 子项背景和边框 |
| | | // 子项背景和边框 |
| | | if (m_nItemRound == 0) { |
| | | ::FillRect(hMemDC, &rcItem, pItem->bHighlight ? hbrItemBackground[1] : hbrItemBackground[0]); |
| | | ::FrameRect(hMemDC, &rcItem, pItem->bHighlight ? hbrItemFrame[1] : hbrItemFrame[0]); |
| | |
| | | ::DeleteObject(hRgn); |
| | | } |
| | | |
| | | |
| | | // name和id |
| | | // name |
| | | HFONT hFontOld = (HFONT)::SelectObject(hMemDC, m_hFontName); |
| | | ::SetTextColor(hMemDC, pItem->bHighlight ? m_crItemNameText[1] : m_crItemNameText[0]); |
| | | ::DrawText(hMemDC, pItem->text, (int)strlen(pItem->text), &rcItem, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | ::DrawText(hMemDC, pItem->text, (int)strlen(pItem->text), &rcItem, |
| | | DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | |
| | | // indicators vertical column layout |
| | | const int indicatorSize = m_nIndicatorSize; |
| | | const int indicatorMargin = m_nIndicatorMargin; |
| | | const int indicatorX = rcItem.left + 5; |
| | | |
| | | for (int k = 0; k < EQITEM_INDICATOR_COUNT; ++k) { |
| | | BYTE indicatorState = pItem->nIndicatorState[k]; |
| | | if (indicatorState == INDICATOR_STATE_HIDDEN) { |
| | | continue; |
| | | } |
| | | |
| | | RECT rcIndicator; |
| | | rcIndicator.left = indicatorX; |
| | | rcIndicator.top = rcItem.top + 5 + k * (indicatorSize + indicatorMargin); |
| | | rcIndicator.right = rcIndicator.left + indicatorSize; |
| | | rcIndicator.bottom = rcIndicator.top + indicatorSize; |
| | | |
| | | RECT rcInner = rcIndicator; |
| | | ::InflateRect(&rcInner, -1, -1); |
| | | ::FillRect(hMemDC, &rcInner, indicatorState == INDICATOR_STATE_HIGHLIGHT |
| | | ? hbrIndicator : hbrIndicatorGray); |
| | | ::FrameRect(hMemDC, &rcIndicator, hbrItemFrame[0]); |
| | | } |
| | | |
| | | // ID 文本(非小号 item) |
| | | if (pItem->nShowType != ITEM_SMALL) { |
| | | RECT rcId = rcItem; |
| | | rcId.left += 5; |
| | |
| | | strId.Format(_T("ID:%d"), pItem->id); |
| | | ::SelectObject(hMemDC, m_hFontId); |
| | | ::SetTextColor(hMemDC, pItem->bHighlight ? m_crItemIdText[1] : m_crItemIdText[0]); |
| | | ::DrawText(hMemDC, strId, (int)strId.GetLength(), &rcId, DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | ::DrawText(hMemDC, strId, (int)strId.GetLength(), &rcId, |
| | | DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | } |
| | | |
| | | |
| | | // 动画效果不绘pin |
| | | // 动画效果时不绘制 pin |
| | | if (m_pAnimationItem == pItem) { |
| | | ::SelectObject(hMemDC, hFontOld); |
| | | continue; |
| | | } |
| | | |
| | | |
| | | // 绘制pin |
| | | // 绘制 pin |
| | | RECT rcPin, rcPin2, rcPinText; |
| | | CPtrArray *pPins; |
| | | CPtrArray* pPins; |
| | | rcPinText.left = rcItem.left + 8; |
| | | rcPinText.right = rcItem.right - 8; |
| | | |
| | | |
| | | // in pins |
| | | PIN *pPin = NULL; |
| | | pPins = (CPtrArray *)pItem->pInPins; |
| | | PIN* pPin = NULL; |
| | | pPins = (CPtrArray*)pItem->pInPins; |
| | | for (int j = 0; j < pPins->GetSize(); j++) { |
| | | if (GetInPinRect(pItem, j, &rcPin)) { |
| | | pPin = (PIN *)pPins->GetAt(j); |
| | | pPin = (PIN*)pPins->GetAt(j); |
| | | ::FrameRect(hMemDC, &rcPin, pItem->bHighlight ? hbrItemFrame[1] : hbrItemFrame[0]); |
| | | |
| | | rcPin2.left = rcPin.left + 1; |
| | |
| | | rcPin2.top = rcPin.top + 1; |
| | | rcPin2.bottom = rcPin.bottom - 1; |
| | | nPinState = GetPinState(pPin); |
| | | ::FillRect(hMemDC, &rcPin2, nPinState == 0 ? (pItem->bHighlight ? hbrItemBackground[1] : hbrItemBackground[0]) : hbrPinBackground[nPinState]); |
| | | ::FillRect(hMemDC, &rcPin2, |
| | | nPinState == 0 |
| | | ? (pItem->bHighlight ? hbrItemBackground[1] : hbrItemBackground[0]) |
| | | : hbrPinBackground[nPinState]); |
| | | |
| | | if (pItem->nShowType != ITEM_SMALL) { |
| | | rcPinText.top = rcPin.top - 12; |
| | | rcPinText.bottom = rcPin.bottom + 12; |
| | | ::SetTextColor(hMemDC, pItem->bHighlight ? m_crItemIdText[1] : m_crItemIdText[0]); |
| | | ::DrawText(hMemDC, pPin->text, (int)strlen(pPin->text), &rcPinText, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | ::DrawText(hMemDC, pPin->text, (int)strlen(pPin->text), &rcPinText, |
| | | DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // out pins |
| | | pPins = (CPtrArray *)pItem->pOutPins; |
| | | pPins = (CPtrArray*)pItem->pOutPins; |
| | | for (int j = 0; j < pPins->GetSize(); j++) { |
| | | pPin = (PIN *)pPins->GetAt(j); |
| | | pPin = (PIN*)pPins->GetAt(j); |
| | | if (GetOutPinRect(pItem, j, &rcPin)) { |
| | | ::FrameRect(hMemDC, &rcPin, pItem->bHighlight ? hbrItemFrame[1] : hbrItemFrame[0]); |
| | | |
| | |
| | | rcPin2.top = rcPin.top + 1; |
| | | rcPin2.bottom = rcPin.bottom - 1; |
| | | nPinState = GetPinState(pPin); |
| | | ::FillRect(hMemDC, &rcPin2, nPinState == 0 ? (pItem->bHighlight ? hbrItemBackground[1] : hbrItemBackground[0]) : hbrPinBackground[nPinState]); |
| | | ::FillRect(hMemDC, &rcPin2, |
| | | nPinState == 0 |
| | | ? (pItem->bHighlight ? hbrItemBackground[1] : hbrItemBackground[0]) |
| | | : hbrPinBackground[nPinState]); |
| | | |
| | | if (pItem->nShowType != ITEM_SMALL) { |
| | | rcPinText.top = rcPin.top - 12; |
| | | rcPinText.bottom = rcPin.bottom + 12; |
| | | ::SetTextColor(hMemDC, pItem->bHighlight ? m_crItemIdText[1] : m_crItemIdText[0]); |
| | | ::DrawText(hMemDC, pPin->text, (int)strlen(pPin->text), &rcPinText, DT_RIGHT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | ::DrawText(hMemDC, pPin->text, (int)strlen(pPin->text), &rcPinText, |
| | | DT_RIGHT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | } |
| | | } |
| | | } |
| | | |
| | | ::DeleteObject(hbrItemFrame); |
| | | ::SelectObject(hMemDC, hFontOld); |
| | | } |
| | | |
| | | |
| | | // 绘制连接线,保存线条在最后绘制 |
| | | // 再绘制连接线 |
| | | for (int i = 0; i < nItemCount; i++) { |
| | | EQITEM *pItem = (EQITEM*)m_arItem.GetAt(i); |
| | | EQITEM* pItem = (EQITEM*)m_arItem.GetAt(i); |
| | | if (pItem->nFlashFlag == 1) { |
| | | continue; |
| | | } |
| | | |
| | | PIN *pPin = NULL; |
| | | CPtrArray *pPins; |
| | | |
| | | // out pins边线 |
| | | PIN* pPin = NULL; |
| | | CPtrArray* pPins; |
| | | RECT rcItem1, rcItem2; |
| | | pPins = (CPtrArray *)pItem->pOutPins; |
| | | |
| | | // out pins 边线 |
| | | pPins = (CPtrArray*)pItem->pOutPins; |
| | | for (int j = 0; j < pPins->GetSize(); j++) { |
| | | pPin = (PIN *)pPins->GetAt(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(&graphics, &brush1, pPin == m_pSelLineOutPin ? &pen2 : &pen1, |
| | | DrawPinConnectedLine(&graphics, &brush1, |
| | | pPin == m_pSelLineOutPin ? &pen2 : &pen1, |
| | | &pt1, &pt2, &rcItem1, &rcItem2, pPin); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 删除 brush |
| | | for (int i = 0; i < 3; i++) { |
| | | ::DeleteObject(hbrPinBackground[i]); |
| | | } |
| | |
| | | ::DeleteObject(hbrItemBackground[1]); |
| | | ::DeleteObject(hbrItemFrame[0]); |
| | | ::DeleteObject(hbrItemFrame[1]); |
| | | ::DeleteObject(hbrIndicator); |
| | | ::DeleteObject(hbrIndicatorGray); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | // EndPaint |
| | | ::BitBlt(hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, |
| | |
| | | ::DeleteObject(hBitmap); |
| | | ::DeleteDC(hMemDC); |
| | | |
| | | |
| | | return 1; |
| | | } |
| | | |
| | | |
| | | /* |
| | | * WM_SIZE |
| | |
| | | |
| | | |
| | | /* |
| | | * 设置背景颜色 |
| | | * color -- 背景色 |
| | | * 设置背景颜色 |
| | | * color -- 背景色 |
| | | */ |
| | | void CEqsGraphWnd::SetBkgndColor(COLORREF color) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * 边框颜色 |
| | | * color -- 边框色 |
| | | * 边框颜色 |
| | | * color -- 边框色 |
| | | */ |
| | | void CEqsGraphWnd::SetFrameColor(COLORREF color) |
| | | { |
| | |
| | | SetTimer(m_hWnd, TIMER_ANIMATION_RECT, uElpase, NULL); |
| | | } |
| | | |
| | | void CEqsGraphWnd::ShowItemIndicator(DWORD_PTR dwItemData, int state, int nIndex) |
| | | { |
| | | if (nIndex < 0 || nIndex >= EQITEM_INDICATOR_COUNT) { |
| | | return; |
| | | } |
| | | |
| | | EQITEM* pItem = GetItem(dwItemData); |
| | | if (pItem != nullptr) { |
| | | pItem->nIndicatorState[nIndex] = (BYTE)state; |
| | | ::InvalidateRect(m_hWnd, nullptr, TRUE); |
| | | } |
| | | } |
| | | |
| | | double CEqsGraphWnd::PointToSegDist(double x, double y, double x1, double y1, double x2, double y2) |
| | | { |
| | | double cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1); |