| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "EqsGraphWnd.h" |
| | | #include "ColorTransfer.h" |
| | | #include "MapPosWnd.h" |
| | | |
| | | |
| | | #define INPIN 1 |
| | | #define OUTPIN 2 |
| | | |
| | | #define ITEM_CX_SMALL 150 |
| | | #define ITEM_CY_SMALL 90 |
| | | #define ITEM_CX_NORMAL 250 |
| | | #define ITEM_CY_NORMAL 150 |
| | | #define ITEM_CX_LARGE 400 |
| | | #define ITEM_CY_LARGE 240 |
| | | |
| | | #define HT_NOWHERE 0x1 |
| | | #define HT_ITEM 0x2 |
| | | #define HT_PIN 0x4 |
| | | #define HT_LINE 0x8 |
| | | |
| | | #define PINWIDTH 8 |
| | | #define PINHEIGHT 12 |
| | | |
| | | #define TIMER_FLASH 1 |
| | | #define TIMER_ANIMATION_RECT 2 |
| | | |
| | | #define MAPPOSSIZE 150 |
| | | #define MAPPOSWND_PADDING_RIGHT 12 |
| | | #define MAPPOSWND_ID 1001 |
| | | |
| | | CEqsGraphWnd::CEqsGraphWnd() |
| | | { |
| | | m_bUseGdiPlus = TRUE; |
| | | 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_crItemBackground[0] = RGB(218, 218, 218); |
| | | m_crItemBackground[1] = RGB(193, 208, 227); |
| | | m_crItemFrame[0] = RGB(128, 128, 128); |
| | | m_crItemFrame[1] = RGB(147, 172, 206); |
| | | m_crItemNameText[0] = RGB(0, 0, 0); |
| | | m_crItemNameText[1] = RGB(0, 0, 0); |
| | | m_crItemIdText[0] = CColorTransfer::ApproximateColor(m_crItemNameText[0], -0.3f); |
| | | m_crItemIdText[1] = m_crItemIdText[0]; |
| | | m_nCurSel = -1; |
| | | m_bMultiSelect = FALSE; |
| | | m_nItemRound = 0; |
| | | m_pCurItem = NULL; |
| | | m_pCurPin = NULL; |
| | | m_pSelLineOutPin = NULL; |
| | | m_crPinBkgnd[0] = RGB(218, 218, 218); |
| | | m_crPinBkgnd[1] = RGB(193, 0, 0); |
| | | m_crPinBkgnd[2] = RGB(193, 0, 0); |
| | | m_nStageCx = 4000; |
| | | m_nStageCy = 3000; |
| | | m_nOffsetX = 0; |
| | | m_nOffsetY = 0; |
| | | m_pFlashItem = NULL; |
| | | m_nFlashCount = 0; |
| | | m_hWndMapPos = NULL; |
| | | m_bEnableScroll = FALSE; |
| | | m_nMagneticLinHoz = 0; |
| | | m_nMagneticLinVer = 0; |
| | | m_hFontTitle = nullptr; |
| | | |
| | | } |
| | | |
| | | CEqsGraphWnd::~CEqsGraphWnd() |
| | | { |
| | | ReleaseAllItems(); |
| | | } |
| | | |
| | | BOOL CEqsGraphWnd::RegisterWndClass() |
| | | { |
| | | WNDCLASS wc; |
| | | wc.lpszClassName = EQSGRAPHWND_CLASS; |
| | | wc.hInstance = AfxGetInstanceHandle(); |
| | | wc.lpfnWndProc = WindowProc; |
| | | wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); |
| | | wc.hIcon = 0; |
| | | wc.lpszMenuName = NULL; |
| | | wc.hbrBackground = NULL; |
| | | wc.style = CS_GLOBALCLASS | CS_DBLCLKS; |
| | | wc.cbClsExtra = 0; |
| | | wc.cbWndExtra = 0; |
| | | |
| | | // 注åçªå£ç±» |
| | | return (::RegisterClass(&wc) != 0); |
| | | } |
| | | |
| | | CEqsGraphWnd* CEqsGraphWnd::FromHandle(HWND hWnd) |
| | | { |
| | | CEqsGraphWnd* pEqsGraphWnd = (CEqsGraphWnd*)::GetProp(hWnd, EQSGRAPHWND_TAG); |
| | | return pEqsGraphWnd; |
| | | } |
| | | |
| | | CEqsGraphWnd* CEqsGraphWnd::Hook(HWND hWnd) |
| | | { |
| | | CEqsGraphWnd* pEqsGraphWnd = (CEqsGraphWnd*)GetProp(hWnd, EQSGRAPHWND_TAG); |
| | | if (pEqsGraphWnd == NULL) { |
| | | pEqsGraphWnd = new CEqsGraphWnd(); |
| | | pEqsGraphWnd->m_hWnd = hWnd; |
| | | |
| | | SetProp(hWnd, EQSGRAPHWND_TAG, (HANDLE)pEqsGraphWnd); |
| | | } |
| | | |
| | | |
| | | return pEqsGraphWnd; |
| | | } |
| | | |
| | | void CEqsGraphWnd::InitFont() |
| | | { |
| | | HDC hDC = GetDC(NULL); |
| | | HFONT hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); |
| | | |
| | | { |
| | | LOGFONT lf = { 0 }; |
| | | ::GetObject(hFont, sizeof(LOGFONT), &lf); |
| | | m_hFontName = CreateFontIndirect(&lf); |
| | | } |
| | | |
| | | { |
| | | LOGFONT lf = { 0 }; |
| | | ::GetObject(hFont, sizeof(LOGFONT), &lf); |
| | | |
| | | int nSize = int(-lf.lfHeight * 72.0 / GetDeviceCaps(hDC, LOGPIXELSY) + 0.5); |
| | | lf.lfHeight = MulDiv(0 - (nSize - 2), GetDeviceCaps(hDC, LOGPIXELSX), 72); |
| | | m_hFontId = CreateFontIndirect(&lf); |
| | | } |
| | | |
| | | ::ReleaseDC(NULL, hDC); |
| | | } |
| | | |
| | | void CEqsGraphWnd::SetItemRound(int nRound) |
| | | { |
| | | m_nItemRound = nRound; |
| | | } |
| | | |
| | | void CEqsGraphWnd::SetDefaultItemBackgroundColor(COLORREF crNormal, COLORREF crSel) |
| | | { |
| | | m_crItemBackground[0] = crNormal; |
| | | m_crItemBackground[1] = crSel; |
| | | } |
| | | |
| | | void CEqsGraphWnd::SetDefaultItemFrameColor(COLORREF crNormal, COLORREF crSel) |
| | | { |
| | | m_crItemFrame[0] = crNormal; |
| | | m_crItemFrame[1] = crSel; |
| | | } |
| | | |
| | | void CEqsGraphWnd::SetDefaultItemTextColor(COLORREF crNormal, COLORREF crSel) |
| | | { |
| | | m_crItemNameText[0] = crNormal; |
| | | m_crItemNameText[1] = crSel; |
| | | |
| | | m_crItemIdText[0] = CColorTransfer::ApproximateColor(m_crItemNameText[0], -0.3f); |
| | | m_crItemIdText[1] = CColorTransfer::ApproximateColor(m_crItemNameText[1], -0.3f); |
| | | } |
| | | |
| | | void CEqsGraphWnd::EnableScroll(BOOL bEnable) |
| | | { |
| | | m_bEnableScroll = bEnable; |
| | | } |
| | | |
| | | void CEqsGraphWnd::EnableMultiSelect() |
| | | { |
| | | m_bMultiSelect = TRUE; |
| | | } |
| | | |
| | | void CEqsGraphWnd::Init() |
| | | { |
| | | InitFont(); |
| | | CalculateScollbar(); |
| | | |
| | | long style = GetWindowLong(m_hWnd, GWL_STYLE); |
| | | SetWindowLong(m_hWnd, GWL_STYLE, style | WS_CLIPCHILDREN); |
| | | |
| | | // MapPosWnd |
| | | if (m_hWndMapPos == NULL) { |
| | | m_hWndMapPos = CreateWindowEx(0, MAPPOSWND_CLASS, |
| | | NULL, WS_CHILD | WS_VISIBLE, |
| | | 0, 0, 400, 400, |
| | | m_hWnd, (HMENU)MAPPOSWND_ID, NULL, NULL); |
| | | |
| | | long styleex = GetWindowLong(m_hWndMapPos, GWL_EXSTYLE); |
| | | SetWindowLong(m_hWndMapPos, GWL_EXSTYLE, styleex | WS_EX_CLIENTEDGE); |
| | | |
| | | CMapPosWnd *pMapPosWnd = CMapPosWnd::FromHandle(m_hWndMapPos); |
| | | pMapPosWnd->SetWndMaxSize(MAPPOSSIZE); |
| | | pMapPosWnd->SetStageSize(m_nStageCx, m_nStageCy, TRUE); |
| | | } |
| | | } |
| | | |
| | | void CEqsGraphWnd::CalculateMapPos() |
| | | { |
| | | CRect rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::OffsetRect(&rcClient, m_nOffsetX, m_nOffsetY); |
| | | CMapPosWnd *pMapPosWnd = CMapPosWnd::FromHandle(m_hWndMapPos); |
| | | pMapPosWnd->SetViewPort(&rcClient, TRUE); |
| | | } |
| | | |
| | | void CEqsGraphWnd::CalculateScollbar() |
| | | { |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | |
| | | // vert scroll |
| | | if(m_bEnableScroll) { |
| | | SCROLLINFO scrinffo; |
| | | scrinffo.cbSize = sizeof(SCROLLINFO); |
| | | scrinffo.fMask = SIF_ALL; |
| | | scrinffo.nMax = m_nStageCy; |
| | | scrinffo.nMin = 0; |
| | | scrinffo.nPos = m_nOffsetY; |
| | | scrinffo.nTrackPos = 0; |
| | | scrinffo.nPage = rcClient.bottom - rcClient.top; |
| | | SetScrollInfo(m_hWnd, SB_VERT, &scrinffo, TRUE); |
| | | } |
| | | |
| | | // horz scroll |
| | | if (m_bEnableScroll) { |
| | | SCROLLINFO scrinffo; |
| | | scrinffo.cbSize = sizeof(SCROLLINFO); |
| | | scrinffo.fMask = SIF_ALL; |
| | | scrinffo.nMax = m_nStageCx; |
| | | scrinffo.nMin = 0; |
| | | scrinffo.nPos = m_nOffsetX; |
| | | scrinffo.nTrackPos = 0; |
| | | scrinffo.nPage = rcClient.right - rcClient.left; |
| | | SetScrollInfo(m_hWnd, SB_HORZ, &scrinffo, TRUE); |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * 计ç®ç£å线ä½ç½® |
| | | */ |
| | | void CEqsGraphWnd::CalculateMagneticLine(EQITEM* pItem, LPRECT lprcItemRect, int &hoz, int &ver) |
| | | { |
| | | hoz = 0; |
| | | 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) { |
| | | if (abs(lprcItemRect->left - pTemp->rect.left) < MAGNETIC_DIS) { |
| | | ver = pTemp->rect.left; |
| | | break; |
| | | } |
| | | else if (abs(lprcItemRect->right - pTemp->rect.right) < MAGNETIC_DIS) { |
| | | ver = pTemp->rect.right - (lprcItemRect->right- lprcItemRect->left); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | for (int i = 0; i < m_arItem.GetSize(); i++) { |
| | | EQITEM* pTemp = (EQITEM*)m_arItem.GetAt(i); |
| | | if (pTemp != pItem) { |
| | | if (abs(lprcItemRect->top - pTemp->rect.top) < MAGNETIC_DIS) { |
| | | hoz = pTemp->rect.top; |
| | | break; |
| | | } |
| | | else if (abs(lprcItemRect->bottom - pTemp->rect.bottom) < MAGNETIC_DIS) { |
| | | hoz = pTemp->rect.bottom - (lprcItemRect->bottom - lprcItemRect->top); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | void CEqsGraphWnd::Release() |
| | | { |
| | | ::DeleteObject(m_hFontName); |
| | | ::DeleteObject(m_hFontId); |
| | | if (m_hFontTitle != nullptr) { |
| | | ::DeleteObject(m_hFontTitle); |
| | | } |
| | | |
| | | // delete |
| | | delete this; |
| | | } |
| | | |
| | | /* |
| | | * åå¾In Pinçåºå |
| | | * pItem -- EQITEM |
| | | * lpRect -- å¾å°çRect |
| | | * è¿åæ¯å¦æå |
| | | */ |
| | | BOOL CEqsGraphWnd::GetItemRect(EQITEM* pItem, LPRECT lpRect) |
| | | { |
| | | ASSERT(pItem); |
| | | if (pItem == m_pAnimationItem) { |
| | | lpRect->left = (int)(m_rcAnimation.left - m_nOffsetX); |
| | | lpRect->top = (int)(m_rcAnimation.top - m_nOffsetY); |
| | | lpRect->right = (int)(m_rcAnimation.right - m_nOffsetX); |
| | | lpRect->bottom = (int)(m_rcAnimation.bottom - m_nOffsetY); |
| | | } |
| | | else { |
| | | lpRect->left = (int)(pItem->rect.left - m_nOffsetX); |
| | | lpRect->top = (int)(pItem->rect.top - m_nOffsetY); |
| | | lpRect->right = (int)(pItem->rect.right - m_nOffsetX); |
| | | lpRect->bottom = (int)(pItem->rect.bottom - m_nOffsetY); |
| | | } |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CEqsGraphWnd::GetItemWarperRect(EQITEM* pItem, LPRECT lpRect) |
| | | { |
| | | CopyRect(lpRect, &pItem->rect); |
| | | lpRect->left -= PINWIDTH; |
| | | lpRect->right += PINWIDTH; |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | /* |
| | | * åå¾In Pinçåºå |
| | | * pItem -- EQITEM |
| | | * nPinIndex -- in pinç´¢å¼ |
| | | * lpRect -- å¾å°çRect |
| | | * è¿åæ¯å¦æå |
| | | */ |
| | | BOOL CEqsGraphWnd::GetInPinRect(EQITEM* pItem, int nPinIndex, LPRECT lpRect) |
| | | { |
| | | CPtrArray * pPins = (CPtrArray *)pItem->pInPins; |
| | | if (nPinIndex >= pPins->GetSize()) { |
| | | return FALSE; |
| | | } |
| | | |
| | | int nBottomMargin = pPins->GetCount() >= 4 ? 8 : 0; |
| | | int nSpace = ((pItem->rect.bottom - nBottomMargin - pItem->rect.top) - (int)pPins->GetSize() * PINHEIGHT) / (pPins->GetSize() + 1); |
| | | lpRect->right = pItem->rect.left+1 - m_nOffsetX; |
| | | lpRect->left = lpRect->right - PINWIDTH; |
| | | lpRect->bottom = pItem->rect.top + (nSpace + PINHEIGHT) * (nPinIndex+1) - m_nOffsetY; |
| | | lpRect->top = lpRect->bottom - PINHEIGHT; |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | /* |
| | | * åå¾Out Pinçåºå |
| | | * pItem -- EQITEM |
| | | * nPinIndex -- in pinç´¢å¼ |
| | | * lpRect -- å¾å°çRect |
| | | * è¿åæ¯å¦æå |
| | | */ |
| | | BOOL CEqsGraphWnd::GetOutPinRect(EQITEM* pItem, int nPinIndex, LPRECT lpRect) |
| | | { |
| | | CPtrArray * pPins = (CPtrArray *)pItem->pOutPins; |
| | | if (nPinIndex >= pPins->GetSize()) { |
| | | return FALSE; |
| | | } |
| | | |
| | | int nSpace = ((pItem->rect.bottom - pItem->rect.top) - (int)pPins->GetSize() * PINHEIGHT) / (pPins->GetSize() + 1); |
| | | lpRect->left = pItem->rect.right-1 - m_nOffsetX; |
| | | lpRect->right = lpRect->left + PINWIDTH; |
| | | lpRect->bottom = pItem->rect.top + (nSpace + PINHEIGHT) * (nPinIndex + 1) - m_nOffsetY; |
| | | lpRect->top = lpRect->bottom - PINHEIGHT; |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | /* |
| | | * åå¾PinçPoint |
| | | * pItem -- EQITEM |
| | | * nPinIndex -- in pinç´¢å¼ |
| | | * lpRect -- å¾å°çRect |
| | | * è¿åæ¯å¦æå |
| | | */ |
| | | BOOL CEqsGraphWnd::GetPinPoint(PIN *pPin, LPPOINT lpPoint) |
| | | { |
| | | ASSERT(pPin); |
| | | ASSERT(pPin->pItem); |
| | | CPtrArray * pPins; |
| | | RECT rcPin; |
| | | |
| | | // in pin? |
| | | pPins = (CPtrArray *)pPin->pItem->pInPins; |
| | | for(int i=0; i<pPins->GetCount(); i++) { |
| | | if (pPins->GetAt(i) == pPin) { |
| | | if (GetInPinRect(pPin->pItem, i, &rcPin)) { |
| | | lpPoint->x = rcPin.left + (rcPin.right - rcPin.left) / 2; |
| | | lpPoint->y = rcPin.top + (rcPin.bottom - rcPin.top) / 2; |
| | | return TRUE; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // out pin? |
| | | pPins = (CPtrArray *)pPin->pItem->pOutPins; |
| | | for (int i = 0; i<pPins->GetCount(); i++) { |
| | | if (pPins->GetAt(i) == pPin) { |
| | | if (GetOutPinRect(pPin->pItem, i, &rcPin)) { |
| | | lpPoint->x = rcPin.left + (rcPin.right - rcPin.left) / 2; |
| | | lpPoint->y = rcPin.top + (rcPin.bottom - rcPin.top) / 2; |
| | | return TRUE; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return FALSE; |
| | | } |
| | | |
| | | void CEqsGraphWnd::ReleaseItem(EQITEM* pItem) |
| | | { |
| | | ASSERT(pItem); |
| | | |
| | | CPtrArray *pArray = (CPtrArray *)pItem->pInPins; |
| | | for (int j = 0; j < pArray->GetSize(); j++) { |
| | | PIN *pPin = (PIN *)pArray->GetAt(j); |
| | | if (pPin->pConnectedPin != NULL) { |
| | | pPin->pConnectedPin->pConnectedPin = NULL; |
| | | } |
| | | delete pPin; |
| | | } |
| | | delete pArray; |
| | | |
| | | pArray = (CPtrArray *)pItem->pOutPins; |
| | | for (int j = 0; j < pArray->GetSize(); j++) { |
| | | PIN *pPin = (PIN *)pArray->GetAt(j); |
| | | if (pPin->pConnectedPin != NULL) { |
| | | pPin->pConnectedPin->pConnectedPin = NULL; |
| | | } |
| | | delete pPin; |
| | | } |
| | | delete pArray; |
| | | |
| | | delete pItem; |
| | | } |
| | | |
| | | void CEqsGraphWnd::ReleaseAllItems() |
| | | { |
| | | for (int i = 0; i < m_arItem.GetCount(); i++) { |
| | | ReleaseItem((EQITEM*)m_arItem.GetAt(i)); |
| | | } |
| | | m_arItem.RemoveAll(); |
| | | } |
| | | |
| | | int CEqsGraphWnd::GetPinState(PIN *pPin) |
| | | { |
| | | if (pPin == m_pCurPin) { |
| | | return 1; |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /* |
| | | * æ¸
空PINè¿æ¥çº¿ç¼åç¹ï¼ä»¥ä¾¿éæ°è®¡ç®åç»å¶ |
| | | */ |
| | | void CEqsGraphWnd::ClearConnectedLinePoint(EQITEM*& pItem) |
| | | { |
| | | ASSERT(pItem); |
| | | |
| | | CPtrArray *pPins; |
| | | PIN *pPin; |
| | | |
| | | pPins = (CPtrArray *)pItem->pInPins; |
| | | for (int j = 0; j < pPins->GetSize(); j++) { |
| | | pPin = (PIN *)pPins->GetAt(j); |
| | | if (pPin->pConnectedPin != NULL) { |
| | | pPin->pConnectedPin->nLinePtCount = 0; |
| | | } |
| | | } |
| | | |
| | | pPins = (CPtrArray *)pItem->pOutPins; |
| | | for (int j = 0; j < pPins->GetSize(); j++) { |
| | | pPin = (PIN *)pPins->GetAt(j); |
| | | pPin->nLinePtCount = 0; |
| | | } |
| | | } |
| | | |
| | | 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; |
| | | } |
| | | |
| | | BOOL CEqsGraphWnd::SetCurSel(int nSel) |
| | | { |
| | | if (!(nSel == -1 || nSel < m_arItem.GetCount())) { |
| | | return FALSE; |
| | | } |
| | | |
| | | |
| | | m_nCurSel = nSel; |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CEqsGraphWnd::SetCurSel(CString strItemName) |
| | | { |
| | | int nIndex = -1; |
| | | for (int i = 0; i < m_arItem.GetCount(); i++) { |
| | | EQITEM* pItem = (EQITEM*)m_arItem.GetAt(i); |
| | | if (strItemName.Compare(pItem->text) == 0) { |
| | | nIndex = i; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (nIndex == -1) { |
| | | return FALSE; |
| | | } |
| | | |
| | | m_nCurSel = nIndex; |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CEqsGraphWnd::SetCurSel(DWORD_PTR pData) |
| | | { |
| | | int nIndex = -1; |
| | | for (int i = 0; i < m_arItem.GetCount(); i++) { |
| | | EQITEM* pItem = (EQITEM*)m_arItem.GetAt(i); |
| | | if (pItem->pData == pData) { |
| | | nIndex = i; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (nIndex == -1) { |
| | | return FALSE; |
| | | } |
| | | |
| | | m_nCurSel = nIndex; |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | /* |
| | | * nType: ITEM_SMALL, ITEM_NORMAL or ITEM_LARGE |
| | | */ |
| | | 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; |
| | | |
| | | |
| | | EQITEM* pItem = new EQITEM; |
| | | memset(pItem, 0, sizeof(EQITEM)); |
| | | pItem->id = id; |
| | | pItem->nShowType = nType; |
| | | pItem->rect.left = x + 20 + m_nOffsetX; |
| | | pItem->rect.top = y + 50 + m_nOffsetY; |
| | | 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; |
| | | } |
| | | |
| | | pItem->pData = dwData; |
| | | pItem->pInPins = (DWORD_PTR)new CPtrArray(); |
| | | pItem->pOutPins = (DWORD_PTR)new CPtrArray(); |
| | | |
| | | int len = min(63, strText.GetLength()); |
| | | memcpy(pItem->text, (LPTSTR)(LPCTSTR)strText, len); |
| | | pItem->text[len] = '\0'; |
| | | m_arItem.Add(pItem); |
| | | |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | |
| | | return pItem; |
| | | } |
| | | |
| | | void CEqsGraphWnd::RemoveItem(EQITEM* pItem) |
| | | { |
| | | BOOL bChanged = FALSE; |
| | | if (m_listener.onDeleteEqItem != NULL) { |
| | | if (m_listener.onDeleteEqItem(m_pCurItem)) { |
| | | bChanged = DeleteItem(m_pCurItem) >= 0; |
| | | } |
| | | } |
| | | |
| | | |
| | | if (bChanged) { |
| | | if (pItem == m_pCurItem) { |
| | | m_pCurItem = NULL; |
| | | } |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | } |
| | | |
| | | void CEqsGraphWnd::SetItemText(EQITEM* pItem, CString strText) |
| | | { |
| | | int len = min(63, strText.GetLength()); |
| | | memcpy(pItem->text, (LPTSTR)(LPCTSTR)strText, len); |
| | | pItem->text[len] = '\0'; |
| | | |
| | | ::InvalidateRect(m_hWnd, &pItem->rect, TRUE); |
| | | } |
| | | |
| | | 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; |
| | | } |
| | | 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); |
| | | } |
| | | |
| | | PIN * CEqsGraphWnd::AddPin(EQITEM* pItem, int nType, CString strName, DWORD_PTR dwData) |
| | | { |
| | | ASSERT(pItem); |
| | | ASSERT(nType == INPIN || nType == OUTPIN); |
| | | ASSERT(pItem->pInPins); |
| | | ASSERT(pItem->pOutPins); |
| | | |
| | | |
| | | |
| | | PIN *pPin = new PIN; |
| | | memset(pPin, 0, sizeof(PIN)); |
| | | pPin->pItem = pItem; |
| | | pPin->nIndex = nType == INPIN ? ((CPtrArray *)pItem->pInPins)->GetSize() : ((CPtrArray *)pItem->pOutPins)->GetSize(); |
| | | pPin->nType = nType; |
| | | pPin->pData = dwData; |
| | | |
| | | int len = MIN(sizeof(pPin->text), strName.GetLength()); |
| | | memcpy(pPin->text, (LPTSTR)(LPCTSTR)strName, len); |
| | | pPin->text[len] = '\0'; |
| | | |
| | | CPtrArray *pArray = NULL; |
| | | if (nType == INPIN) { |
| | | pArray = (CPtrArray *)pItem->pInPins; |
| | | } |
| | | else { |
| | | pArray = (CPtrArray *)pItem->pOutPins; |
| | | } |
| | | |
| | | ASSERT(pItem->pOutPins); |
| | | pArray->Add(pPin); |
| | | |
| | | return pPin; |
| | | } |
| | | |
| | | EQITEM* CEqsGraphWnd::GetItem(DWORD_PTR dwData) |
| | | { |
| | | for (int i = 0; i < m_arItem.GetCount(); i++) { |
| | | EQITEM* pItem = (EQITEM*)m_arItem.GetAt(i); |
| | | if (pItem->pData == dwData) { |
| | | return pItem; |
| | | } |
| | | } |
| | | |
| | | return NULL; |
| | | } |
| | | |
| | | PIN * CEqsGraphWnd::GetPin(DWORD_PTR dwItemData, DWORD_PTR dwPinData) |
| | | { |
| | | EQITEM* pItem = GetItem(dwItemData); |
| | | if (pItem != NULL) { |
| | | CPtrArray *pArray = (CPtrArray *)pItem->pInPins; |
| | | for (int i = 0; i < pArray->GetCount(); i++) { |
| | | PIN *pPin = (PIN *)pArray->GetAt(i); |
| | | if (pPin->pData == dwPinData) { |
| | | return pPin; |
| | | } |
| | | } |
| | | |
| | | pArray = (CPtrArray *)pItem->pOutPins; |
| | | for (int i = 0; i < pArray->GetCount(); i++) { |
| | | PIN *pPin = (PIN *)pArray->GetAt(i); |
| | | if (pPin->pData == dwPinData) { |
| | | return pPin; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return NULL; |
| | | } |
| | | |
| | | int CEqsGraphWnd::ConnectPin(DWORD_PTR dwItem1Data, DWORD_PTR dwPin1Data, DWORD_PTR dwItem2Data, DWORD_PTR dwPin2Data) |
| | | { |
| | | PIN *pPin1, *pPin2; |
| | | |
| | | pPin1 = GetPin(dwItem1Data, dwPin1Data); |
| | | if (pPin1 == NULL) { |
| | | return -1; |
| | | } |
| | | |
| | | pPin2 = GetPin(dwItem2Data, dwPin2Data); |
| | | if (pPin2 == NULL) { |
| | | return -2; |
| | | } |
| | | |
| | | pPin1->pConnectedPin = pPin2; |
| | | pPin2->pConnectedPin = pPin1; |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | // å é¤Item, 妿pinæè¿æ¥ï¼æ³¨æå
æå¼ |
| | | int CEqsGraphWnd::DeleteItem(EQITEM* pItem) |
| | | { |
| | | for (int i = 0; i < m_arItem.GetSize(); i++) { |
| | | if (pItem == (EQITEM*)m_arItem.GetAt(i)) { |
| | | m_arItem.RemoveAt(i); |
| | | ReleaseItem(pItem); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | return -1; |
| | | } |
| | | |
| | | void CEqsGraphWnd::DeleteAllItems() |
| | | { |
| | | ReleaseAllItems(); |
| | | |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | |
| | | void CEqsGraphWnd::SetCurrentItem(EQITEM* pItem) |
| | | { |
| | | if (m_pCurItem != NULL) { |
| | | m_pCurItem->bHighlight = FALSE; |
| | | } |
| | | |
| | | m_pCurItem = pItem; |
| | | if (m_pCurItem != NULL) { |
| | | m_pCurItem->bHighlight = TRUE; |
| | | } |
| | | |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | |
| | | /* |
| | | * 设置å项çéä¸ç¶æ |
| | | */ |
| | | void CEqsGraphWnd::SetItemSelectState(int nIndex, BOOL bSelect) |
| | | { |
| | | if (nIndex >= m_arItem.GetCount()) { |
| | | return; |
| | | } |
| | | |
| | | EQITEM *pItem = (EQITEM*)m_arItem.GetAt(nIndex); |
| | | pItem->bHighlight = bSelect; |
| | | |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | |
| | | void CEqsGraphWnd::Notify(int nCode, int dwData, int dwData1/* = 0*/, int dwData2/* = 0*/) |
| | | { |
| | | HWND hParent; |
| | | hParent = GetParent(m_hWnd); |
| | | if (hParent != NULL) { |
| | | EQSGRAPHWND_NMHDR nmhdr; |
| | | nmhdr.nmhdr.hwndFrom = m_hWnd; |
| | | nmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID); |
| | | nmhdr.nmhdr.code = nCode; |
| | | nmhdr.dwData = dwData; |
| | | nmhdr.dwData1 = dwData1; |
| | | nmhdr.dwData2 = dwData2; |
| | | SendMessage(hParent, WM_NOTIFY, (WPARAM)nmhdr.nmhdr.idFrom, (LPARAM)&nmhdr); |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * æ£æµåæ ç¹æå¨ç项 |
| | | * è¿å项类å, å¦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; |
| | | RECT rcItem; |
| | | for (int i = m_arItem.GetSize() - 1; i >= 0 ; i--) { |
| | | EQITEM *pTempItem = (EQITEM*)m_arItem.GetAt(i); |
| | | GetItemRect(pTempItem, &rcItem); |
| | | if (::PtInRect(&rcItem, pt)) { |
| | | // å¨Item |
| | | pItem = pTempItem; |
| | | nRet = HT_ITEM; |
| | | break; |
| | | } |
| | | else { |
| | | RECT rcPin; |
| | | CPtrArray * pPins = (CPtrArray *)pTempItem->pInPins; |
| | | for (int j = 0; j < pPins->GetSize(); j++) { |
| | | if (GetInPinRect(pTempItem, j, &rcPin) && ::PtInRect(&rcPin, pt)) { |
| | | // å¨in pinä¸ |
| | | pPin = (PIN *)pPins->GetAt(j); |
| | | pItem = pTempItem; |
| | | nRet = HT_PIN; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (nRet == HT_NOWHERE) { |
| | | pPins = (CPtrArray *)pTempItem->pOutPins; |
| | | for (int j = 0; j < pPins->GetSize(); j++) { |
| | | if (GetOutPinRect(pTempItem, j, &rcPin) && ::PtInRect(&rcPin, pt)) { |
| | | // å¨out pin |
| | | pPin = (PIN *)pPins->GetAt(j); |
| | | pItem = pTempItem; |
| | | nRet = HT_PIN; |
| | | break; |
| | | } |
| | | else { |
| | | // æ¯å¦å¨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++) { |
| | | double distance = PointToSegDist(pt.x + m_nOffsetX, pt.y + m_nOffsetY, |
| | | pTempPin->ptConnectedLine[i].x, pTempPin->ptConnectedLine[i].y, |
| | | pTempPin->ptConnectedLine[i+1].x, pTempPin->ptConnectedLine[i+1].y); |
| | | if (distance < 5.0) { |
| | | nRet = HT_LINE; |
| | | pPin = pTempPin; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (nRet == HT_LINE) { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (nRet != HT_NOWHERE) { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | return nRet; |
| | | } |
| | | |
| | | /* |
| | | * ç»å¶è线æ¡ï¼ä»£è¡¨æ£å¨æå¨çitem |
| | | */ |
| | | void CEqsGraphWnd::DrawDropItemRectangle(LPRECT lpRect1, LPRECT lpRect2) |
| | | { |
| | | HDC hDC = GetDC(m_hWnd); |
| | | HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255)); |
| | | HPEN hPen = CreatePen(PS_DASH, 1, RGB(0, 0, 0)); |
| | | int oldRop = SetROP2(hDC, R2_NOTXORPEN); |
| | | HBRUSH hOldBrush = (HBRUSH)::SelectObject(hDC, hBrush); |
| | | HBRUSH hOldPen = (HBRUSH)::SelectObject(hDC, hPen); |
| | | |
| | | if (lpRect1 != NULL) { |
| | | ::Rectangle(hDC, lpRect1->left, lpRect1->top, lpRect1->right, lpRect1->bottom); |
| | | } |
| | | |
| | | if (lpRect2 != NULL) { |
| | | ::Rectangle(hDC, lpRect2->left, lpRect2->top, lpRect2->right, lpRect2->bottom); |
| | | } |
| | | |
| | | ::SetROP2(hDC, oldRop); |
| | | ::SelectObject(hDC, hOldBrush); |
| | | ::SelectObject(hDC, hPen); |
| | | ::DeleteObject(hBrush); |
| | | ::DeleteObject(hOldPen); |
| | | ::ReleaseDC(m_hWnd, hDC); |
| | | } |
| | | |
| | | /* |
| | | * ç»å¶ç£å¸çº¿ |
| | | */ |
| | | void CEqsGraphWnd::DrawMagneticLine(LPRECT lprcClient, int nHozLine1, int nHozLine2, int nVerLine1, int nVerLine2) |
| | | { |
| | | HDC hDC = GetDC(m_hWnd); |
| | | HPEN hPen = CreatePen(PS_DASH, 1, RGB(64, 64, 64)); |
| | | int oldRop = SetROP2(hDC, R2_NOTXORPEN); |
| | | HBRUSH hOldPen = (HBRUSH)::SelectObject(hDC, hPen); |
| | | |
| | | if (nHozLine1) { |
| | | ::MoveToEx(hDC, 1, nHozLine1, NULL); |
| | | ::LineTo(hDC, lprcClient->right-1, nHozLine1); |
| | | } |
| | | if (nHozLine2) { |
| | | ::MoveToEx(hDC, 1, nHozLine2, NULL); |
| | | ::LineTo(hDC, lprcClient->right - 1, nHozLine2); |
| | | } |
| | | |
| | | if (nVerLine1) { |
| | | ::MoveToEx(hDC, nVerLine1, 1, NULL); |
| | | ::LineTo(hDC, nVerLine1, lprcClient->bottom - 1); |
| | | } |
| | | if (nVerLine2) { |
| | | ::MoveToEx(hDC, nVerLine2, 1, NULL); |
| | | ::LineTo(hDC, nVerLine2, lprcClient->bottom - 1); |
| | | } |
| | | |
| | | ::SetROP2(hDC, oldRop); |
| | | ::SelectObject(hDC, hPen); |
| | | ::DeleteObject(hOldPen); |
| | | ::ReleaseDC(m_hWnd, hDC); |
| | | } |
| | | |
| | | /* |
| | | * ç¼å¶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ï¼åå
计ç®å¹¶ç¼å |
| | | ASSERT(pOwnerPin); |
| | | |
| | | int nPinCount = ((CPtrArray*)pOwnerPin->pItem->pOutPins)->GetSize(); |
| | | int nArrowLen = 8; |
| | | int nStartMinX = 8; |
| | | int nMargin = 12; |
| | | int x1, x2, y1; |
| | | |
| | | if (pOwnerPin->nLinePtCount == 0) { // 第ä¸ä¸ªç¹çæå°æçº¿é¿ |
| | | ::OffsetRect(lpRect1, +m_nOffsetX, +m_nOffsetY); |
| | | ::OffsetRect(lpRect2, +m_nOffsetX, +m_nOffsetY); |
| | | lpPt1->x += m_nOffsetX; // æ¶é¤åç§» |
| | | lpPt1->y += m_nOffsetY; |
| | | lpPt2->x += m_nOffsetX; |
| | | lpPt2->y += m_nOffsetY; |
| | | int nMinX = 10 + nMargin * nPinCount + nArrowLen; |
| | | int xEnd = lpPt2->x - 5; |
| | | x1 = lpPt1->x + 10 + pOwnerPin->nIndex * nMargin; |
| | | if (lpPt2->x - lpPt1->x > nMinX) { |
| | | pOwnerPin->ptConnectedLine[0].x = lpPt1->x; |
| | | pOwnerPin->ptConnectedLine[0].y = lpPt1->y; |
| | | pOwnerPin->ptConnectedLine[1].x = x1; |
| | | pOwnerPin->ptConnectedLine[1].y = lpPt1->y; |
| | | pOwnerPin->ptConnectedLine[2].x = x1; |
| | | pOwnerPin->ptConnectedLine[2].y = lpPt2->y; |
| | | pOwnerPin->ptConnectedLine[3].x = xEnd; |
| | | pOwnerPin->ptConnectedLine[3].y = lpPt2->y; |
| | | pOwnerPin->nLinePtCount = 4; |
| | | } |
| | | else if (lpRect1 != NULL && lpRect2 != NULL) { |
| | | if (lpRect2->top - lpRect1->bottom > 20 || lpRect1->top - lpRect2->bottom > 20) { |
| | | if (lpRect2->top - lpRect1->bottom > 20) { |
| | | y1 = lpRect1->bottom + 10 + pOwnerPin->nIndex * nMargin; |
| | | x2 = min(lpPt2->x - nArrowLen, x1) - (nPinCount - pOwnerPin->nIndex) * nMargin; |
| | | } |
| | | else { |
| | | y1 = lpRect1->top - 10 - pOwnerPin->nIndex * nMargin; |
| | | x2 = min(lpPt2->x - nArrowLen, x1) - (nPinCount - pOwnerPin->nIndex) * nMargin; |
| | | } |
| | | pOwnerPin->ptConnectedLine[0].x = lpPt1->x; |
| | | pOwnerPin->ptConnectedLine[0].y = lpPt1->y; |
| | | pOwnerPin->ptConnectedLine[1].x = x1; |
| | | pOwnerPin->ptConnectedLine[1].y = lpPt1->y; |
| | | pOwnerPin->ptConnectedLine[2].x = x1; |
| | | pOwnerPin->ptConnectedLine[2].y = y1; |
| | | pOwnerPin->ptConnectedLine[3].x = x2; |
| | | pOwnerPin->ptConnectedLine[3].y = y1; |
| | | pOwnerPin->ptConnectedLine[4].x = x2; |
| | | pOwnerPin->ptConnectedLine[4].y = lpPt2->y; |
| | | pOwnerPin->ptConnectedLine[5].x = xEnd; |
| | | pOwnerPin->ptConnectedLine[5].y = lpPt2->y; |
| | | pOwnerPin->nLinePtCount = 6; |
| | | } |
| | | else { |
| | | 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; |
| | | pOwnerPin->ptConnectedLine[1].y = lpPt1->y; |
| | | pOwnerPin->ptConnectedLine[2].x = x1; |
| | | pOwnerPin->ptConnectedLine[2].y = y1; |
| | | pOwnerPin->ptConnectedLine[3].x = x2; |
| | | pOwnerPin->ptConnectedLine[3].y = y1; |
| | | pOwnerPin->ptConnectedLine[4].x = x2; |
| | | pOwnerPin->ptConnectedLine[4].y = lpPt2->y; |
| | | pOwnerPin->ptConnectedLine[5].x = xEnd; |
| | | pOwnerPin->ptConnectedLine[5].y = lpPt2->y; |
| | | pOwnerPin->nLinePtCount = 6; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (pOwnerPin->nLinePtCount >= 2) { |
| | | 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); |
| | | } |
| | | |
| | | DrawArrow(pGraphics, pBrush, pPen, pOwnerPin->ptConnectedLine[pOwnerPin->nLinePtCount-1].x - m_nOffsetX, |
| | | pOwnerPin->ptConnectedLine[pOwnerPin->nLinePtCount-1].y - m_nOffsetY, nArrowLen); |
| | | } |
| | | } |
| | | |
| | | void CEqsGraphWnd::DrawArrow(Gdiplus::Graphics *pGraphics, Gdiplus::Brush* pBrush, Gdiplus::Pen *pPen, |
| | | int x, int y, int nArrowLen) |
| | | { |
| | | Gdiplus::Point pt[4]; |
| | | pt[0].X = x; |
| | | pt[0].Y = y; |
| | | pt[1].X = x - nArrowLen; |
| | | pt[1].Y = y - 3; |
| | | pt[2].X = pt[1].X; |
| | | pt[2].Y = y + 3; |
| | | pt[3].X = x; |
| | | pt[3].Y = y; |
| | | pGraphics->FillPolygon(pBrush, pt, 4); |
| | | pGraphics->DrawPolygon(pPen, pt, 4); |
| | | } |
| | | |
| | | void CEqsGraphWnd::DrawPinWillConnectLine(COLORREF color, LPPOINT lpPt1, LPPOINT lpPt2) |
| | | { |
| | | HDC hDC = GetDC(m_hWnd); |
| | | |
| | | HPEN hPen = CreatePen(PS_SOLID, 2, color); |
| | | int oldRop = SetROP2(hDC, R2_NOTXORPEN); |
| | | HBRUSH hOldPen = (HBRUSH)::SelectObject(hDC, hPen); |
| | | |
| | | if (lpPt1 != NULL && lpPt2 != NULL) { |
| | | ::MoveToEx(hDC, lpPt1->x, lpPt1->y, NULL); |
| | | ::LineTo(hDC, lpPt2->x, lpPt2->y); |
| | | } |
| | | |
| | | ::SetROP2(hDC, oldRop); |
| | | ::SelectObject(hDC, hPen); |
| | | ::DeleteObject(hOldPen); |
| | | ::ReleaseDC(m_hWnd, hDC); |
| | | } |
| | | |
| | | /* |
| | | * WindowProcï¼çªå£è¿ç¨ |
| | | */ |
| | | LRESULT CALLBACK CEqsGraphWnd::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
| | | { |
| | | CEqsGraphWnd* pEqsGraphWnd = (CEqsGraphWnd*)GetProp(hWnd, EQSGRAPHWND_TAG); |
| | | if (pEqsGraphWnd == NULL && uMsg != WM_NCCREATE) |
| | | { |
| | | return ::DefWindowProc(hWnd, uMsg, wParam, lParam); |
| | | } |
| | | |
| | | |
| | | // å¤ççªå£æ¶æ¯ |
| | | ASSERT(hWnd); |
| | | switch (uMsg) |
| | | { |
| | | case WM_NCCREATE: |
| | | return CEqsGraphWnd::OnNcCreate(hWnd, wParam, lParam); |
| | | |
| | | case WM_DESTROY: |
| | | return pEqsGraphWnd->OnDestroy(wParam, lParam); |
| | | |
| | | case WM_NCPAINT: |
| | | return pEqsGraphWnd->OnNcPaint(wParam, lParam); |
| | | |
| | | case WM_PAINT: |
| | | return pEqsGraphWnd->OnPaint(wParam, lParam); |
| | | |
| | | case WM_TIMER: |
| | | return pEqsGraphWnd->OnTimer(wParam, lParam); |
| | | |
| | | case WM_MOUSEMOVE: |
| | | return pEqsGraphWnd->OnMouseMove(wParam, lParam); |
| | | |
| | | case WM_LBUTTONDOWN: |
| | | return pEqsGraphWnd->OnLButtonDown(wParam, lParam); |
| | | |
| | | case WM_RBUTTONDOWN: |
| | | return pEqsGraphWnd->OnRButtonDown(wParam, lParam); |
| | | |
| | | case WM_LBUTTONDBLCLK: |
| | | return pEqsGraphWnd->OnLButtonDblclk(wParam, lParam); |
| | | |
| | | case WM_MOUSEWHEEL: |
| | | return pEqsGraphWnd->OnMouseWheel(wParam, lParam); |
| | | |
| | | case WM_MOUSEHWHEEL: |
| | | return pEqsGraphWnd->OnMouseHWheel(wParam, lParam); |
| | | |
| | | case WM_KEYDOWN: |
| | | return pEqsGraphWnd->OnKeyDown(wParam, lParam); |
| | | |
| | | case WM_SIZE: |
| | | return pEqsGraphWnd->OnSize(wParam, lParam); |
| | | |
| | | case WM_VSCROLL: |
| | | return pEqsGraphWnd->OnVScroll(wParam, lParam); |
| | | |
| | | case WM_HSCROLL: |
| | | return pEqsGraphWnd->OnHScroll(wParam, lParam); |
| | | |
| | | case WM_NOTIFY: |
| | | return pEqsGraphWnd->OnNitify(wParam, lParam); |
| | | |
| | | case WM_GETDLGCODE: |
| | | return DLGC_WANTALLKEYS; |
| | | |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | return ::DefWindowProc(hWnd, uMsg, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_NCCREATE |
| | | * çªå£å建 |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) |
| | | { |
| | | CEqsGraphWnd* pEqsGraphWnd = (CEqsGraphWnd*)GetProp(hWnd,EQSGRAPHWND_TAG); |
| | | ASSERT(pEqsGraphWnd == NULL); |
| | | |
| | | Hook(hWnd)->Init(); |
| | | return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_DESTROY |
| | | * çªå£éæ¯ |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnDestroy(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | Release(); |
| | | return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam); |
| | | } |
| | | |
| | | |
| | | /* |
| | | * WM_TIMER |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnTimer(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | if (wParam == TIMER_FLASH) { |
| | | if (m_pFlashItem != NULL && m_nFlashCount > 0) { |
| | | m_nFlashCount--; |
| | | m_pFlashItem->nFlashFlag = (m_nFlashCount % 2); |
| | | |
| | | RECT rcItem; |
| | | GetItemWarperRect(m_pFlashItem, &rcItem); |
| | | InvalidateRect(m_hWnd, &rcItem, TRUE); |
| | | } |
| | | else { |
| | | m_pFlashItem = NULL; |
| | | m_nFlashCount = 0; |
| | | } |
| | | } |
| | | else if (TIMER_ANIMATION_RECT == wParam) { |
| | | if (m_pAnimationItem != NULL) { |
| | | if (m_nAninationStep > 0) { |
| | | m_nAninationStep--; |
| | | |
| | | m_rcAnimation.left += m_rcAninationStep.left; |
| | | m_rcAnimation.right += m_rcAninationStep.right; |
| | | m_rcAnimation.top += m_rcAninationStep.top; |
| | | m_rcAnimation.bottom += m_rcAninationStep.bottom; |
| | | |
| | | RECT rcItem; |
| | | GetItemWarperRect(m_pAnimationItem, &rcItem); |
| | | InvalidateRect(m_hWnd, &rcItem, TRUE); |
| | | } |
| | | else { |
| | | KillTimer(m_hWnd, TIMER_ANIMATION_RECT); |
| | | RECT rcItem; |
| | | GetItemWarperRect(m_pAnimationItem, &rcItem); |
| | | InvalidateRect(m_hWnd, &rcItem, TRUE); |
| | | m_pAnimationItem = NULL; |
| | | } |
| | | } |
| | | else { |
| | | KillTimer(m_hWnd, TIMER_ANIMATION_RECT); |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | } |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_MOUSEMOVE |
| | | * é¼ æ æ»å¨ |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnMouseMove(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | return ::DefWindowProc(m_hWnd, WM_MOUSEMOVE, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_LBUTTONDOWN |
| | | * é¼ æ å·¦é®æä¸ |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | POINT pt, ptNew; |
| | | pt.x = LOWORD(lParam); |
| | | pt.y = HIWORD(lParam); |
| | | |
| | | RECT rcClient, rcItem, rcNewItem, rcLast; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | rcLast = {0, 0, 0, 0}; |
| | | int nMaxOffsetX = m_nStageCx - (rcClient.right - rcClient.left); |
| | | int nMaxOffsetY = m_nStageCy - (rcClient.bottom - rcClient.top); |
| | | int nLastHozLine = 0; |
| | | int nLastVerLine = 0; |
| | | |
| | | |
| | | // æ£æµç¹å»åæ æ¯å¦å¨æä¸å项ä¸ï¼å¦æ¯ï¼åé«äº®æ¾ç¤º |
| | | EQITEM* pLastItem = m_pCurItem; |
| | | PIN *pLastPin = m_pCurPin; |
| | | PIN *pLastSelLineOutPin = m_pSelLineOutPin; |
| | | BOOL bChanged = FALSE; |
| | | EQITEM* pHitItem = NULL; |
| | | PIN *pHitPin = NULL; |
| | | PIN *pPin2 = NULL; |
| | | int nRet = HighTest(pt, pHitItem, pHitPin); |
| | | if (pHitItem != m_pCurItem || nRet != HT_ITEM) { |
| | | if (m_pCurItem != NULL) { |
| | | m_pCurItem->bHighlight = FALSE; |
| | | } |
| | | m_pCurItem = NULL; |
| | | } |
| | | |
| | | if (pHitPin != m_pCurPin || nRet != HT_PIN) { |
| | | if (m_pCurPin != NULL) { |
| | | m_pCurPin->bHighlight = FALSE; |
| | | } |
| | | m_pCurPin = NULL; |
| | | } |
| | | |
| | | if (pHitPin != m_pSelLineOutPin || nRet != HT_LINE) { |
| | | m_pSelLineOutPin = NULL; |
| | | } |
| | | |
| | | if (nRet == HT_ITEM) { |
| | | m_pCurItem = pHitItem; |
| | | m_pCurItem->bHighlight = TRUE; |
| | | } |
| | | else if (nRet == HT_PIN) { |
| | | m_pCurPin = pHitPin; |
| | | m_pCurPin->bHighlight = TRUE; |
| | | } |
| | | else if (nRet == HT_LINE) { |
| | | m_pSelLineOutPin = 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); |
| | | |
| | | if (::GetCapture() == NULL) { |
| | | SetCapture(m_hWnd); |
| | | ASSERT(m_hWnd == GetCapture()); |
| | | AfxLockTempMaps(); |
| | | for (;;) |
| | | { |
| | | MSG msg; |
| | | VERIFY(::GetMessage(&msg, NULL, 0, 0)); |
| | | |
| | | if (GetCapture() != m_hWnd) break; |
| | | |
| | | switch (msg.message) |
| | | { |
| | | case WM_MOUSEMOVE: |
| | | ptNew = msg.pt; |
| | | ::ScreenToClient(m_hWnd, &ptNew); |
| | | rcNewItem.left = rcItem.left + (ptNew.x - pt.x); |
| | | rcNewItem.right = rcItem.right + (ptNew.x - pt.x); |
| | | rcNewItem.top = rcItem.top + (ptNew.y - pt.y); |
| | | rcNewItem.bottom = rcItem.bottom + (ptNew.y - pt.y); |
| | | CalculateMagneticLine(m_pCurItem, &rcNewItem, m_nMagneticLinHoz, m_nMagneticLinVer); |
| | | DrawDropItemRectangle(&rcNewItem, &rcLast); |
| | | DrawMagneticLine(&rcClient, m_nMagneticLinHoz, nLastHozLine, m_nMagneticLinVer, nLastVerLine); |
| | | nLastHozLine = m_nMagneticLinHoz; |
| | | nLastVerLine = m_nMagneticLinVer; |
| | | CopyRect(&rcLast, &rcNewItem); |
| | | break; |
| | | |
| | | case WM_LBUTTONUP: |
| | | ptNew = msg.pt; |
| | | ::ScreenToClient(m_hWnd, &ptNew); |
| | | m_pCurItem->rect.left = m_nMagneticLinVer > 0 ? m_nMagneticLinVer : (rcItem.left + (ptNew.x - pt.x) + m_nOffsetX); |
| | | m_pCurItem->rect.right = m_pCurItem->rect.left + (rcItem.right - rcItem.left); |
| | | m_pCurItem->rect.top = m_nMagneticLinHoz > 0 ? m_nMagneticLinHoz : (rcItem.top + (ptNew.y - pt.y) + m_nOffsetY); |
| | | m_pCurItem->rect.bottom = m_pCurItem->rect.top + (rcItem.bottom - rcItem.top); |
| | | if (m_pCurItem->rect.left != rcItem.left || m_pCurItem->rect.top != rcItem.top) { |
| | | if (m_listener.onEqItemPosChanged != nullptr) { |
| | | m_listener.onEqItemPosChanged(m_pCurItem, m_pCurItem->rect.left, m_pCurItem->rect.top); |
| | | } |
| | | } |
| | | DrawDropItemRectangle(NULL, &rcLast); |
| | | ReleaseCapture(); |
| | | |
| | | ClearConnectedLinePoint(m_pCurItem); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | goto ExitLoop; |
| | | |
| | | case WM_KEYDOWN: |
| | | if (msg.wParam != VK_ESCAPE) |
| | | break; |
| | | |
| | | default: |
| | | DispatchMessage(&msg); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | ReleaseCapture(); |
| | | ExitLoop: |
| | | m_nMagneticLinHoz = 0; |
| | | m_nMagneticLinVer = 0; |
| | | AfxUnlockTempMaps(FALSE); |
| | | } |
| | | } |
| | | |
| | | |
| | | // ææé¼ æ æ¶æ¯ï¼æ£æµæ¯å¦è¿æ¥å¼è |
| | | else if (nRet == HT_PIN && m_pCurPin != NULL) { |
| | | if (::GetCapture() == NULL) { |
| | | BOOL bLast = FALSE; |
| | | bool bCanConnect; |
| | | POINT ptPin, ptLast; |
| | | COLORREF lineColor; |
| | | GetPinPoint(m_pCurPin, &ptPin); |
| | | ptLast.x = ptPin.x; |
| | | ptLast.y = ptPin.y; |
| | | |
| | | SetCapture(m_hWnd); |
| | | ASSERT(m_hWnd == GetCapture()); |
| | | AfxLockTempMaps(); |
| | | for (;;) |
| | | { |
| | | MSG msg; |
| | | VERIFY(::GetMessage(&msg, NULL, 0, 0)); |
| | | |
| | | if (GetCapture() != m_hWnd) break; |
| | | |
| | | switch (msg.message) |
| | | { |
| | | case WM_MOUSEMOVE: |
| | | ptNew = msg.pt; |
| | | ::ScreenToClient(m_hWnd, &ptNew); |
| | | |
| | | // æ¦é¤ä¸ä¸æ¬¡ |
| | | if (bLast) { |
| | | DrawPinWillConnectLine(lineColor, &ptPin, &ptLast); |
| | | } |
| | | |
| | | // æ£æµæ¯å¦å¯ä»¥è¿æ¥ |
| | | bCanConnect = false; |
| | | nRet = HighTest(ptNew, pHitItem, pHitPin); |
| | | if (nRet == HT_PIN) { |
| | | if (m_listener.onCheckConnectPin != nullptr) { |
| | | bCanConnect = m_listener.onCheckConnectPin(m_pCurPin, pHitPin); |
| | | } |
| | | } |
| | | if (bCanConnect) { |
| | | lineColor = RGB(0, 255, 0); |
| | | DrawPinWillConnectLine(lineColor, &ptPin, &ptNew); |
| | | } |
| | | else { |
| | | lineColor = RGB(0, 0, 0); |
| | | DrawPinWillConnectLine(lineColor, &ptPin, &ptNew); |
| | | } |
| | | |
| | | ptLast.x = ptNew.x; |
| | | ptLast.y = ptNew.y; |
| | | bLast = TRUE; |
| | | break; |
| | | |
| | | case WM_LBUTTONUP: |
| | | ptNew = msg.pt; |
| | | ::ScreenToClient(m_hWnd, &ptNew); |
| | | |
| | | // æ¦é¤ä¸ä¸æ¬¡ |
| | | if (bLast) { |
| | | DrawPinWillConnectLine(lineColor, &ptPin, &ptLast); |
| | | } |
| | | |
| | | // æ£æµæ¯å¦å¯ä»¥è¿æ¥ |
| | | bCanConnect = false; |
| | | nRet = HighTest(ptNew, pHitItem, pHitPin); |
| | | if (nRet == HT_PIN) { |
| | | if (m_listener.onConnectPin != nullptr) { |
| | | bCanConnect = m_listener.onConnectPin(m_pCurPin, pHitPin); |
| | | } |
| | | } |
| | | if (bCanConnect) { |
| | | m_pCurPin->pConnectedPin = pHitPin; |
| | | pHitPin->pConnectedPin = m_pCurPin; |
| | | } |
| | | bLast = FALSE; |
| | | |
| | | ReleaseCapture(); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | goto ExitLoop2; |
| | | |
| | | case WM_KEYDOWN: |
| | | if (msg.wParam != VK_ESCAPE) |
| | | break; |
| | | |
| | | default: |
| | | DispatchMessage(&msg); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | ReleaseCapture(); |
| | | ExitLoop2: |
| | | AfxUnlockTempMaps(FALSE); |
| | | } |
| | | } |
| | | |
| | | |
| | | // æ£æµé¼ æ æ¶æ¯ï¼æ£æµæ¯å¦ç§»å¨ç»å¸ |
| | | else if (nRet == HT_NOWHERE) { |
| | | if (::GetCapture() == NULL) { |
| | | int nLastOffsetX = m_nOffsetX; |
| | | int nLastOffsetY = m_nOffsetY; |
| | | |
| | | POINT ptStart; |
| | | ptStart.x = pt.x; |
| | | ptStart.y = pt.y; |
| | | |
| | | SetCursor(LoadCursor(NULL, IDC_SIZEALL)); |
| | | SetCapture(m_hWnd); |
| | | ASSERT(m_hWnd == GetCapture()); |
| | | AfxLockTempMaps(); |
| | | for (;;) { |
| | | MSG msg; |
| | | VERIFY(::GetMessage(&msg, NULL, 0, 0)); |
| | | |
| | | if (GetCapture() != m_hWnd) break; |
| | | |
| | | switch (msg.message) |
| | | { |
| | | case WM_MOUSEMOVE: |
| | | ptNew = msg.pt; |
| | | ::ScreenToClient(m_hWnd, &ptNew); |
| | | m_nOffsetX = min(nMaxOffsetX, max(0, nLastOffsetX - (ptNew.x - ptStart.x))); |
| | | m_nOffsetY = min(nMaxOffsetY, max(0, nLastOffsetY - (ptNew.y - ptStart.y))); |
| | | CalculateScollbar(); |
| | | CalculateMapPos(); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | break; |
| | | |
| | | case WM_LBUTTONUP: |
| | | ptNew = msg.pt; |
| | | ::ScreenToClient(m_hWnd, &ptNew); |
| | | |
| | | ReleaseCapture(); |
| | | CalculateScollbar(); |
| | | CalculateMapPos(); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | goto ExitLoop3; |
| | | |
| | | case WM_KEYDOWN: |
| | | if (msg.wParam != VK_ESCAPE) |
| | | break; |
| | | |
| | | default: |
| | | DispatchMessage(&msg); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | ReleaseCapture(); |
| | | ExitLoop3: |
| | | AfxUnlockTempMaps(FALSE); |
| | | } |
| | | } |
| | | |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_LBUTTONDBLCLK |
| | | * é¼ æ å·¦é®åå» |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnLButtonDblclk(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | POINT pt; |
| | | pt.x = LOWORD(lParam); |
| | | pt.y = HIWORD(lParam); |
| | | |
| | | RECT rcClient, rcLast; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | rcLast = { 0, 0, 0, 0 }; |
| | | |
| | | // æ£æµç¹å»åæ æ¯å¦å¨æä¸å项ä¸ï¼å¦æ¯ï¼åé«äº®æ¾ç¤º |
| | | EQITEM* pLastItem = m_pCurItem; |
| | | BOOL bChanged = FALSE; |
| | | EQITEM* pHitItem = NULL; |
| | | PIN *pHitPin = NULL; |
| | | int nRet = HighTest(pt, pHitItem, pHitPin); |
| | | if ( nRet == HT_ITEM) { |
| | | m_pCurItem = pHitItem; |
| | | m_pCurItem->bHighlight = FALSE; |
| | | if (m_listener.onDblckEqItem != nullptr) { |
| | | m_listener.onDblckEqItem(pHitItem); |
| | | } |
| | | } |
| | | |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_LBUTTONDBLCLK, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_MOUSEWHEEL |
| | | * é¼ æ æ»å¨ |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnMouseWheel(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | short zDelta; |
| | | UINT nFlags; |
| | | CPoint pt; |
| | | |
| | | nFlags = LOWORD(wParam); |
| | | zDelta = (short)HIWORD(wParam); |
| | | pt.x = (short)LOWORD(lParam); |
| | | pt.y = (short)HIWORD(lParam); |
| | | |
| | | |
| | | CRect rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | m_nOffsetY -= zDelta; |
| | | m_nOffsetY = max(0, min(m_nOffsetY, m_nStageCy - rcClient.Height())); |
| | | CalculateScollbar(); |
| | | CalculateMapPos(); |
| | | |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | return ::DefWindowProc(m_hWnd, WM_MOUSEWHEEL, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_MOUSEHWHEEL |
| | | * é¼ æ æ»å¨ |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnMouseHWheel(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | short zDelta; |
| | | UINT nFlags; |
| | | CPoint pt; |
| | | |
| | | nFlags = LOWORD(wParam); |
| | | zDelta = (short)HIWORD(wParam); |
| | | pt.x = (short)LOWORD(lParam); |
| | | pt.y = (short)HIWORD(lParam); |
| | | |
| | | |
| | | CRect rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | m_nOffsetX += zDelta; |
| | | m_nOffsetX = max(0, min(m_nOffsetX, m_nStageCx - rcClient.Width())); |
| | | CalculateScollbar(); |
| | | CalculateMapPos(); |
| | | |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | return ::DefWindowProc(m_hWnd, WM_MOUSEHWHEEL, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_RBUTTONDOWN |
| | | * é¼ æ å·¦é®æä¸ |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnRButtonDown(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | POINT pt, ptNew; |
| | | pt.x = LOWORD(lParam); |
| | | pt.y = HIWORD(lParam); |
| | | |
| | | RECT rcClient, rcItem, rcLast; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | rcLast = { 0, 0, 0, 0 }; |
| | | |
| | | // æ£æµç¹å»åæ æ¯å¦å¨æä¸å项ä¸ï¼å¦æ¯ï¼åé«äº®æ¾ç¤º |
| | | EQITEM* pLastItem = m_pCurItem; |
| | | PIN *pLastPin = m_pCurPin; |
| | | PIN *pLastSelLineOutPin = m_pSelLineOutPin; |
| | | BOOL bChanged = FALSE; |
| | | EQITEM* pHitItem = NULL; |
| | | PIN *pHitPin = NULL; |
| | | PIN *pPin2 = NULL; |
| | | int nRet = HighTest(pt, pHitItem, pHitPin); |
| | | if (pHitItem != m_pCurItem || nRet != HT_ITEM) { |
| | | if (m_pCurItem != NULL) { |
| | | m_pCurItem->bHighlight = FALSE; |
| | | } |
| | | m_pCurItem = NULL; |
| | | } |
| | | |
| | | if (pHitPin != m_pCurPin || nRet != HT_PIN) { |
| | | if (m_pCurPin != NULL) { |
| | | m_pCurPin->bHighlight = FALSE; |
| | | } |
| | | m_pCurPin = NULL; |
| | | } |
| | | |
| | | if (pHitPin != m_pSelLineOutPin || nRet != HT_LINE) { |
| | | m_pSelLineOutPin = NULL; |
| | | } |
| | | |
| | | if (nRet == HT_ITEM) { |
| | | m_pCurItem = pHitItem; |
| | | m_pCurItem->bHighlight = TRUE; |
| | | } |
| | | else if (nRet == HT_PIN) { |
| | | m_pCurPin = pHitPin; |
| | | m_pCurPin->bHighlight = TRUE; |
| | | } |
| | | else if (nRet == HT_LINE) { |
| | | m_pSelLineOutPin = 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) { |
| | | CopyRect(&rcItem, &m_pCurItem->rect); |
| | | |
| | | if (::GetCapture() == NULL) { |
| | | SetCapture(m_hWnd); |
| | | ASSERT(m_hWnd == GetCapture()); |
| | | AfxLockTempMaps(); |
| | | for (;;) |
| | | { |
| | | MSG msg; |
| | | VERIFY(::GetMessage(&msg, NULL, 0, 0)); |
| | | |
| | | if (GetCapture() != m_hWnd) break; |
| | | |
| | | switch (msg.message) |
| | | { |
| | | case WM_MOUSEMOVE: |
| | | break; |
| | | |
| | | case WM_RBUTTONUP: |
| | | ptNew = msg.pt; |
| | | ::ScreenToClient(m_hWnd, &ptNew); |
| | | nRet = HighTest(ptNew, pHitItem, pHitPin); |
| | | ReleaseCapture(); |
| | | if (m_listener.onRclickEqItem != NULL) { |
| | | m_listener.onRclickEqItem(pHitItem); |
| | | } |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | goto ExitLoop; |
| | | |
| | | case WM_KEYDOWN: |
| | | if (msg.wParam != VK_ESCAPE) |
| | | break; |
| | | |
| | | default: |
| | | DispatchMessage(&msg); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | ReleaseCapture(); |
| | | ExitLoop: |
| | | AfxUnlockTempMaps(FALSE); |
| | | } |
| | | } |
| | | |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * 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)) { |
| | | m_pSelLineOutPin->pConnectedPin->pConnectedPin = NULL; |
| | | m_pSelLineOutPin->pConnectedPin = NULL; |
| | | m_pSelLineOutPin = NULL; |
| | | bChanged = TRUE; |
| | | } |
| | | } |
| | | } |
| | | else if (m_pCurItem != NULL) { |
| | | if (m_listener.onDeleteEqItem != NULL) { |
| | | if (m_listener.onDeleteEqItem(m_pCurItem)) { |
| | | bChanged = DeleteItem(m_pCurItem) >= 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | if (bChanged) { |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_KEYDOWN, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_NCPAINT |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnNcPaint(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | LRESULT lRet = ::DefWindowProc(m_hWnd, WM_NCPAINT, wParam, lParam); |
| | | |
| | | |
| | | long styleEx = GetWindowLong(m_hWnd, GWL_EXSTYLE); |
| | | if ((styleEx & WS_EX_CLIENTEDGE) == WS_EX_CLIENTEDGE) { |
| | | |
| | | RECT rect, rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.left); |
| | | ::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.right); |
| | | GetWindowRect(m_hWnd, &rect); |
| | | rcClient.right = rect.right - 1; |
| | | rcClient.bottom = rect.bottom - 1; |
| | | ::OffsetRect(&rcClient, -rect.left, -rect.top); |
| | | |
| | | rect.right -= rect.left; |
| | | rect.bottom -= rect.top; |
| | | rect.left = 0; |
| | | rect.top = 0; |
| | | |
| | | HRGN hRgnWnd = CreateRectRgnIndirect(&rect); |
| | | HRGN hRgnClient = CreateRectRgnIndirect(&rcClient); |
| | | |
| | | HBRUSH hBrushBK, hBrushFrame; |
| | | HDC hDC = ::GetWindowDC(m_hWnd); |
| | | ::SelectClipRgn(hDC, hRgnWnd); |
| | | ::ExtSelectClipRgn(hDC, hRgnClient, RGN_DIFF); |
| | | |
| | | hBrushBK = CreateSolidBrush(m_crBkgnd); |
| | | ::FillRect(hDC, &rect, hBrushBK); |
| | | DeleteObject(hBrushBK); |
| | | |
| | | hBrushFrame = CreateSolidBrush(m_crFrame); |
| | | ::FrameRect(hDC, &rect, hBrushFrame); |
| | | |
| | | ::DeleteObject(hRgnWnd); |
| | | ::DeleteObject(hRgnClient); |
| | | DeleteObject(hBrushFrame); |
| | | ::ReleaseDC(m_hWnd, hDC); |
| | | } |
| | | |
| | | return lRet; |
| | | } |
| | | |
| | | /* |
| | | * WM_PAINT |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnPaint(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | HDC hDC, hMemDC; |
| | | HBITMAP hBitmap; |
| | | RECT rcClient; |
| | | CString strText; |
| | | HBRUSH hBrushBK; |
| | | |
| | | |
| | | // BeginPaint |
| | | PAINTSTRUCT ps; |
| | | hDC = BeginPaint(m_hWnd, &ps); |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | |
| | | hMemDC = ::CreateCompatibleDC(hDC); |
| | | hBitmap = ::CreateCompatibleBitmap(hDC, rcClient.right - rcClient.left, |
| | | 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); |
| | | ::GetObject(hFontDefault, sizeof(LOGFONT), &lf); |
| | | lf.lfHeight -= 6; |
| | | lf.lfWeight = FW_SEMIBOLD; |
| | | m_hFontTitle = CreateFontIndirect(&lf); |
| | | } |
| | | |
| | | { |
| | | char szTitle[256]; |
| | | GetWindowText(m_hWnd, szTitle, 256); |
| | | RECT rcTitle; |
| | | rcTitle.left = rcClient.left + 5; |
| | | rcTitle.top = rcClient.top + 12; |
| | | rcTitle.bottom = rcClient.bottom - 5; |
| | | rcTitle.right = rcClient.right - 5; |
| | | ::SelectObject(hMemDC, m_hFontTitle); |
| | | ::DrawText(hMemDC, szTitle, (int)strlen(szTitle), &rcTitle, DT_LEFT | DT_TOP); |
| | | } |
| | | |
| | | |
| | | // ç»å¶å项 |
| | | HBRUSH hbrItemBackground[2]; |
| | | HBRUSH hbrItemFrame[2]; |
| | | HBRUSH hbrPinBackground[3]; |
| | | hbrItemBackground[0] = CreateSolidBrush(m_crItemBackground[0]); |
| | | hbrItemBackground[1] = CreateSolidBrush(m_crItemBackground[1]); |
| | | hbrItemFrame[0] = CreateSolidBrush(m_crItemFrame[0]); |
| | | hbrItemFrame[1] = CreateSolidBrush(m_crItemFrame[1]); |
| | | for (int i = 0; i < 3; i++) { |
| | | hbrPinBackground[i] = CreateSolidBrush(m_crPinBkgnd[i]); |
| | | } |
| | | |
| | | |
| | | // gdi+ |
| | | Gdiplus::Graphics graphics(hMemDC); |
| | | Gdiplus::Pen pen1(Gdiplus::Color(255, 64, 64, 64), 2); |
| | | Gdiplus::Pen pen2(Gdiplus::Color(255, 255, 127, 39), 2); |
| | | Gdiplus::SolidBrush brush1(Gdiplus::Color(255, 64, 64, 64)); |
| | | if (m_bUseGdiPlus) { |
| | | graphics.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality); |
| | | } |
| | | |
| | | |
| | | SetBkMode(hMemDC, TRANSPARENT); |
| | | { |
| | | RECT rcItem; |
| | | int nPinState; |
| | | int nItemCount = (int)m_arItem.GetCount(); |
| | | 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]); |
| | | } |
| | | else { |
| | | HRGN hRgn = CreateRoundRectRgn(rcItem.left, rcItem.top, rcItem.right, rcItem.bottom, m_nItemRound, m_nItemRound); |
| | | ::FillRgn(hMemDC, hRgn, pItem->bHighlight ? hbrItemBackground[1] : hbrItemBackground[0]); |
| | | ::FrameRgn(hMemDC, hRgn, pItem->bHighlight ? hbrItemFrame[1] : hbrItemFrame[0], 1, 1); |
| | | ::DeleteObject(hRgn); |
| | | } |
| | | |
| | | |
| | | // nameåid |
| | | 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); |
| | | |
| | | if (pItem->nShowType != ITEM_SMALL) { |
| | | RECT rcId = rcItem; |
| | | rcId.left += 5; |
| | | rcId.bottom -= 5; |
| | | CString strId; |
| | | 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); |
| | | } |
| | | |
| | | |
| | | // å¨ç»ææä¸ç»pin |
| | | if (m_pAnimationItem == pItem) { |
| | | continue; |
| | | } |
| | | |
| | | |
| | | // ç»å¶pin |
| | | RECT rcPin, rcPin2, rcPinText; |
| | | CPtrArray *pPins; |
| | | rcPinText.left = rcItem.left + 8; |
| | | rcPinText.right = rcItem.right - 8; |
| | | |
| | | |
| | | // in pins |
| | | 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); |
| | | ::FrameRect(hMemDC, &rcPin, pItem->bHighlight ? hbrItemFrame[1] : hbrItemFrame[0]); |
| | | |
| | | rcPin2.left = rcPin.left + 1; |
| | | rcPin2.right = rcPin.right; |
| | | 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]); |
| | | |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // out pins |
| | | pPins = (CPtrArray *)pItem->pOutPins; |
| | | for (int j = 0; j < pPins->GetSize(); j++) { |
| | | pPin = (PIN *)pPins->GetAt(j); |
| | | if (GetOutPinRect(pItem, j, &rcPin)) { |
| | | ::FrameRect(hMemDC, &rcPin, pItem->bHighlight ? hbrItemFrame[1] : hbrItemFrame[0]); |
| | | |
| | | rcPin2.left = rcPin.left; |
| | | rcPin2.right = rcPin.right - 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]); |
| | | |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | |
| | | ::DeleteObject(hbrItemFrame); |
| | | ::SelectObject(hMemDC, hFontOld); |
| | | } |
| | | |
| | | |
| | | // ç»å¶è¿æ¥çº¿ï¼ä¿å线æ¡å¨æåç»å¶ |
| | | for (int i = 0; i < nItemCount; i++) { |
| | | EQITEM *pItem = (EQITEM*)m_arItem.GetAt(i); |
| | | if (pItem->nFlashFlag == 1) { |
| | | continue; |
| | | } |
| | | |
| | | PIN *pPin = NULL; |
| | | CPtrArray *pPins; |
| | | |
| | | // out pins边线 |
| | | RECT rcItem1, rcItem2; |
| | | pPins = (CPtrArray *)pItem->pOutPins; |
| | | 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(&graphics, &brush1, pPin == m_pSelLineOutPin ? &pen2 : &pen1, |
| | | &pt1, &pt2, &rcItem1, &rcItem2, pPin); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | for (int i = 0; i < 3; i++) { |
| | | ::DeleteObject(hbrPinBackground[i]); |
| | | } |
| | | ::DeleteObject(hbrItemBackground[0]); |
| | | ::DeleteObject(hbrItemBackground[1]); |
| | | ::DeleteObject(hbrItemFrame[0]); |
| | | ::DeleteObject(hbrItemFrame[1]); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | // EndPaint |
| | | ::BitBlt(hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, |
| | | hMemDC, 0, 0, SRCCOPY); |
| | | EndPaint(m_hWnd, &ps); |
| | | ::DeleteObject(hBitmap); |
| | | ::DeleteDC(hMemDC); |
| | | |
| | | |
| | | return 1; |
| | | } |
| | | |
| | | /* |
| | | * WM_SIZE |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnSize(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | LRESULT lRet = ::DefWindowProc(m_hWnd, WM_SIZE, wParam, lParam); |
| | | |
| | | CalculateScollbar(); |
| | | |
| | | if (m_hWndMapPos != NULL) { |
| | | CalculateMapPos(); |
| | | |
| | | CRect rcItem, rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | GetWindowRect(m_hWndMapPos,& rcItem); |
| | | |
| | | ::MoveWindow(m_hWndMapPos, rcClient.right- rcItem.Width() - MAPPOSWND_PADDING_RIGHT, |
| | | MAPPOSWND_PADDING_RIGHT, rcItem.Width(), rcItem.Height(), TRUE); |
| | | } |
| | | |
| | | return lRet; |
| | | } |
| | | |
| | | /* |
| | | * WM_VSCROLL |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnVScroll(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | int nSBCode = LOWORD(wParam); |
| | | int nPos = HIWORD(wParam); |
| | | |
| | | SCROLLINFO info = { 0 }; |
| | | info.cbSize = sizeof(SCROLLINFO); |
| | | info.fMask = SIF_ALL; |
| | | GetScrollInfo(m_hWnd, SB_VERT, &info); |
| | | |
| | | int nMaxPos = info.nMax - info.nPage; |
| | | int inc = 10; |
| | | |
| | | switch (nSBCode) |
| | | { |
| | | case SB_BOTTOM: |
| | | if (info.nPos < nMaxPos) { |
| | | // ScrollWindow(m_hWnd, 0, -1 * inc*(iMaxPos - info.nPos), NULL, NULL); |
| | | info.nPos = nMaxPos; |
| | | } |
| | | break; |
| | | |
| | | case SB_TOP: |
| | | if (info.nPos > info.nMin) { |
| | | // ScrollWindow(m_hWnd, 0, inc*(info.nPos - info.nMin), NULL, NULL); |
| | | info.nPos = info.nMin; |
| | | } |
| | | break; |
| | | |
| | | case SB_LINEUP: |
| | | if (info.nPos > info.nMin) { |
| | | //ScrollWindow(m_hWnd, 0, inc, NULL, NULL); |
| | | info.nPos -= 1; |
| | | } |
| | | break; |
| | | |
| | | case SB_LINEDOWN: |
| | | if (info.nPos < nMaxPos) { |
| | | // ScrollWindow(m_hWnd, 0, -1 * inc, NULL, NULL); |
| | | info.nPos += 1; |
| | | } |
| | | break; |
| | | |
| | | case SB_PAGEUP: |
| | | if (info.nPos - 100 >= info.nMin) { |
| | | //ScrollWindow(m_hWnd, 0, 100 * inc, NULL, NULL); |
| | | info.nPos -= 100; |
| | | } |
| | | else { |
| | | if (info.nPos <= 0) { |
| | | // ScrollWindow(m_hWnd, 0, 0, NULL, NULL); |
| | | } |
| | | else { |
| | | // ScrollWindow(m_hWnd, 0, info.nPos, NULL, NULL); |
| | | } |
| | | info.nPos = info.nMin; |
| | | } |
| | | break; |
| | | |
| | | case SB_PAGEDOWN: |
| | | if (info.nPos + 100 <= nMaxPos) { |
| | | // ScrollWindow(m_hWnd, 0, -100*inc, NULL, NULL); |
| | | info.nPos += 100; |
| | | } |
| | | else { |
| | | // ScrollWindow(m_hWnd, 0, (info.nPos - iMaxPos) * inc, NULL, NULL); |
| | | info.nPos = nMaxPos; |
| | | } |
| | | break; |
| | | |
| | | case SB_ENDSCROLL: |
| | | break; |
| | | |
| | | case SB_THUMBPOSITION: |
| | | break; |
| | | |
| | | case SB_THUMBTRACK: |
| | | // ScrollWindow(m_hWnd, 0, inc * (info.nPos - nPos), NULL, NULL); |
| | | info.nPos = nPos; |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | m_nOffsetY = info.nPos; |
| | | SetScrollInfo(m_hWnd, SB_VERT, &info, TRUE); |
| | | CalculateMapPos(); |
| | | |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | |
| | | LRESULT lRet = ::DefWindowProc(m_hWnd, WM_VSCROLL, wParam, lParam); |
| | | return lRet; |
| | | } |
| | | |
| | | /* |
| | | * WM_HSCROLL |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnHScroll(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | int nSBCode = LOWORD(wParam); |
| | | int nPos = HIWORD(wParam); |
| | | |
| | | SCROLLINFO info = { 0 }; |
| | | info.cbSize = sizeof(SCROLLINFO); |
| | | info.fMask = SIF_ALL; |
| | | GetScrollInfo(m_hWnd, SB_HORZ, &info); |
| | | |
| | | int nMaxPos = info.nMax - info.nPage; |
| | | int inc = 10; |
| | | |
| | | switch (nSBCode) |
| | | { |
| | | case SB_RIGHT: |
| | | if (info.nPos < nMaxPos) { |
| | | // ScrollWindow(m_hWnd, 0, -1 * inc*(iMaxPos - info.nPos), NULL, NULL); |
| | | info.nPos = nMaxPos; |
| | | } |
| | | break; |
| | | |
| | | case SB_LEFT: |
| | | if (info.nPos > info.nMin) { |
| | | // ScrollWindow(m_hWnd, 0, inc*(info.nPos - info.nMin), NULL, NULL); |
| | | info.nPos = info.nMin; |
| | | } |
| | | break; |
| | | |
| | | case SB_LINELEFT: |
| | | if (info.nPos > info.nMin) { |
| | | //ScrollWindow(m_hWnd, 0, inc, NULL, NULL); |
| | | info.nPos -= 1; |
| | | } |
| | | break; |
| | | |
| | | case SB_LINERIGHT: |
| | | if (info.nPos < nMaxPos) { |
| | | // ScrollWindow(m_hWnd, 0, -1 * inc, NULL, NULL); |
| | | info.nPos += 1; |
| | | } |
| | | break; |
| | | |
| | | case SB_PAGELEFT: |
| | | if (info.nPos - 100 >= info.nMin) { |
| | | //ScrollWindow(m_hWnd, 0, 100 * inc, NULL, NULL); |
| | | info.nPos -= 100; |
| | | } |
| | | else { |
| | | if (info.nPos <= 0) { |
| | | // ScrollWindow(m_hWnd, 0, 0, NULL, NULL); |
| | | } |
| | | else { |
| | | // ScrollWindow(m_hWnd, 0, info.nPos, NULL, NULL); |
| | | } |
| | | info.nPos = info.nMin; |
| | | } |
| | | break; |
| | | |
| | | case SB_PAGERIGHT: |
| | | if (info.nPos + 100 <= nMaxPos) { |
| | | // ScrollWindow(m_hWnd, 0, -100*inc, NULL, NULL); |
| | | info.nPos += 100; |
| | | } |
| | | else { |
| | | // ScrollWindow(m_hWnd, 0, (info.nPos - iMaxPos) * inc, NULL, NULL); |
| | | info.nPos = nMaxPos; |
| | | } |
| | | break; |
| | | |
| | | case SB_ENDSCROLL: |
| | | break; |
| | | |
| | | case SB_THUMBPOSITION: |
| | | break; |
| | | |
| | | case SB_THUMBTRACK: |
| | | // ScrollWindow(m_hWnd, 0, inc * (info.nPos - nPos), NULL, NULL); |
| | | info.nPos = nPos; |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | m_nOffsetX = info.nPos; |
| | | SetScrollInfo(m_hWnd, SB_HORZ, &info, TRUE); |
| | | CalculateMapPos(); |
| | | |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | |
| | | LRESULT lRet = ::DefWindowProc(m_hWnd, WM_HSCROLL, wParam, lParam); |
| | | return lRet; |
| | | } |
| | | |
| | | /* |
| | | * WM_NOTIFY |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnNitify(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | LRESULT lRet = ::DefWindowProc(m_hWnd, WM_NOTIFY, wParam, lParam); |
| | | |
| | | NMHDR *pNmhdr = (NMHDR *)lParam; |
| | | if (pNmhdr->idFrom == MAPPOSWND_ID) { |
| | | MAPPOSWND_NMHDR *pNmhdr2 = (MAPPOSWND_NMHDR *)lParam; |
| | | m_nOffsetX = pNmhdr2->dwData; |
| | | m_nOffsetY = pNmhdr2->dwData1; |
| | | CalculateScollbar(); |
| | | CalculateMapPos(); |
| | | |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | |
| | | return lRet; |
| | | } |
| | | |
| | | |
| | | /* |
| | | * è®¾ç½®èæ¯é¢è² |
| | | * color -- èæ¯è² |
| | | */ |
| | | void CEqsGraphWnd::SetBkgndColor(COLORREF color) |
| | | { |
| | | m_crBkgnd = color; |
| | | } |
| | | |
| | | /* |
| | | * è¾¹æ¡é¢è² |
| | | * color -- è¾¹æ¡è² |
| | | */ |
| | | void CEqsGraphWnd::SetFrameColor(COLORREF color) |
| | | { |
| | | m_crFrame = color; |
| | | } |
| | | |
| | | void CEqsGraphWnd::FlashItem(EQITEM *pItem) |
| | | { |
| | | if (m_pFlashItem != NULL) { |
| | | KillTimer(m_hWnd, TIMER_FLASH); |
| | | } |
| | | |
| | | m_nFlashCount = 5; |
| | | m_pFlashItem = pItem; |
| | | SetTimer(m_hWnd, TIMER_FLASH, 100, NULL); |
| | | } |
| | | |
| | | void CEqsGraphWnd::AnimationItem(EQITEM* pItem) |
| | | { |
| | | if (m_pAnimationItem != NULL) { |
| | | KillTimer(m_hWnd, TIMER_ANIMATION_RECT); |
| | | } |
| | | |
| | | |
| | | m_pAnimationItem = NULL; |
| | | KillTimer(m_hWnd, TIMER_ANIMATION_RECT); |
| | | |
| | | UINT uElpase = 50; |
| | | m_nAninationDuration = 200; |
| | | m_nAninationStep = m_nAninationDuration / uElpase; |
| | | m_pAnimationItem = pItem; |
| | | m_rcAnimation.left = pItem->rect.left + (pItem->rect.right - pItem->rect.left) / 2.0f; |
| | | m_rcAnimation.right = m_rcAnimation.left; |
| | | m_rcAnimation.top = pItem->rect.top + (pItem->rect.bottom - pItem->rect.top) / 2.0f; |
| | | m_rcAnimation.bottom = m_rcAnimation.top; |
| | | m_rcAninationStep.left = (pItem->rect.left - m_rcAnimation.left) / (float)m_nAninationStep; |
| | | m_rcAninationStep.right = (pItem->rect.right - m_rcAnimation.right) / (float)m_nAninationStep; |
| | | m_rcAninationStep.top = (pItem->rect.top - m_rcAnimation.top) / (float)m_nAninationStep; |
| | | m_rcAninationStep.bottom = (pItem->rect.bottom - m_rcAnimation.bottom) / (float)m_nAninationStep; |
| | | |
| | | SetTimer(m_hWnd, TIMER_ANIMATION_RECT, uElpase, NULL); |
| | | } |
| | | |
| | | 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); |
| | | if (cross <= 0) return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1)); |
| | | |
| | | double d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1); |
| | | if (cross >= d2) return sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2)); |
| | | |
| | | double r = cross / d2; |
| | | double px = x1 + (x2 - x1) * r; |
| | | double py = y1 + (y2 - y1) * r; |
| | | return sqrt((x - px) * (x - px) + (py - y) * (py - y)); |
| | | } |
| | | |