| | |
| | | CEquipment::serialize(ar); |
| | | } |
| | | |
| | | void CBonder::getAttributeVector(CAttributeVector& attrubutes) |
| | | { |
| | | __super::getAttributeVector(attrubutes); |
| | | |
| | | for (auto item : m_inputPins) { |
| | | attrubutes.addAttribute(new CAttribute(item->getName().c_str(), |
| | | std::to_string((int)item->getType()).c_str(), "")); |
| | | } |
| | | |
| | | for (auto item : m_outputPins) { |
| | | attrubutes.addAttribute(new CAttribute(item->getName().c_str(), |
| | | std::to_string((int)item->getType()).c_str(), "")); |
| | | } |
| | | |
| | | for (auto item : m_panelList) { |
| | | attrubutes.addAttribute(new CAttribute("Panel", |
| | | item->getID().c_str(), "")); |
| | | } |
| | | } |
| | | |
| | | int CBonder::recvIntent(CPin* pPin, CIntent* pIntent) |
| | | { |
| | | ASSERT(pPin); |
| | |
| | | CEquipment* pFromEq = pFromPin->getEquipment(); |
| | | ASSERT(pFromEq); |
| | | |
| | | |
| | | LOGI("<CBonder><%s-%s>æ¶å°æ¥èª<%s.%s>çIntent<%d,%s,0x%x>", |
| | | this->getName().c_str(), |
| | | pPin->getName().c_str(), |
| | |
| | | pFromPin->getName().c_str(), |
| | | pIntent->getCode(), |
| | | pIntent->getMsg(), |
| | | pIntent->getContext() |
| | | ); |
| | | pIntent->getContext()); |
| | | |
| | | return 0; |
| | | |
| | | |
| | | // 以ä¸è§£éå¤çæ°æ® |
| | | int code = pIntent->getCode(); |
| | | |
| | | |
| | | // æµè¯ |
| | | if (code == FLOW_TEST) { |
| | | AfxMessageBox(pIntent->getMsg()); |
| | | return FLOW_ACCEPT; |
| | | } |
| | | |
| | | |
| | | // ä¿¡å· |
| | | if (code == FLOW_SIGNAL) { |
| | | return FLOW_ACCEPT; |
| | | } |
| | | |
| | | |
| | | // æ°æ® |
| | | if (code == FLOW_SIGNAL) { |
| | | return FLOW_ACCEPT; |
| | | } |
| | | |
| | | |
| | | // ç©æ |
| | | if (code == FLOW_MOVE_MATERIAL) { |
| | | // 妿æè¿éæ¯ç©ºçï¼å¯ä»¥æ¥å |
| | | Lock(); |
| | | if (m_panelList.size() < 15) { |
| | | CPanel* pPanel = (CPanel*)pIntent->getContext(); |
| | | ASSERT(pPanel); |
| | | pPanel->addRef(); |
| | | m_panelList.push_back(pPanel); |
| | | Unlock(); |
| | | return FLOW_ACCEPT; |
| | | } |
| | | else { |
| | | Unlock(); |
| | | return FLOW_REJECT; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | return FLOW_ACCEPT; |
| | | } |
| | | } |
| | |
| | | virtual void initPins(); |
| | | virtual void onTimer(UINT nTimerid); |
| | | virtual void serialize(CArchive& ar); |
| | | virtual void getAttributeVector(CAttributeVector& attrubutes); |
| | | virtual int recvIntent(CPin* pPin, CIntent* pIntent); |
| | | }; |
| | | } |
| | |
| | | { |
| | | return 0; |
| | | } |
| | | |
| | | void CEquipment::addPanelToList(CPanel* pPanel) |
| | | { |
| | | ASSERT(pPanel); |
| | | |
| | | Lock(); |
| | | pPanel->addRef(); |
| | | m_panelList.push_back(pPanel); |
| | | Unlock(); |
| | | } |
| | | } |
| | |
| | | #include "CEqVCREnableStep.h" |
| | | #include <vector> |
| | | #include <map> |
| | | #include <list> |
| | | #include "CPanel.h" |
| | | |
| | | |
| | | namespace SERVO { |
| | |
| | | protected: |
| | | inline void Lock() { EnterCriticalSection(&m_criticalSection); } |
| | | inline void Unlock() { LeaveCriticalSection(&m_criticalSection); } |
| | | void addPanelToList(CPanel* pPanel); |
| | | |
| | | protected: |
| | | EquipmentListener m_listener; |
| | |
| | | MemoryBlock m_blockWriteBit; |
| | | std::vector<CPin*> m_inputPins; |
| | | std::vector<CPin*> m_outputPins; |
| | | std::list<CPanel*> m_panelList; |
| | | |
| | | |
| | | // 以ä¸ä¸ºä»CC-Link读åå°çBitæ å¿ä½ |
| | | private: |
| | |
| | | attrubutes.addAttribute(new CAttribute(item->getName().c_str(), |
| | | std::to_string((int)item->getType()).c_str(), "")); |
| | | } |
| | | |
| | | for (auto item : m_panelList) { |
| | | attrubutes.addAttribute(new CAttribute("Panel", |
| | | item->getID().c_str(), "")); |
| | | } |
| | | } |
| | | |
| | | void CLoadPort::outputPanel() |
| | | { |
| | | CPin* pOutPin = getPin("Out"); |
| | | |
| | | CIntent intent; |
| | | intent.setCode(1); |
| | | intent.setMsg("Hello"); |
| | | pOutPin->sendIntent(&intent); |
| | | |
| | | // 妿åè¡¨ä¸æ²¡æPanel,模æçæ10å¼ |
| | | if (m_panelList.empty()) { |
| | | static int ii = 0; |
| | | char szBuffer[64]; |
| | | LOGI("<CLoadPort>模æçæ10å¼ PANEL"); |
| | | for (int i = 0; i < 10; i++) { |
| | | sprintf_s(szBuffer, "P20250320A1A%d", ++ii); |
| | | CPanel* pPanel = new CPanel(); |
| | | pPanel->setID(szBuffer); |
| | | addPanelToList(pPanel); |
| | | } |
| | | } |
| | | |
| | | |
| | | // 模æååºç¬¬ä¸å¼ Panel,ä¼ éå°ä¸ä¸ç¯è |
| | | Lock(); |
| | | CPanel* pContext = m_panelList.front(); |
| | | pContext->addRef(); |
| | | |
| | | CIntent intent(FLOW_MOVE_MATERIAL, "", pContext); |
| | | int nRet = pOutPin->sendIntent(&intent); |
| | | if (nRet == FLOW_REJECT) { |
| | | AfxMessageBox("å¯¹æ¹æç»æ¥å"); |
| | | } |
| | | else if (nRet == FLOW_ACCEPT) { |
| | | m_panelList.pop_front(); |
| | | pContext->release(); // æ·»å å°åéæ¶addRef, ååºæ¶release |
| | | } |
| | | |
| | | pContext->release(); |
| | | Unlock(); |
| | | } |
| | | } |
| | |
| | | AfxMessageBox("è¿æ¥å¤±è´¥"); |
| | | } |
| | | else { |
| | | AfxMessageBox("è¿æ¥æå"); |
| | | // AfxMessageBox("è¿æ¥æå"); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // CPageGraph1.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "CPageGraph1.h" |
| | | #include "afxdialogex.h" |
| | | #include "Common.h" |
| | | |
| | | |
| | | |
| | | // Image |
| | | #define IMAGE_ROBOT 2 |
| | | |
| | | #define INDICATE_BONDER1 1 |
| | | #define INDICATE_BONDER2 2 |
| | | #define INDICATE_FLIPER 3 |
| | | #define INDICATE_ALIGNER 4 |
| | | #define INDICATE_LPORT4 5 |
| | | #define INDICATE_LPORT3 6 |
| | | #define INDICATE_LPORT2 7 |
| | | #define INDICATE_LPORT1 8 |
| | | #define INDICATE_ROBOT_ARM1 9 |
| | | #define INDICATE_ROBOT_ARM2 10 |
| | | #define INDICATE_VACUUM_BAKE 11 |
| | | #define INDICATE_BAKE_COOLING 12 |
| | | #define INDICATE_MEASUREMENT 13 |
| | | |
| | | // CPageGraph1 å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CPageGraph1, CDialogEx) |
| | | |
| | | CPageGraph1::CPageGraph1(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_PAGE_GRAPH1, pParent) |
| | | { |
| | | m_pGraph = nullptr; |
| | | m_pObserver = nullptr; |
| | | m_bIsRobotMoving = FALSE; |
| | | m_crBkgnd = PAGE_GRPAH1_BACKGROUND_COLOR; |
| | | m_hbrBkgnd = nullptr; |
| | | } |
| | | |
| | | CPageGraph1::~CPageGraph1() |
| | | { |
| | | } |
| | | |
| | | void CPageGraph1::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CPageGraph1, CDialogEx) |
| | | ON_WM_CTLCOLOR() |
| | | ON_WM_DESTROY() |
| | | ON_WM_SIZE() |
| | | ON_NOTIFY(BYSERVOGRAPH_ITEM_CLICKED, IDC_SERVO_GRAPH1, &CPageGraph1::OnGraphItemClicked) |
| | | ON_WM_ERASEBKGND() |
| | | ON_WM_TIMER() |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CPageGraph1 æ¶æ¯å¤çç¨åº |
| | | |
| | | |
| | | void CPageGraph1::InitRxWindows() |
| | | { |
| | | /* code */ |
| | | // 订é
æ°æ® |
| | | IRxWindows* pRxWindows = RX_GetRxWindows(); |
| | | pRxWindows->enableLog(5); |
| | | if (m_pObserver == NULL) { |
| | | m_pObserver = pRxWindows->allocObserver([&](IAny* pAny) -> void { |
| | | // onNext |
| | | pAny->addRef(); |
| | | int code = pAny->getCode(); |
| | | if (RX_CODE_EQ_ALIVE == code) { |
| | | // éç¥è®¾å¤ç¶æ |
| | | SERVO::CEquipment* pEquipment = nullptr; |
| | | if (pAny->getPtrValue("ptr", (void*&)pEquipment)) { |
| | | if (pEquipment != nullptr) { |
| | | int nID = pEquipment->getID(); |
| | | BOOL bAlive = pEquipment->isAlive(); |
| | | if (EQ_ID_EFEM == nID) { |
| | | DeviceStatus status = bAlive ? DeviceStatus::ONLINE : DeviceStatus::OFFLINE; |
| | | UpdateDeviceStatus(INDICATE_ROBOT_ARM1, status); |
| | | UpdateDeviceStatus(INDICATE_ROBOT_ARM2, status); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | pAny->release(); |
| | | }, [&]() -> void { |
| | | // onComplete |
| | | }, [&](IThrowable* pThrowable) -> void { |
| | | // onErrorm |
| | | pThrowable->printf(); |
| | | }); |
| | | |
| | | theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread()) |
| | | ->subscribe(m_pObserver); |
| | | } |
| | | } |
| | | |
| | | BOOL CPageGraph1::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | SetTimer(1, 3000, nullptr); |
| | | |
| | | |
| | | // å¾ç¤º |
| | | m_pGraph = CServoGraph::Hook(GetDlgItem(IDC_SERVO_GRAPH1)->GetSafeHwnd()); |
| | | CString strPath; |
| | | strPath.Format(_T("%s\\res\\Servo001.bmp"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | m_pGraph->AddImage(1, (LPTSTR)(LPCTSTR)strPath, 0, 0); |
| | | |
| | | strPath.Format(_T("%s\\res\\Robot001.bmp"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | m_pGraph->AddImage(IMAGE_ROBOT, (LPTSTR)(LPCTSTR)strPath, 170, 270); |
| | | |
| | | // æ·»å æç¤ºå¨ |
| | | // Bonder |
| | | m_pGraph->AddIndicateBox(INDICATE_BONDER1, 220, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_BONDER1, "10", "Bonder 1"); |
| | | m_pGraph->AddIndicateBox(INDICATE_BONDER2, 220, 516, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_BONDER2, "11", "Bonder 2"); |
| | | |
| | | |
| | | // 翻转 |
| | | m_pGraph->AddIndicateBox(INDICATE_FLIPER, 338, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_FLIPER, "8", "Fliper"); |
| | | |
| | | |
| | | // å¯¹ä½ |
| | | m_pGraph->AddIndicateBox(INDICATE_ALIGNER, 428, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_ALIGNER, "7", "Aligner"); |
| | | |
| | | |
| | | // Load port 4 |
| | | m_pGraph->AddIndicateBox(INDICATE_LPORT4, 518, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT4, "4", "LPort4"); |
| | | |
| | | |
| | | // Load port 3 |
| | | m_pGraph->AddIndicateBox(INDICATE_LPORT3, 606, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT3, "3", "LPort3"); |
| | | |
| | | |
| | | // Load port 2 |
| | | m_pGraph->AddIndicateBox(INDICATE_LPORT2, 690, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT2, "2", "LPort2"); |
| | | |
| | | |
| | | // Load port 1 |
| | | m_pGraph->AddIndicateBox(INDICATE_LPORT1, 774, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT1, "1", "LPort1"); |
| | | |
| | | |
| | | // Robot |
| | | m_pGraph->AddIndicateBox(INDICATE_ROBOT_ARM1, 190, 294, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_ROBOT_ARM1, "5", "Robot"); |
| | | m_pGraph->AddIndicateBox(INDICATE_ROBOT_ARM2, 243, 294, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_ROBOT_ARM2, "6", "Robot"); |
| | | |
| | | |
| | | |
| | | |
| | | // Vacuum bake |
| | | m_pGraph->AddIndicateBox(INDICATE_VACUUM_BAKE, 396, 516, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_VACUUM_BAKE, "9", "Vacuum bake"); |
| | | |
| | | |
| | | // Bake cooling |
| | | m_pGraph->AddIndicateBox(INDICATE_BAKE_COOLING, 566, 516, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_BAKE_COOLING, "12", "Bake cooling"); |
| | | |
| | | |
| | | // ç²¾åº¦æ£ |
| | | m_pGraph->AddIndicateBox(INDICATE_MEASUREMENT, 737, 516, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_MEASUREMENT, "13", "Measurement"); |
| | | |
| | | |
| | | // ç»å®æ°æ® |
| | | { |
| | | SERVO::CEquipment* pEquipment = theApp.m_model.m_master.getEquipment(EQ_ID_EFEM); |
| | | m_pGraph->SetIndicateBoxData(INDICATE_ROBOT_ARM1, pEquipment); |
| | | } |
| | | |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| | | |
| | | void CPageGraph1::UpdateDeviceStatus(int id, DeviceStatus status) |
| | | { |
| | | // æ ¹æ®ç¶æè®¾ç½®é¢è² |
| | | COLORREF newBackgroundColor; |
| | | COLORREF newFrameColor1; |
| | | COLORREF newFrameColor2; |
| | | |
| | | switch (status) { |
| | | case ONLINE: |
| | | newBackgroundColor = EQ_BOX_ONLINE; |
| | | newFrameColor1 = EQ_BOX_FRAME1; |
| | | newFrameColor2 = EQ_BOX_FRAME2; |
| | | break; |
| | | case OFFLINE: |
| | | newBackgroundColor = RGB(222, 222, 222); |
| | | newFrameColor1 = EQ_BOX_FRAME1; |
| | | newFrameColor2 = EQ_BOX_FRAME2; |
| | | break; |
| | | default: |
| | | newBackgroundColor = RGB(255, 255, 255); // é»è®¤ç½è²èæ¯ |
| | | newFrameColor1 = RGB(0, 0, 0); // é»è®¤é»è²æ¡æ¶1 |
| | | newFrameColor2 = RGB(0, 0, 0); // é»è®¤é»è²æ¡æ¶2 |
| | | break; |
| | | } |
| | | |
| | | m_pGraph->UpdateIndicateBox1Colors(id, newBackgroundColor, newFrameColor1, newFrameColor2); |
| | | |
| | | // å·æ°çé¢ |
| | | Invalidate(); |
| | | UpdateWindow(); |
| | | } |
| | | |
| | | BOOL CPageGraph1::OnEraseBkgnd(CDC* pDC) |
| | | { |
| | | // TODO: 卿¤æ·»å æ¶æ¯å¤çç¨åºä»£ç å/æè°ç¨é»è®¤å¼ |
| | | if (m_bIsRobotMoving) { |
| | | // ç¦æ¢å·æ°èæ¯ï¼é¿å
éªç |
| | | return TRUE; |
| | | } |
| | | |
| | | return CDialogEx::OnEraseBkgnd(pDC); |
| | | } |
| | | |
| | | HBRUSH CPageGraph1::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) |
| | | { |
| | | HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); |
| | | |
| | | if (nCtlColor == CTLCOLOR_STATIC) { |
| | | pDC->SetBkColor(m_crBkgnd); |
| | | pDC->SetTextColor(RGB(0, 0, 0)); |
| | | } |
| | | |
| | | if (m_hbrBkgnd == nullptr) { |
| | | m_hbrBkgnd = CreateSolidBrush(m_crBkgnd); |
| | | } |
| | | |
| | | return m_hbrBkgnd; |
| | | } |
| | | |
| | | void CPageGraph1::OnDestroy() |
| | | { |
| | | CDialogEx::OnDestroy(); |
| | | |
| | | if (m_hbrBkgnd != nullptr) { |
| | | ::DeleteObject(m_hbrBkgnd); |
| | | } |
| | | } |
| | | |
| | | void CPageGraph1::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | if (GetDlgItem(IDC_SERVO_GRAPH1) == nullptr) return; |
| | | |
| | | CRect rcClient; |
| | | GetClientRect(&rcClient); |
| | | GetDlgItem(IDC_SERVO_GRAPH1)->MoveWindow(0, 0, rcClient.Width(), rcClient.Height()); |
| | | } |
| | | |
| | | void CPageGraph1::UpdateRobotPosition(float percentage) |
| | | { |
| | | // éå¶ç¾åæ¯èå´å¨ [0, 1] ä¹é´ |
| | | if (percentage < 0.0f) percentage = 0.0f; |
| | | if (percentage > 1.0f) percentage = 1.0f; |
| | | |
| | | // æ ¹æ®ç¾åæ¯è®¡ç®ç®æ X åæ |
| | | int startX = m_pGraph->GetImage(IMAGE_ROBOT)->x; |
| | | int endX = static_cast<int>(170 + percentage * (700 - 170)); |
| | | |
| | | int arm1Offset = 20; // ä»å¾çå°ARM1çåç§» |
| | | int arm2Offset = 73; // ä»å¾çå°ARM2çåç§» |
| | | |
| | | // 计ç®ç§»å¨æéçæ¶é´ |
| | | int distance = abs(endX - startX); |
| | | int duration = static_cast<int>((distance / 100.0) * 1000); |
| | | |
| | | auto startTime = std::chrono::steady_clock::now(); |
| | | auto endTime = startTime + std::chrono::milliseconds(duration); |
| | | |
| | | // å¼å§ç§»å¨ï¼è®¾ç½®æ è®° |
| | | m_bIsRobotMoving = TRUE; |
| | | |
| | | // å¼å§å¹³æ»ç§»å¨ |
| | | while (std::chrono::steady_clock::now() < endTime) { |
| | | auto currentTime = std::chrono::steady_clock::now(); |
| | | float progress = std::chrono::duration<float, std::milli>(currentTime - startTime).count() / duration; |
| | | progress = min(progress, 1.0f); |
| | | |
| | | // æ ¹æ®è¿åº¦è®¡ç®å½åä½ç½® |
| | | int currentX = static_cast<int>(startX + progress * (endX - startX)); |
| | | m_pGraph->UpdateImageCoordinates(IMAGE_ROBOT, currentX, 270); |
| | | m_pGraph->UpdateIndicateBoxCoordinates(INDICATE_ROBOT_ARM1, currentX + arm1Offset, 294); |
| | | m_pGraph->UpdateIndicateBoxCoordinates(INDICATE_ROBOT_ARM2, currentX + arm2Offset, 294); |
| | | |
| | | // å·æ°çé¢ |
| | | Invalidate(); |
| | | UpdateWindow(); |
| | | |
| | | // æ§å¶å¸§ç约为 60 FPS |
| | | std::this_thread::sleep_for(std::chrono::milliseconds(16)); |
| | | } |
| | | |
| | | // ç¡®ä¿æåä½ç½®ç²¾ç¡®å°ç®æ ä½ç½® |
| | | m_pGraph->UpdateImageCoordinates(IMAGE_ROBOT, endX, 270); |
| | | m_pGraph->UpdateIndicateBoxCoordinates(INDICATE_ROBOT_ARM1, endX + arm1Offset, 294); |
| | | m_pGraph->UpdateIndicateBoxCoordinates(INDICATE_ROBOT_ARM2, endX + arm2Offset, 294); |
| | | |
| | | // çé¢éç» |
| | | Invalidate(); |
| | | |
| | | // å¨ç»ç»æï¼è®¾ç½®æ è®° |
| | | m_bIsRobotMoving = FALSE; |
| | | } |
| | | |
| | | void CPageGraph1::RotateRobot(float angleInDegrees) |
| | | { |
| | | // å°è§åº¦è½¬æ¢ä¸ºå¼§åº¦ |
| | | float angleInRadians = static_cast<float>(std::acos(-1)) / 180.0f * angleInDegrees; |
| | | |
| | | // è·åæºå¨äººå¾ççå½ååæ åä¸å¿ |
| | | auto* pImage = m_pGraph->GetImage(IMAGE_ROBOT); |
| | | if (!pImage) return; |
| | | |
| | | // æ´æ° Rotate å¾ççè§åº¦ï¼ç¡®ä¿è§åº¦ä¿æå¨ [0, 360) èå´å
|
| | | m_pGraph->UpdateImageAngle(IMAGE_ROBOT, static_cast<float>(fmod(pImage->angle + angleInDegrees + 360, 360))); |
| | | |
| | | int cx = pImage->x + pImage->bmWidth / 2; // å¾çä¸å¿ X |
| | | int cy = pImage->y + pImage->bmHeight / 2; // å¾çä¸å¿ Y |
| | | |
| | | // æè½¬æç¤ºæ¡çåæ |
| | | auto* pRobot1 = m_pGraph->GetIndicateBox(INDICATE_ROBOT_ARM1); |
| | | auto* pRobot2 = m_pGraph->GetIndicateBox(INDICATE_ROBOT_ARM2); |
| | | |
| | | if (pRobot1 && pRobot2) { |
| | | int newArmX1 = pImage->x + 20; |
| | | int newArmY1 = 294; |
| | | |
| | | int newArmX2 = pImage->x + 73; |
| | | int newArmY2 = 294; |
| | | |
| | | if (angleInDegrees != 0.0f) { |
| | | // è®¡ç®æç¤ºæ¡1çæ°åæ |
| | | newArmX1 = static_cast<int>(cx + (pRobot1->x - cx) * cos(angleInRadians) - (pRobot1->y - cy) * sin(angleInRadians)); |
| | | newArmY1 = static_cast<int>(cy + (pRobot1->x - cx) * sin(angleInRadians) + (pRobot1->y - cy) * cos(angleInRadians)); |
| | | |
| | | // è®¡ç®æç¤ºæ¡2çæ°åæ |
| | | newArmX2 = static_cast<int>(cx + (pRobot2->x - cx) * cos(angleInRadians) - (pRobot2->y - cy) * sin(angleInRadians)); |
| | | newArmY2 = static_cast<int>(cy + (pRobot2->x - cx) * sin(angleInRadians) + (pRobot2->y - cy) * cos(angleInRadians)); |
| | | } |
| | | |
| | | // æ´æ°æç¤ºæ¡çä½ç½® |
| | | m_pGraph->UpdateIndicateBoxCoordinates(INDICATE_ROBOT_ARM1, newArmX1, newArmY1); |
| | | m_pGraph->UpdateIndicateBoxCoordinates(INDICATE_ROBOT_ARM2, newArmX2, newArmY2); |
| | | } |
| | | |
| | | // 强å¶éç»çé¢ |
| | | Invalidate(); |
| | | } |
| | | |
| | | void CPageGraph1::OnGraphItemClicked(NMHDR* pNMHDR, LRESULT* pResult) |
| | | { |
| | | BYSERVOGRAPH_NMHDR* pGraphNmhdr = reinterpret_cast<BYSERVOGRAPH_NMHDR*>(pNMHDR); |
| | | CString s; s.Format(_T("OnGraphItemClicked %d"), pGraphNmhdr->dwData); |
| | | SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)m_pGraph->GetIndicateBoxData(pGraphNmhdr->dwData); |
| | | if (pEquipment != nullptr) { |
| | | AfxMessageBox(pEquipment->getName().c_str()); |
| | | } |
| | | |
| | | |
| | | *pResult = 0; |
| | | } |
| | | |
| | | void CPageGraph1::OnTimer(UINT_PTR nIDEvent) |
| | | { |
| | | if (1 == nIDEvent) { |
| | | KillTimer(1); |
| | | InitRxWindows(); |
| | | } |
| | | |
| | | CDialogEx::OnTimer(nIDEvent); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "ServoGraph.h" |
| | | |
| | | |
| | | enum DeviceStatus { |
| | | ONLINE, // å¨çº¿ |
| | | OFFLINE, // 离线 |
| | | }; |
| | | |
| | | |
| | | // CPageGraph1 å¯¹è¯æ¡ |
| | | |
| | | class CPageGraph1 : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CPageGraph1) |
| | | |
| | | public: |
| | | CPageGraph1(CWnd* pParent = nullptr); // æ åæé 彿° |
| | | virtual ~CPageGraph1(); |
| | | |
| | | |
| | | public: |
| | | void InitRxWindows(); |
| | | void UpdateDeviceStatus(int id, DeviceStatus status); |
| | | void UpdateRobotPosition(float percentage); |
| | | void RotateRobot(float angleInDegrees); |
| | | |
| | | private: |
| | | IObserver* m_pObserver; |
| | | CServoGraph* m_pGraph; |
| | | BOOL m_bIsRobotMoving; |
| | | COLORREF m_crBkgnd; |
| | | HBRUSH m_hbrBkgnd; |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_PAGE_GRAPH1 }; |
| | | #endif |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); |
| | | afx_msg void OnDestroy(); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnGraphItemClicked(NMHDR* pNMHDR, LRESULT* pResult); |
| | | afx_msg BOOL OnEraseBkgnd(CDC* pDC); |
| | | afx_msg void OnTimer(UINT_PTR nIDEvent); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // CPageGraph2.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "CPageGraph2.h" |
| | | #include "afxdialogex.h" |
| | | |
| | | |
| | | // CPageGraph2 å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CPageGraph2, CDialogEx) |
| | | |
| | | CPageGraph2::CPageGraph2(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_PAGE_GRAPH2, pParent) |
| | | { |
| | | m_pEqsGraphWnd = nullptr; |
| | | m_crBkgnd = PAGE_GRPAH2_BACKGROUND_COLOR; |
| | | m_hbrBkgnd = nullptr; |
| | | } |
| | | |
| | | CPageGraph2::~CPageGraph2() |
| | | { |
| | | } |
| | | |
| | | void CPageGraph2::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CPageGraph2, CDialogEx) |
| | | ON_WM_CTLCOLOR() |
| | | ON_WM_DESTROY() |
| | | ON_WM_SIZE() |
| | | ON_WM_TIMER() |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CPageGraph2 æ¶æ¯å¤çç¨åº |
| | | |
| | | |
| | | BOOL CPageGraph2::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | SetTimer(1, 2000, nullptr); |
| | | |
| | | |
| | | // filter graph wnd |
| | | EqsGraphListener listener; |
| | | listener.onCheckConnectPin = [](PIN* pPin1, PIN* pPin2) -> bool { |
| | | ASSERT(pPin1); |
| | | ASSERT(pPin2); |
| | | ASSERT(pPin1->pData); |
| | | ASSERT(pPin2->pData); |
| | | |
| | | //int nRet = ((IPin*)pPin1->pData)->checkConnectPin((IPin*)pPin2->pData); |
| | | //if (nRet >= 0) { |
| | | // return true; |
| | | //} |
| | | |
| | | return false; |
| | | }; |
| | | listener.onConnectPin = [](PIN* pPin1, PIN* pPin2) -> bool { |
| | | ASSERT(pPin1); |
| | | ASSERT(pPin2); |
| | | ASSERT(pPin1->pData); |
| | | ASSERT(pPin2->pData); |
| | | |
| | | //int nRet = ((IPin*)pPin1->pData)->connectPin((IPin*)pPin2->pData); |
| | | //if (nRet >= 0) { |
| | | // return true; |
| | | //} |
| | | |
| | | return false; |
| | | }; |
| | | listener.onDisconnectPin = [](PIN* pPin) -> bool { |
| | | ASSERT(pPin); |
| | | ASSERT(pPin->pData); |
| | | |
| | | //int nRet = ((IPin*)pPin->pData)->disconnect(); |
| | | //if (nRet >= 0) { |
| | | // return true; |
| | | //} |
| | | |
| | | return false; |
| | | }; |
| | | listener.onDeleteEqItem = [&](EQITEM* pItem) -> bool { |
| | | ASSERT(pItem); |
| | | ASSERT(pItem->pData); |
| | | return true; |
| | | // return _filterManager.unload((CFilter*)pFilter->pData) >= 0; |
| | | }; |
| | | listener.onEqItemPosChanged = [&](EQITEM* pItem, int x, int y) -> void { |
| | | ASSERT(pItem); |
| | | }; |
| | | listener.onDblckEqItem = [&](EQITEM* pItem) -> bool { |
| | | ASSERT(pItem); |
| | | return true; |
| | | }; |
| | | listener.onRclickEqItem = [&](EQITEM* pItem) -> bool { |
| | | ASSERT(pItem); |
| | | return true; |
| | | }; |
| | | |
| | | m_pEqsGraphWnd = CEqsGraphWnd::FromHandle(GetDlgItem(IDC_EQSGRAPHWND1)->m_hWnd); |
| | | m_pEqsGraphWnd->SetBkgndColor(m_crBkgnd); |
| | | m_pEqsGraphWnd->SetOnListener(listener); |
| | | |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| | | |
| | | |
| | | HBRUSH CPageGraph2::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) |
| | | { |
| | | HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); |
| | | |
| | | if (nCtlColor == CTLCOLOR_STATIC) { |
| | | pDC->SetBkColor(m_crBkgnd); |
| | | pDC->SetTextColor(RGB(0, 0, 0)); |
| | | } |
| | | |
| | | if (m_hbrBkgnd == nullptr) { |
| | | m_hbrBkgnd = CreateSolidBrush(m_crBkgnd); |
| | | } |
| | | |
| | | return m_hbrBkgnd; |
| | | } |
| | | |
| | | |
| | | void CPageGraph2::OnDestroy() |
| | | { |
| | | CDialogEx::OnDestroy(); |
| | | |
| | | if (m_hbrBkgnd != nullptr) { |
| | | ::DeleteObject(m_hbrBkgnd); |
| | | } |
| | | } |
| | | |
| | | |
| | | void CPageGraph2::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | if (GetDlgItem(IDC_EQSGRAPHWND1) == nullptr) return; |
| | | |
| | | CRect rcClient; |
| | | GetClientRect(&rcClient); |
| | | GetDlgItem(IDC_EQSGRAPHWND1)->MoveWindow(0, 0, rcClient.Width(), rcClient.Height()); |
| | | } |
| | | |
| | | #define INPIN 1 |
| | | #define OUTPIN 2 |
| | | void CPageGraph2::AddEqToGraphWnd(SERVO::CEquipment* pEquipment) |
| | | { |
| | | EQITEM* pItem = m_pEqsGraphWnd->AddItem(0, pEquipment->getName().c_str(), (DWORD_PTR)pEquipment); |
| | | m_pEqsGraphWnd->SetItemType(pItem, ITEM_SMALL); |
| | | std::vector<SERVO::CPin*>& inPins = pEquipment->getInputPins(); |
| | | for (auto inPin : inPins) { |
| | | m_pEqsGraphWnd->AddPin(pItem, INPIN, inPin->getName().c_str(), (DWORD_PTR)inPin); |
| | | } |
| | | |
| | | std::vector<SERVO::CPin*>& outPins = pEquipment->getOutputPins(); |
| | | for (auto outPin : outPins) { |
| | | m_pEqsGraphWnd->AddPin(pItem, OUTPIN, outPin->getName().c_str(), (DWORD_PTR)outPin); |
| | | } |
| | | } |
| | | |
| | | void CPageGraph2::OnTimer(UINT_PTR nIDEvent) |
| | | { |
| | | if (1 == nIDEvent) { |
| | | KillTimer(1); |
| | | std::list<SERVO::CEquipment*>& eqs = theApp.m_model.m_master.getEquipmentList(); |
| | | for (auto item : eqs) { |
| | | AddEqToGraphWnd(item); |
| | | } |
| | | } |
| | | |
| | | CDialogEx::OnTimer(nIDEvent); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "EqsGraphWnd.h" |
| | | |
| | | |
| | | // CPageGraph2 å¯¹è¯æ¡ |
| | | |
| | | class CPageGraph2 : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CPageGraph2) |
| | | |
| | | public: |
| | | CPageGraph2(CWnd* pParent = nullptr); // æ åæé 彿° |
| | | virtual ~CPageGraph2(); |
| | | |
| | | |
| | | private: |
| | | void AddEqToGraphWnd(SERVO::CEquipment* pEquipment); |
| | | |
| | | private: |
| | | CEqsGraphWnd* m_pEqsGraphWnd; |
| | | COLORREF m_crBkgnd; |
| | | HBRUSH m_hbrBkgnd; |
| | | |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_PAGE_GRAPH2 }; |
| | | #endif |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); |
| | | afx_msg void OnDestroy(); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnTimer(UINT_PTR nIDEvent); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "CPanel.h" |
| | | |
| | | |
| | | namespace SERVO { |
| | | CPanel::CPanel() |
| | | { |
| | | |
| | | } |
| | | |
| | | CPanel::~CPanel() |
| | | { |
| | | |
| | | } |
| | | |
| | | std::string& CPanel::getClassName() |
| | | { |
| | | static std::string strName = "CPanel"; |
| | | return strName; |
| | | } |
| | | |
| | | std::string CPanel::toString() |
| | | { |
| | | std::string strText; |
| | | strText += "CPanel["; |
| | | strText += ("ID:" + m_strID + ";"); |
| | | strText += "]"; |
| | | |
| | | return strText; |
| | | } |
| | | |
| | | void CPanel::setID(const char* pszID) |
| | | { |
| | | m_strID = pszID; |
| | | } |
| | | |
| | | std::string& CPanel::getID() |
| | | { |
| | | return m_strID; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "Context.h" |
| | | #include <string> |
| | | |
| | | |
| | | namespace SERVO { |
| | | class CPanel : public CContext |
| | | { |
| | | public: |
| | | CPanel(); |
| | | virtual ~CPanel(); |
| | | |
| | | public: |
| | | virtual std::string& getClassName(); |
| | | virtual std::string toString(); |
| | | void setID(const char* pszID); |
| | | std::string& getID(); |
| | | |
| | | private: |
| | | std::string m_strID; |
| | | }; |
| | | } |
| | | |
| | |
| | | int CPin::sendIntent(CIntent* pIntent) |
| | | { |
| | | if (m_pConnectedPin != NULL) { |
| | | m_pConnectedPin->recvIntent(pIntent); |
| | | return m_pConnectedPin->recvIntent(pIntent); |
| | | } |
| | | |
| | | return 0; |
| | | return FLOW_REJECT; |
| | | } |
| | | |
| | | int CPin::recvIntent(CIntent* pIntent) |
| | | { |
| | | assert(m_pEquipment); |
| | | m_pEquipment->recvIntent(this, pIntent); |
| | | return 0; |
| | | return m_pEquipment->recvIntent(this, pIntent); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "ColorTransfer.h" |
| | | |
| | | |
| | | CColorTransfer::CColorTransfer() |
| | | { |
| | | } |
| | | |
| | | |
| | | CColorTransfer::~CColorTransfer() |
| | | { |
| | | } |
| | | |
| | | COLORREF CColorTransfer::ApproximateColor(COLORREF crScr, double diff) |
| | | { |
| | | double h, s, l; |
| | | RGB2HSL(crScr, h, s, l); |
| | | l -= diff; |
| | | |
| | | return HSL2RGB(h, s, l); |
| | | } |
| | | |
| | | void CColorTransfer::RGB2HSL(COLORREF color, double &H, double &S, double &L) |
| | | { |
| | | double R, G, B, Max, Min, del_R, del_G, del_B, del_Max; |
| | | R = GetRValue(color) / 255.0; //Where RGB values = 0 ÷ 255 |
| | | G = GetGValue(color) / 255.0; |
| | | B = GetBValue(color) / 255.0; |
| | | |
| | | Min = min(R, min(G, B)); //Min. value of RGB |
| | | Max = max(R, max(G, B)); //Max. value of RGB |
| | | del_Max = Max - Min; //Delta RGB value |
| | | |
| | | L = (Max + Min) / 2.0; |
| | | |
| | | if (del_Max == 0) { |
| | | // This is a gray, no chroma... |
| | | // H = 2.0/3.0; //Windowsä¸Så¼ä¸º0æ¶ï¼Hå¼å§ç»ä¸º160ï¼2/3*240ï¼ |
| | | H = 0; //HSL results = 0 ÷ 1 |
| | | S = 0; |
| | | } |
| | | else { |
| | | //Chromatic data... |
| | | if (L < 0.5) { |
| | | S = del_Max / (Max + Min); |
| | | } |
| | | else { |
| | | S = del_Max / (2 - Max - Min); |
| | | } |
| | | |
| | | del_R = (((Max - R) / 6.0) + (del_Max / 2.0)) / del_Max; |
| | | del_G = (((Max - G) / 6.0) + (del_Max / 2.0)) / del_Max; |
| | | del_B = (((Max - B) / 6.0) + (del_Max / 2.0)) / del_Max; |
| | | |
| | | if (R == Max) { |
| | | H = del_B - del_G; |
| | | } |
| | | else if (G == Max) { |
| | | H = (1.0 / 3.0) + del_R - del_B; |
| | | } |
| | | else if (B == Max) { |
| | | H = (2.0 / 3.0) + del_G - del_R; |
| | | } |
| | | |
| | | if (H < 0) { |
| | | H += 1; |
| | | } |
| | | if (H > 1) { |
| | | H -= 1; |
| | | } |
| | | } |
| | | } |
| | | |
| | | COLORREF CColorTransfer::HSL2RGB(double H, double S, double L) |
| | | { |
| | | double R, G, B; |
| | | double var_1, var_2; |
| | | if (S == 0) { |
| | | // HSL values = 0 ÷ 1 |
| | | R = L * 255.0; //RGB results = 0 ÷ 255 |
| | | G = L * 255.0; |
| | | B = L * 255.0; |
| | | } |
| | | else { |
| | | if (L < 0.5) { |
| | | var_2 = L * (1 + S); |
| | | } |
| | | else { |
| | | var_2 = (L + S) - (S * L); |
| | | } |
| | | var_1 = 2.0 * L - var_2; |
| | | |
| | | R = 255.0 * Hue2RGB(var_1, var_2, H + (1.0 / 3.0)); |
| | | G = 255.0 * Hue2RGB(var_1, var_2, H); |
| | | B = 255.0 * Hue2RGB(var_1, var_2, H - (1.0 / 3.0)); |
| | | } |
| | | return RGB(R, G, B); |
| | | } |
| | | |
| | | double CColorTransfer::Hue2RGB(double v1, double v2, double vH) |
| | | { |
| | | if (vH < 0) { |
| | | vH += 1; |
| | | } |
| | | |
| | | if (vH > 1) { |
| | | vH -= 1; |
| | | } |
| | | |
| | | if (6.0 * vH < 1) { |
| | | return v1 + (v2 - v1) * 6.0 * vH; |
| | | } |
| | | |
| | | if (2.0 * vH < 1) { |
| | | return v2; |
| | | } |
| | | |
| | | if (3.0 * vH < 2) { |
| | | return v1 + (v2 - v1) * ((2.0 / 3.0) - vH) * 6.0; |
| | | } |
| | | |
| | | return (v1); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | class CColorTransfer |
| | | { |
| | | public: |
| | | CColorTransfer(); |
| | | ~CColorTransfer(); |
| | | |
| | | public: |
| | | static void RGB2HSL(COLORREF color, double &H, double &S, double &L); |
| | | static COLORREF HSL2RGB(double H, double S, double L); |
| | | static COLORREF ApproximateColor(COLORREF crScr, double diff); |
| | | |
| | | private: |
| | | static double Hue2RGB(double v1, double v2, double vH); |
| | | }; |
| | | |
| | |
| | | #define PANEL_MASTER_BACKGROUND_COLOR RGB(255, 255, 255) |
| | | #define PANEL_ATTRIBUTES_BACKGROUND_COLOR RGB(255, 255, 255) |
| | | #define PANEL_EQUIPMENT_BACKGROUND_COLOR RGB(255, 255, 255) |
| | | #define PAGE_GRPAH1_BACKGROUND_COLOR RGB(255, 255, 255) |
| | | #define PAGE_GRPAH2_BACKGROUND_COLOR RGB(255, 255, 255) |
| | | #define EQ_BOX_OFFLINE RGB(222, 222, 222) |
| | | #define EQ_BOX_ONLINE RGB(0, 176, 80) |
| | | #define EQ_BOX_FRAME1 RGB(22, 22, 22) |
| | |
| | | #define STEP_EQ_VCR_ENABLE _T("EQVCREnable") |
| | | |
| | | |
| | | /* base alarm */ |
| | | #define BASE_ALARM_EFEM 10000 |
| | | #define BASE_ALARM_BONDER1 20000 |
| | | #define BASE_ALARM_BONDER2 30000 |
| | |
| | | |
| | | /* èªå®ä¹æ¶æ¯ */ |
| | | #define ID_MSG_PANEL_RESIZE WM_USER + 1998 |
| | | |
| | | |
| | | /* æµç¨æ§å¶ç¸å
³ä»£ç */ |
| | | #define FLOW_REJECT 0x0 |
| | | #define FLOW_ACCEPT 0x1 |
| | | #define FLOW_TEST 0x1000 |
| | | #define FLOW_SIGNAL 0x1001 |
| | | #define FLOW_DATA 0x1002 |
| | | #define FLOW_MOVE_MATERIAL 0x1003 |
| | |
| | | CContext::CContext() |
| | | { |
| | | m_nRef = 0; |
| | | m_nRetCode = CRC_UNKNOWN; |
| | | m_nRetCode = 0; |
| | | m_hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); |
| | | InitializeCriticalSection(&m_criticalSection); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #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); |
| | | } |
| | | |
| | | 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: |
| | | 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)); |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include <functional> |
| | | |
| | | |
| | | #ifndef EQSGRAPHWND_TAG |
| | | |
| | | #ifdef _WIN32 |
| | | |
| | | #define EQSGRAPHWND_CLASSA "EqsGraphWnd" |
| | | #define EQSGRAPHWND_CLASSW L"EqsGraphWnd" |
| | | |
| | | #ifdef UNICODE |
| | | #define EQSGRAPHWND_CLASS EQSGRAPHWND_CLASSW |
| | | #else |
| | | #define EQSGRAPHWND_CLASS EQSGRAPHWND_CLASSA |
| | | #endif |
| | | |
| | | #else |
| | | #define EQSGRAPHWND_CLASS "EqsGraphWnd" |
| | | #endif |
| | | |
| | | |
| | | #define EQSGRAPHWND_TAG _T("EQSGRAPHWND_TAG") |
| | | |
| | | #define EQSGRAPHWND_FIRST (0U-2890U) |
| | | #define EQSGRAPHWND_LAST (0U-2850U) |
| | | #define EQSGRAPHWND_ (EQSGRAPHWND_FIRST - 1) |
| | | |
| | | |
| | | #ifndef MIN |
| | | #define MIN(X,Y) (((X)>(Y))?(Y):(X)) |
| | | #endif |
| | | |
| | | #ifndef MAX |
| | | #define MAX(X,Y) (((X)>(Y))?(X):(Y)) |
| | | #endif |
| | | |
| | | typedef struct tagEQSGRAPHWND_NMHDR |
| | | { |
| | | NMHDR nmhdr; |
| | | DWORD dwData; |
| | | DWORD dwData1; |
| | | DWORD dwData2; |
| | | } EQSGRAPHWND_NMHDR; |
| | | |
| | | typedef struct tagEQITEM |
| | | { |
| | | unsigned int id; |
| | | RECT rect; |
| | | char text[64]; |
| | | BOOL bHighlight; |
| | | int nShowType; |
| | | DWORD_PTR pData; |
| | | DWORD_PTR pInPins; |
| | | DWORD_PTR pOutPins; |
| | | int nFlashFlag; |
| | | } EQITEM; |
| | | |
| | | typedef struct tagPIN |
| | | { |
| | | int nIndex; |
| | | int nType; |
| | | char text[64]; |
| | | BOOL bHighlight; |
| | | EQITEM* pItem; |
| | | tagPIN *pConnectedPin; |
| | | POINT ptConnectedLine[6]; |
| | | int nLinePtCount; |
| | | DWORD_PTR pData; |
| | | } PIN; |
| | | |
| | | #define ITEM_NORMAL 0 |
| | | #define ITEM_SMALL 1 |
| | | #define ITEM_LARGE 2 |
| | | |
| | | #endif |
| | | |
| | | typedef std::function<bool(PIN *pPin1, PIN *pPin2)> ONCONNECTPIN; |
| | | typedef std::function<bool(PIN *pPin)> ONDISCONNECTPIN; |
| | | typedef std::function<bool(EQITEM* pItem)> ONDELETEEQITEM; |
| | | typedef std::function<void(EQITEM* pItem, int x, int y)> ONEQITEMPOSCHANGED; |
| | | |
| | | typedef struct _EqsGraphListener |
| | | { |
| | | ONCONNECTPIN onConnectPin; |
| | | ONCONNECTPIN onCheckConnectPin; |
| | | ONDISCONNECTPIN onDisconnectPin; |
| | | ONDELETEEQITEM onDeleteEqItem; |
| | | ONEQITEMPOSCHANGED onEqItemPosChanged; |
| | | ONDELETEEQITEM onDblckEqItem; |
| | | ONDELETEEQITEM onRclickEqItem; |
| | | } EqsGraphListener; |
| | | |
| | | class CEqsGraphWnd |
| | | { |
| | | typedef struct tagRECTF |
| | | { |
| | | float left; |
| | | float top; |
| | | float right; |
| | | float bottom; |
| | | } RECTF; |
| | | |
| | | public: |
| | | CEqsGraphWnd(); |
| | | ~CEqsGraphWnd(); |
| | | |
| | | public: |
| | | static BOOL RegisterWndClass(); |
| | | static CEqsGraphWnd* FromHandle(HWND hWnd); |
| | | void SetFrameColor(COLORREF color); |
| | | void SetBkgndColor(COLORREF color); |
| | | |
| | | public: |
| | | void EnableScroll(BOOL bEnable); |
| | | void EnableMultiSelect(); |
| | | void SetItemRound(int nRound); |
| | | void SetDefaultItemBackgroundColor(COLORREF crNormal, COLORREF crSel); |
| | | void SetDefaultItemFrameColor(COLORREF crNormal, COLORREF crSel); |
| | | void SetDefaultItemTextColor(COLORREF crNormal, COLORREF crSel); |
| | | void SetOnListener(EqsGraphListener& listener); |
| | | BOOL SetCurSel(int nSel); |
| | | BOOL SetCurSel(CString strItemName); |
| | | BOOL SetCurSel(DWORD_PTR pData); |
| | | EQITEM * AddItem(int id, CString strText, DWORD_PTR dwData, int nType = ITEM_NORMAL); |
| | | void RemoveItem(EQITEM* pItem); |
| | | PIN * AddPin(EQITEM* pItem, int nType, CString strName, DWORD_PTR dwData); |
| | | int DeleteItem(EQITEM* pItem); |
| | | void DeleteAllItems(); |
| | | void SetItemSelectState(int nIndex, BOOL bSelect); |
| | | void SetCurrentItem(EQITEM* pItem); |
| | | BOOL GetItemRect(EQITEM* pItem, LPRECT lpRect); |
| | | BOOL GetItemWarperRect(EQITEM* pItem, LPRECT lpRect); |
| | | BOOL GetInPinRect(EQITEM* pItem, int nPinIndex, LPRECT lpRect); |
| | | BOOL GetOutPinRect(EQITEM* pItem, int nPinIndex, LPRECT lpRect); |
| | | BOOL GetPinPoint(PIN *pPin, LPPOINT lpPoint); |
| | | EQITEM* GetItem(DWORD_PTR dwData); |
| | | PIN * GetPin(DWORD_PTR dwItemData, DWORD_PTR dwPinData); |
| | | int ConnectPin(DWORD_PTR dwItem1Data, DWORD_PTR dwPin1Data, DWORD_PTR dwItem2Data, DWORD_PTR dwPin2Data); |
| | | void SetItemText(EQITEM* pItem, CString strText); |
| | | void SetItemType(EQITEM* pItem, int type); |
| | | void FlashItem(EQITEM* pItem); |
| | | void AnimationItem(EQITEM*pItem); |
| | | |
| | | private: |
| | | void Init(); |
| | | void InitFont(); |
| | | void Notify(int nCode, int dwData, int dwData1 = 0, int dwData2 = 0); |
| | | void Release(); |
| | | void ReleaseItem(EQITEM* pItem); |
| | | void ReleaseAllItems(); |
| | | void CalculateScollbar(); |
| | | void CalculateMapPos(); |
| | | void CalculateMagneticLine(EQITEM* pItem, LPRECT lprcItemRect, int &hoz, int &ver); |
| | | int HighTest(POINT pt, OUT EQITEM*& pItem, OUT PIN *& pPin); |
| | | int GetPinState(PIN *pPin); |
| | | void ClearConnectedLinePoint(EQITEM*& pItem); |
| | | void DrawMagneticLine(LPRECT lprcClient, int nHozLine1, int nHozLine2, int nVerLine1, int nVerLine2); |
| | | void DrawArrow(Gdiplus::Graphics *pGraphics, Gdiplus::Brush* pBrush, Gdiplus::Pen *pPen, |
| | | int x, int y, int nArrowLen); |
| | | void DrawDropItemRectangle(LPRECT lpRect1, LPRECT lpRect2); |
| | | void DrawPinConnectedLine(Gdiplus::Graphics *pGraphics, Gdiplus::Brush *pBrush, Gdiplus::Pen *pPen, LPPOINT lpPt1, LPPOINT lpPt2, |
| | | LPRECT lpRect1, LPRECT lpRect2, PIN *pOwnerPin); |
| | | void DrawPinWillConnectLine(COLORREF color, LPPOINT lpPt1, LPPOINT lpPt2); |
| | | double PointToSegDist(double x, double y, double x1, double y1, double x2, double y2); |
| | | static CEqsGraphWnd* Hook(HWND hWnd); |
| | | static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); |
| | | static LRESULT OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnDestroy(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnTimer(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnNcPaint(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnPaint(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnMouseMove(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnRButtonDown(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnLButtonDblclk(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnMouseWheel(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnMouseHWheel(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnKeyDown(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnSize(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnVScroll(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnHScroll(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnNitify(WPARAM wParam, LPARAM lParam); |
| | | |
| | | private: |
| | | EQITEM* m_pCurItem; |
| | | int m_nFlashCount; |
| | | EQITEM* m_pFlashItem; |
| | | EQITEM* m_pAnimationItem; |
| | | PIN * m_pCurPin; |
| | | PIN * m_pSelLineOutPin; // éä¸çè¿çº¿ç两个pinä¸çout pin |
| | | |
| | | private: |
| | | HWND m_hWnd; |
| | | COLORREF m_crBkgnd; |
| | | COLORREF m_crFrame; |
| | | HFONT m_hFontTitle; |
| | | |
| | | private: |
| | | BOOL m_bUseGdiPlus; // 使ç¨GDI+ç»å¾ï¼ |
| | | COLORREF m_crItemBackground[2]; // itemçé¢è²ï¼normalï¼ active |
| | | COLORREF m_crItemFrame[2]; // itemçè¾¹æ¡ï¼normalï¼ active |
| | | COLORREF m_crItemNameText[2]; |
| | | COLORREF m_crItemIdText[2]; |
| | | COLORREF m_crPinBkgnd[3]; // pinçé¢è²ï¼normal, active, enable connect |
| | | int m_nCurSel; |
| | | EqsGraphListener m_listener; |
| | | CPtrArray m_arItem; |
| | | BOOL m_bMultiSelect; |
| | | int m_nItemRound; |
| | | |
| | | private: |
| | | int m_nStageCx; // ç»å¸å¤§å° |
| | | int m_nStageCy; |
| | | int m_nOffsetX; |
| | | int m_nOffsetY; |
| | | |
| | | // å¨ç» |
| | | RECTF m_rcAnimation; |
| | | RECTF m_rcAninationStep; |
| | | int m_nAninationStep; |
| | | int m_nAninationDuration; // ms |
| | | |
| | | // åä½ |
| | | HFONT m_hFontName; |
| | | HFONT m_hFontId; |
| | | |
| | | private: |
| | | HWND m_hWndMapPos; |
| | | BOOL m_bEnableScroll; |
| | | int m_nMagneticLinHoz; |
| | | int m_nMagneticLinVer; |
| | | }; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // HmTab.cpp: implementation of the CHmTab class. |
| | | // |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | #include "stdafx.h" |
| | | #include "HmTab.h" |
| | | |
| | | #ifdef _DEBUG |
| | | #undef THIS_FILE |
| | | static char THIS_FILE[]=__FILE__; |
| | | #define new DEBUG_NEW |
| | | #endif |
| | | |
| | | ////////////////////////////////////////////////////////////////////// |
| | | // Construction/Destruction |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | CHmTab::CHmTab() |
| | | { |
| | | m_hWnd = NULL; |
| | | m_crBkgnd = RGB(250, 250, 255); |
| | | m_nPaddingLeft = 28; |
| | | m_nPaddingBottom = 12; |
| | | m_nItemMarginLeft = 8; |
| | | m_crText[0] = RGB(88, 88, 88); |
| | | m_crText[1] = RGB(18, 18, 18); |
| | | m_pPressItem = nullptr; |
| | | m_pHighItem = nullptr; |
| | | |
| | | LOGBRUSH lb; |
| | | lb.lbColor = RGB(225, 127, 39); |
| | | lb.lbHatch = 0; |
| | | lb.lbStyle = BS_SOLID; |
| | | DWORD iStyle = PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_SQUARE | PS_JOIN_MITER; |
| | | m_hPenUnder[0] = ExtCreatePen(iStyle, 3, &lb, 0, NULL); |
| | | lb.lbColor = RGB(225, 127, 39); |
| | | m_hPenUnder[1] = ExtCreatePen(iStyle, 2, &lb, 0, NULL); |
| | | lb.lbColor = RGB(223, 226, 230); |
| | | m_hPenUnderWnd = ExtCreatePen(iStyle, 1, &lb, 0, NULL); |
| | | m_nCurSel = 0; |
| | | } |
| | | |
| | | CHmTab::~CHmTab() |
| | | { |
| | | if (m_hPenUnder[0] != nullptr) { |
| | | ::DeleteObject(m_hPenUnder[0]); |
| | | } |
| | | if (m_hPenUnder[1] != nullptr) { |
| | | ::DeleteObject(m_hPenUnder[1]); |
| | | } |
| | | |
| | | if (m_hPenUnderWnd != nullptr) { |
| | | ::DeleteObject(m_hPenUnderWnd); |
| | | } |
| | | } |
| | | |
| | | BOOL CHmTab::RegisterWndClass() |
| | | { |
| | | WNDCLASS wc; |
| | | wc.lpszClassName = BYHMTAB_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); |
| | | } |
| | | |
| | | CHmTab* CHmTab::Hook(HWND hWnd) |
| | | { |
| | | CHmTab* pHmTab = (CHmTab*)GetProp(hWnd, BYSTAG_HMTAB); |
| | | if(pHmTab == NULL) |
| | | { |
| | | pHmTab = new CHmTab; |
| | | pHmTab->m_hWnd = hWnd; |
| | | |
| | | SetProp(hWnd, BYSTAG_HMTAB, (HANDLE)pHmTab); |
| | | } |
| | | |
| | | return pHmTab; |
| | | } |
| | | |
| | | void CHmTab::Release() |
| | | { |
| | | // delete |
| | | delete this; |
| | | } |
| | | |
| | | void CHmTab::SetPaddingLeft(int value) |
| | | { |
| | | m_nPaddingLeft = value; |
| | | } |
| | | |
| | | void CHmTab::SetItemMarginLeft(int value) |
| | | { |
| | | m_nItemMarginLeft = value; |
| | | } |
| | | |
| | | void CHmTab::SetTextColor(COLORREF color1, COLORREF color2) |
| | | { |
| | | m_crText[0] = color1; |
| | | m_crText[1] = color2; |
| | | InvalidateRect(m_hWnd, NULL, TRUE); |
| | | } |
| | | |
| | | int CHmTab::AddItem(const char* pszText,BOOL bUpdate/* = TRUE*/) |
| | | { |
| | | HMTABITEM item; |
| | | memset(&item, 0, sizeof(HMTABITEM)); |
| | | strcpy_s(item.szText, MHITEM_TEXT_MAX, pszText); |
| | | m_items.push_back(item); |
| | | |
| | | if (bUpdate) { |
| | | InvalidateRect(m_hWnd, NULL, TRUE); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CHmTab::DeleteItem(const char* pszText, BOOL bUpdate/* = TRUE*/) |
| | | { |
| | | for (auto iter = m_items.begin(); iter != m_items.end(); iter++) { |
| | | if (strcmp((*iter).szText, pszText) == 0) { |
| | | m_items.erase(iter); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (bUpdate) { |
| | | InvalidateRect(m_hWnd, NULL, TRUE); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | void CHmTab::Notify(int nCode, DWORD_PTR dwData, DWORD_PTR dwData1/* = 0*/, DWORD_PTR dwData2/* = 0*/) |
| | | { |
| | | HWND hParent; |
| | | hParent = GetParent(m_hWnd); |
| | | if (hParent != NULL) { |
| | | BYHMTAB_NMHDR iii_nmhdr; |
| | | iii_nmhdr.nmhdr.hwndFrom = m_hWnd; |
| | | iii_nmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID); |
| | | iii_nmhdr.nmhdr.code = nCode; |
| | | iii_nmhdr.dwData = dwData; |
| | | iii_nmhdr.dwData1 = dwData1; |
| | | iii_nmhdr.dwData2 = dwData2; |
| | | SendMessage(hParent, WM_NOTIFY, (WPARAM)iii_nmhdr.nmhdr.idFrom, (LPARAM)&iii_nmhdr); |
| | | } |
| | | } |
| | | |
| | | //////////////////////////////// |
| | | // æ¦æªçªå£æ¶æ¯å½æ° |
| | | LRESULT CALLBACK CHmTab::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
| | | { |
| | | CHmTab* pHmTab = (CHmTab *)GetProp(hWnd, BYSTAG_HMTAB); |
| | | if(pHmTab == NULL && uMsg != WM_NCCREATE) |
| | | { |
| | | return ::DefWindowProc(hWnd, uMsg, wParam, lParam); |
| | | } |
| | | |
| | | |
| | | // 妿Hookåååºæ¶æ¯ |
| | | ASSERT(hWnd); |
| | | switch(uMsg) |
| | | { |
| | | case WM_NCCREATE: |
| | | return OnNcCreate(hWnd, wParam, lParam); |
| | | |
| | | case WM_DESTROY: |
| | | return pHmTab->OnDestroy(wParam, lParam); |
| | | |
| | | case WM_PAINT: |
| | | return pHmTab->OnPaint(wParam, lParam); |
| | | |
| | | case WM_TIMER: |
| | | return pHmTab->OnTimer(wParam, lParam); |
| | | |
| | | case WM_MOUSEMOVE: |
| | | return pHmTab->OnMouseMove(wParam, lParam); |
| | | |
| | | case WM_LBUTTONDOWN: |
| | | return pHmTab->OnLButtonDown(wParam, lParam); |
| | | |
| | | case WM_SETCURSOR: |
| | | return pHmTab->OnSetCursor(wParam, lParam); |
| | | |
| | | case WM_SIZE: |
| | | return pHmTab->OnSize(wParam, lParam); |
| | | |
| | | case WM_GETDLGCODE: |
| | | return DLGC_WANTALLKEYS; |
| | | |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | return ::DefWindowProc(hWnd, uMsg, wParam, lParam); |
| | | } |
| | | |
| | | /////////////////////////////// |
| | | // WM_NCCREATE |
| | | // çªå£å建åçåå§åå·¥ä½ |
| | | LRESULT CHmTab::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) |
| | | { |
| | | CHmTab* pHmTab = (CHmTab *)GetProp(hWnd, BYSTAG_HMTAB); |
| | | ASSERT(pHmTab == NULL); |
| | | |
| | | Hook(hWnd); |
| | | return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam); |
| | | } |
| | | |
| | | /////////////////////////////// |
| | | // WM_DESTROY |
| | | LRESULT CHmTab::OnDestroy(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | Release(); |
| | | return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam); |
| | | } |
| | | |
| | | /////////////////////////////// |
| | | // WM_TIMER |
| | | LRESULT CHmTab::OnTimer(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | if (wParam == 1) { |
| | | POINT pt; |
| | | GetCursorPos(&pt); |
| | | ::ScreenToClient(m_hWnd, &pt); |
| | | |
| | | HMTABITEM* pLastHighItem = m_pHighItem; |
| | | HighTest(pt, m_pHighItem, nullptr); |
| | | if (m_pHighItem != pLastHighItem) { |
| | | ::InvalidateRect(m_hWnd, NULL, TRUE); |
| | | } |
| | | |
| | | if (m_pHighItem == nullptr) { |
| | | ::KillTimer(m_hWnd, 1); |
| | | } |
| | | } |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam); |
| | | } |
| | | |
| | | /////////////////////////////// |
| | | // WM_MOUSEMOVE |
| | | LRESULT CHmTab::OnMouseMove(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | POINT pt; |
| | | pt.x = LOWORD(lParam); |
| | | pt.y = HIWORD(lParam); |
| | | |
| | | HMTABITEM* pLastHighItem = m_pHighItem; |
| | | int nHitCode = HighTest(pt, m_pHighItem, nullptr); |
| | | if (m_pHighItem != pLastHighItem) { |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | if (m_pHighItem != NULL) { |
| | | ::KillTimer(m_hWnd, 1); |
| | | ::SetTimer(m_hWnd, 1, 100, NULL); |
| | | } |
| | | |
| | | ::SetProp(m_hWnd, HMTAB_HITCODETEST, (HANDLE)(__int64)nHitCode); |
| | | return ::DefWindowProc(m_hWnd, WM_MOUSEMOVE, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_LBUTTONDOWN |
| | | * é¼ æ å·¦é®æä¸ |
| | | */ |
| | | LRESULT CHmTab::OnLButtonDown(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | POINT pt, ptNew; |
| | | pt.x = LOWORD(lParam); |
| | | pt.y = HIWORD(lParam); |
| | | |
| | | BOOL bButtonUp = FALSE; |
| | | int nClickIndex = -1; |
| | | HighTest(pt, m_pPressItem, &nClickIndex); |
| | | if (m_pPressItem != NULL) { |
| | | m_pHighItem = NULL; |
| | | ::InvalidateRect(m_hWnd, NULL, TRUE); |
| | | } |
| | | |
| | | |
| | | // ææé¼ æ æ¶æ¯ï¼æ£æµæ¯å¦æå¨ |
| | | HMTABITEM* pPressItem = NULL; |
| | | if (m_pPressItem != NULL) { |
| | | ::KillTimer(m_hWnd, 1); |
| | | 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); |
| | | HighTest(ptNew, pPressItem, &nClickIndex); |
| | | if (pPressItem != m_pPressItem) { |
| | | m_pPressItem = nullptr; |
| | | ::InvalidateRect(m_hWnd, NULL, TRUE); |
| | | } |
| | | break; |
| | | |
| | | case WM_LBUTTONUP: |
| | | ptNew = msg.pt; |
| | | ::ScreenToClient(m_hWnd, &ptNew); |
| | | HighTest(ptNew, pPressItem, &nClickIndex); |
| | | if (m_pPressItem != nullptr && pPressItem == m_pPressItem) { |
| | | m_nCurSel = nClickIndex; |
| | | bButtonUp = TRUE; |
| | | } |
| | | goto ExitLoop; |
| | | |
| | | case WM_KEYDOWN: |
| | | if (msg.wParam == VK_ESCAPE) { |
| | | goto ExitLoop; |
| | | } |
| | | break; |
| | | |
| | | default: |
| | | DispatchMessage(&msg); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | ExitLoop: |
| | | m_pPressItem = NULL; |
| | | ReleaseCapture(); |
| | | ::InvalidateRect(m_hWnd, NULL, TRUE); |
| | | |
| | | if (bButtonUp) { |
| | | Notify((int)BYHMTAB_SEL_CHANGED, m_nCurSel); |
| | | } |
| | | |
| | | AfxUnlockTempMaps(FALSE); |
| | | } |
| | | } |
| | | |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam); |
| | | } |
| | | |
| | | /////////////////////////////// |
| | | // WM_SETCURSOR |
| | | LRESULT CHmTab::OnSetCursor(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | int nHitCode = (int)(__int64)GetProp(m_hWnd, HMTAB_HITCODETEST); |
| | | switch (nHitCode) |
| | | { |
| | | case HMTAB_HT_NOWHERE: |
| | | case HMTAB_HT_ITEM: |
| | | SetCursor(::LoadCursor(NULL, IDC_ARROW)); |
| | | return TRUE; |
| | | |
| | | case HMTAB_HT_HIGT_ITEM: |
| | | SetCursor(::LoadCursor(NULL, IDC_HAND)); |
| | | return TRUE; |
| | | |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_SETCURSOR, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_SIZE |
| | | */ |
| | | LRESULT CHmTab::OnSize(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | ::InvalidateRect(m_hWnd, NULL, TRUE); |
| | | return ::DefWindowProc(m_hWnd, WM_SIZE, wParam, lParam); |
| | | } |
| | | |
| | | /////////////////////////////// |
| | | // WM_PAINT |
| | | LRESULT CHmTab::OnPaint(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | HDC hDC, hMemDC; |
| | | HBITMAP hBitmap; |
| | | RECT rcClient; |
| | | CString strText; |
| | | HFONT hFont1, hFont2; |
| | | 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); |
| | | ::SetBkMode(hMemDC, TRANSPARENT); |
| | | |
| | | |
| | | HFONT hFontDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT); |
| | | CFont* pFont = CFont::FromHandle(hFontDefault); |
| | | LOGFONT lf; |
| | | pFont->GetLogFont(&lf); |
| | | hFont1 = ::CreateFontIndirect(&lf); |
| | | lf.lfHeight -= 5; |
| | | hFont2 = ::CreateFontIndirect(&lf); |
| | | |
| | | |
| | | // èæ¯é¢è² |
| | | hBrushBK = CreateSolidBrush(m_crBkgnd); |
| | | ::FillRect(hMemDC, &rcClient, hBrushBK); |
| | | DeleteObject(hBrushBK); |
| | | |
| | | |
| | | SelectObject(hMemDC, m_hPenUnderWnd); |
| | | ::MoveToEx(hMemDC, rcClient.left, rcClient.bottom - 2, NULL); |
| | | ::LineTo(hMemDC, rcClient.right, rcClient.bottom - 2); |
| | | |
| | | |
| | | |
| | | // ç»å¶å项 |
| | | SIZE sizeItem; |
| | | RECT rcItem, rcText; |
| | | rcItem.top = rcClient.top; |
| | | rcItem.bottom = rcClient.bottom-1; |
| | | rcItem.left = m_nPaddingLeft; |
| | | int index = 0; |
| | | for (int i = 0; i < m_items.size(); i++) { |
| | | auto& item = m_items.at(i); |
| | | ::SelectObject(hMemDC, i == m_nCurSel ? hFont2 : hFont1); |
| | | ::SetTextColor(hMemDC, i == m_nCurSel ? m_crText[1] : m_crText[0]); |
| | | ::GetTextExtentPoint32(hMemDC, item.szText, (int)strlen(item.szText), &sizeItem); |
| | | rcItem.left += m_nItemMarginLeft; |
| | | rcItem.right = rcItem.left + (int)sizeItem.cx; |
| | | |
| | | ::CopyRect(&rcText, &rcItem); |
| | | rcText.bottom -= m_nPaddingBottom; |
| | | ::DrawText(hMemDC, item.szText, (int)strlen(item.szText), &rcText, |
| | | DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | ::CopyRect(&item.rect, &rcItem); |
| | | |
| | | |
| | | // ä¸å线? |
| | | if (i == m_nCurSel || &item == m_pHighItem) { |
| | | HPEN hOldPen = (HPEN)::SelectObject(hMemDC, i == m_nCurSel ? m_hPenUnder[0] : m_hPenUnder[1]); |
| | | ::MoveToEx(hMemDC, item.rect.left, item.rect.bottom - 3, NULL); |
| | | ::LineTo(hMemDC, item.rect.right, item.rect.bottom - 3); |
| | | ::SelectObject(hMemDC, hOldPen); |
| | | } |
| | | |
| | | |
| | | index++; |
| | | rcItem.left = rcItem.right; |
| | | } |
| | | ::DeleteObject(hFont1); |
| | | ::DeleteObject(hFont2); |
| | | |
| | | |
| | | // 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; |
| | | } |
| | | |
| | | void CHmTab::SetBkgndColor(COLORREF cr) |
| | | { |
| | | m_crBkgnd = cr; |
| | | } |
| | | |
| | | /* |
| | | * æ£æµåæ ç¹æå¨ç项 |
| | | * è¿å, TYGTLITEM |
| | | */ |
| | | int CHmTab::HighTest(POINT pt, OUT HMTABITEM*& pItem, int* pnIndex) |
| | | { |
| | | // æ£æµæ¯å¦å¨æä¸ªå项 |
| | | int nRet = HMTAB_HT_NOWHERE; |
| | | pItem = NULL; |
| | | for (int i = 0; i < m_items.size(); i++) { |
| | | auto& item = m_items.at(i); |
| | | if (::PtInRect(&item.rect, pt)) { |
| | | pItem = &item; |
| | | nRet = pItem == m_pHighItem ? HMTAB_HT_HIGT_ITEM : HMTAB_HT_ITEM; |
| | | if (pnIndex != nullptr) *pnIndex = i; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | |
| | | return nRet; |
| | | } |
| | | |
| | | int CHmTab::GetCurSel() |
| | | { |
| | | return m_nCurSel; |
| | | } |
| | | |
| | | void CHmTab::SetCurSel(int index) |
| | | { |
| | | if (0 <= index && index <= m_items.size()) { |
| | | m_nCurSel = index; |
| | | InvalidateRect(m_hWnd, NULL, TRUE); |
| | | } |
| | | } |
| | | |
| | | int CHmTab::GetItemCount() |
| | | { |
| | | return (int)m_items.size(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // HmTab.h: interface for the CHmTab class. |
| | | // |
| | | ////////////////////////////////////////////////////////////////////// |
| | | |
| | | #if !defined(AFX_HMTAB_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_) |
| | | #define AFX_HMTAB_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_ |
| | | |
| | | |
| | | #pragma comment(lib, "Msimg32.lib") // TransparentBlt |
| | | #include <vector> |
| | | |
| | | |
| | | |
| | | //====== HmTab ===================================================== |
| | | |
| | | #ifndef NOHMTAB |
| | | |
| | | #ifdef _WIN32 |
| | | |
| | | #define BYHMTAB_CLASSA "BYHmTab" |
| | | #define BYHMTAB_CLASSW L"BYHmTab" |
| | | |
| | | #ifdef UNICODE |
| | | #define BYHMTAB_CLASS BYHMTAB_CLASSW |
| | | #else |
| | | #define BYHMTAB_CLASS BYHMTAB_CLASSA |
| | | #endif |
| | | |
| | | #else |
| | | #define BYHMTAB_CLASS "BYHmTab" |
| | | #endif |
| | | |
| | | |
| | | #define BYSTAG_HMTAB _T("ISHMTAB") |
| | | |
| | | |
| | | //====== WM_NOTIFY codes (NMHDR.code values) ================================== |
| | | #define BYHMTAB_FIRST (0U-1190U) // |
| | | #define BYHMTAB_LAST (0U-1150U) |
| | | #define BYHMTAB_SEL_CHANGED (BYHMTAB_FIRST - 1) |
| | | |
| | | |
| | | |
| | | |
| | | typedef struct tagBYHMTAB_NMHDR |
| | | { |
| | | NMHDR nmhdr; |
| | | DWORD_PTR dwData; |
| | | DWORD_PTR dwData1; |
| | | DWORD_PTR dwData2; |
| | | } BYHMTAB_NMHDR; |
| | | |
| | | #define MHITEM_TEXT_MAX 64 |
| | | |
| | | typedef struct tagHMTABITEM |
| | | { |
| | | int id; |
| | | char szText[MHITEM_TEXT_MAX]; |
| | | RECT rect; |
| | | } HMTABITEM; |
| | | |
| | | #define HMTAB_HITCODETEST _T("HitCode") |
| | | #define HMTAB_HT_NOWHERE 0x1 |
| | | #define HMTAB_HT_ITEM 0x2 |
| | | #define HMTAB_HT_HIGT_ITEM 0x4 |
| | | |
| | | |
| | | #endif |
| | | |
| | | |
| | | |
| | | |
| | | #if _MSC_VER > 1000 |
| | | #pragma once |
| | | #endif // _MSC_VER > 1000 |
| | | |
| | | |
| | | class CHmTab |
| | | { |
| | | public: |
| | | CHmTab(); |
| | | virtual ~CHmTab(); |
| | | |
| | | public: |
| | | static BOOL RegisterWndClass(); |
| | | static CHmTab* Hook(HWND hWnd); |
| | | void Notify(int nCode, DWORD_PTR dwData, DWORD_PTR dwData1 = 0, DWORD_PTR dwData2 = 0); |
| | | void Release(); |
| | | void SetBkgndColor(COLORREF cr); |
| | | static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); |
| | | static LRESULT OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnDestroy(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnTimer(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnPaint(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnSetCursor(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnSize(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnMouseMove(WPARAM wParam, LPARAM lParam); |
| | | |
| | | |
| | | public: |
| | | void SetPaddingLeft(int value); |
| | | void SetItemMarginLeft(int value); |
| | | void SetTextColor(COLORREF color1, COLORREF color2); |
| | | int AddItem(const char* pszText, BOOL bUpdate = TRUE); |
| | | int DeleteItem(const char* pszText, BOOL bUpdate = TRUE); |
| | | int HighTest(POINT pt, OUT HMTABITEM*& pItem, int* pnIndex); |
| | | int GetCurSel(); |
| | | void SetCurSel(int index); |
| | | int GetItemCount(); |
| | | |
| | | |
| | | private: |
| | | HWND m_hWnd; |
| | | COLORREF m_crBkgnd; |
| | | |
| | | private: |
| | | int m_nCurSel; |
| | | std::vector< HMTABITEM > m_items; |
| | | HMTABITEM* m_pHighItem; |
| | | HMTABITEM* m_pPressItem; |
| | | int m_nPaddingLeft; |
| | | int m_nPaddingBottom; |
| | | int m_nItemMarginLeft; |
| | | COLORREF m_crText[2]; |
| | | HPEN m_hPenUnder[2]; |
| | | HPEN m_hPenUnderWnd; |
| | | }; |
| | | |
| | | #endif // !defined(AFX_HMTAB_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "MapPosWnd.h" |
| | | #include "ColorTransfer.h" |
| | | |
| | | #define HT_NOWHERE 0x1 |
| | | #define HT_INDICATOR 0x2 |
| | | |
| | | CMapPosWnd::CMapPosWnd() |
| | | { |
| | | m_hWnd = NULL; |
| | | m_crFrame = RGB(0, 0, 0); |
| | | m_crBkgnd = RGB(255, 255, 255); |
| | | m_crViewPort = RGB(185, 122, 87); |
| | | |
| | | m_nWndMaxSize = 200; |
| | | m_nStageCx = 4000; |
| | | m_nStageCy = 3000; |
| | | m_rcViewPort = {200, 200, 800, 800}; |
| | | } |
| | | |
| | | CMapPosWnd::~CMapPosWnd() |
| | | { |
| | | |
| | | } |
| | | |
| | | BOOL CMapPosWnd::RegisterWndClass() |
| | | { |
| | | WNDCLASS wc; |
| | | wc.lpszClassName = MAPPOSWND_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); |
| | | } |
| | | |
| | | CMapPosWnd * CMapPosWnd::FromHandle(HWND hWnd) |
| | | { |
| | | CMapPosWnd *pMapPosWnd = (CMapPosWnd *)::GetProp(hWnd, MAPPOSWND_TAG); |
| | | return pMapPosWnd; |
| | | } |
| | | |
| | | CMapPosWnd* CMapPosWnd::Hook(HWND hWnd) |
| | | { |
| | | CMapPosWnd* pMapPosWnd = (CMapPosWnd*)GetProp(hWnd, MAPPOSWND_TAG); |
| | | if (pMapPosWnd == NULL) { |
| | | pMapPosWnd = new CMapPosWnd(); |
| | | pMapPosWnd->m_hWnd = hWnd; |
| | | |
| | | SetProp(hWnd, MAPPOSWND_TAG, (HANDLE)pMapPosWnd); |
| | | } |
| | | |
| | | |
| | | return pMapPosWnd; |
| | | } |
| | | |
| | | void CMapPosWnd::SetWndMaxSize(int nMaxSize) |
| | | { |
| | | m_nWndMaxSize = nMaxSize; |
| | | } |
| | | |
| | | void CMapPosWnd::SetStageSize(int cx, int cy, BOOL bInvalidata) |
| | | { |
| | | m_nStageCx = cx; |
| | | m_nStageCy = cy; |
| | | |
| | | float scale = max(m_nStageCx / (float)m_nWndMaxSize, m_nStageCy / (float)m_nWndMaxSize); |
| | | int w = (int)(m_nStageCx / scale) +1; |
| | | int h = (int)(m_nStageCy / scale) + 1; |
| | | ::SetWindowPos(m_hWnd, NULL, 0, 0, w, h, SWP_NOMOVE); |
| | | |
| | | if (bInvalidata) { |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | } |
| | | |
| | | void CMapPosWnd::SetViewPort(LPRECT lpRect, BOOL bInvalidata) |
| | | { |
| | | ::CopyRect(&m_rcViewPort, lpRect); |
| | | if (bInvalidata) { |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | } |
| | | |
| | | void CMapPosWnd::GetViewPortRect(LPRECT lprcClient, LPRECT lprcDest) |
| | | { |
| | | RECT rcClient; |
| | | if (lprcClient == NULL) { |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | lprcClient = &rcClient; |
| | | } |
| | | |
| | | |
| | | float scale = max(m_nStageCx / (float)(lprcClient->right - lprcClient->left), m_nStageCy / (float)(lprcClient->bottom - lprcClient->top)); |
| | | lprcDest->left = long(m_rcViewPort.left / scale); |
| | | lprcDest->top = long(m_rcViewPort.top / scale); |
| | | lprcDest->right = long(m_rcViewPort.right / scale); |
| | | lprcDest->bottom = long(m_rcViewPort.bottom / scale); |
| | | } |
| | | |
| | | void CMapPosWnd::Init() |
| | | { |
| | | } |
| | | |
| | | void CMapPosWnd::Release() |
| | | { |
| | | |
| | | // delete |
| | | delete this; |
| | | } |
| | | |
| | | void CMapPosWnd::Notify(int nCode, int dwData, int dwData1/* = 0*/, int dwData2/* = 0*/) |
| | | { |
| | | HWND hParent; |
| | | hParent = GetParent(m_hWnd); |
| | | if (hParent != NULL) { |
| | | MAPPOSWND_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_INDICATOR |
| | | */ |
| | | int CMapPosWnd::HighTest(POINT pt) |
| | | { |
| | | // æ£æµæ¯å¦å¨æä¸ªå项 |
| | | int nRet = HT_NOWHERE; |
| | | |
| | | RECT rcClient, rcViewPort; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | GetViewPortRect(&rcClient, &rcViewPort); |
| | | if (::PtInRect(&rcViewPort, pt)) { |
| | | nRet = HT_INDICATOR; |
| | | } |
| | | |
| | | return nRet; |
| | | } |
| | | |
| | | /* |
| | | * WindowProcï¼çªå£è¿ç¨ |
| | | */ |
| | | LRESULT CALLBACK CMapPosWnd::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
| | | { |
| | | CMapPosWnd* pMapPosWnd = (CMapPosWnd *)GetProp(hWnd, MAPPOSWND_TAG); |
| | | if (pMapPosWnd == NULL && uMsg != WM_NCCREATE) |
| | | { |
| | | return ::DefWindowProc(hWnd, uMsg, wParam, lParam); |
| | | } |
| | | |
| | | |
| | | // å¤ççªå£æ¶æ¯ |
| | | ASSERT(hWnd); |
| | | switch (uMsg) |
| | | { |
| | | case WM_NCCREATE: |
| | | return CMapPosWnd::OnNcCreate(hWnd, wParam, lParam); |
| | | |
| | | case WM_DESTROY: |
| | | return pMapPosWnd->OnDestroy(wParam, lParam); |
| | | |
| | | case WM_NCPAINT: |
| | | return pMapPosWnd->OnNcPaint(wParam, lParam); |
| | | |
| | | case WM_PAINT: |
| | | return pMapPosWnd->OnPaint(wParam, lParam); |
| | | |
| | | case WM_TIMER: |
| | | return pMapPosWnd->OnTimer(wParam, lParam); |
| | | |
| | | case WM_MOUSEMOVE: |
| | | return pMapPosWnd->OnMouseMove(wParam, lParam); |
| | | |
| | | case WM_LBUTTONDOWN: |
| | | return pMapPosWnd->OnLButtonDown(wParam, lParam); |
| | | |
| | | case WM_LBUTTONDBLCLK: |
| | | return pMapPosWnd->OnLButtonDblclk(wParam, lParam); |
| | | |
| | | case WM_MOUSEWHEEL: |
| | | return pMapPosWnd->OnMouseWheel(wParam, lParam); |
| | | |
| | | case WM_KEYDOWN: |
| | | return pMapPosWnd->OnKeyDown(wParam, lParam); |
| | | |
| | | case WM_SIZE: |
| | | return pMapPosWnd->OnSize(wParam, lParam); |
| | | |
| | | case WM_GETDLGCODE: |
| | | return DLGC_WANTALLKEYS; |
| | | |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | return ::DefWindowProc(hWnd, uMsg, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_NCCREATE |
| | | * çªå£å建 |
| | | */ |
| | | LRESULT CMapPosWnd::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) |
| | | { |
| | | CMapPosWnd* pMapPosWnd = (CMapPosWnd *)GetProp(hWnd, MAPPOSWND_TAG); |
| | | ASSERT(pMapPosWnd == NULL); |
| | | |
| | | Hook(hWnd)->Init(); |
| | | return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_DESTROY |
| | | * çªå£éæ¯ |
| | | */ |
| | | LRESULT CMapPosWnd::OnDestroy(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | Release(); |
| | | return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam); |
| | | } |
| | | |
| | | |
| | | /* |
| | | * WM_TIMER |
| | | */ |
| | | LRESULT CMapPosWnd::OnTimer(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_MOUSEMOVE |
| | | * é¼ æ æ»å¨ |
| | | */ |
| | | LRESULT CMapPosWnd::OnMouseMove(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | return ::DefWindowProc(m_hWnd, WM_MOUSEMOVE, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_LBUTTONDOWN |
| | | * é¼ æ å·¦é®æä¸ |
| | | */ |
| | | LRESULT CMapPosWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | POINT pt, ptNew, ptPox; |
| | | pt.x = LOWORD(lParam); |
| | | pt.y = HIWORD(lParam); |
| | | |
| | | RECT rcClient, rcLastViewPort; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | float scale = max(m_nStageCx / (float)(rcClient.right - rcClient.left), m_nStageCy / (float)(rcClient.bottom - rcClient.top)); |
| | | CopyRect(&rcLastViewPort, &m_rcViewPort); |
| | | |
| | | |
| | | // æ£æµç¹å»åæ æ¯å¦å¨æä¸å项ä¸ï¼å¦æ¯ï¼åé«äº®æ¾ç¤º |
| | | int nRet = HighTest(pt); |
| | | SetFocus(m_hWnd); |
| | | |
| | | |
| | | // ææé¼ æ æ¶æ¯ï¼æ£æµæ¯å¦æå¨ |
| | | if (nRet == HT_INDICATOR) { |
| | | |
| | | 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); |
| | | ptPox.x = long(rcLastViewPort.left + (ptNew.x - pt.x) * scale); |
| | | ptPox.x = max(0, min(ptPox.x, m_nStageCx - (rcLastViewPort.right - rcLastViewPort.left))); |
| | | ptPox.y = long(rcLastViewPort.top + (ptNew.y - pt.y) * scale); |
| | | ptPox.y = max(0, min(ptPox.y, m_nStageCy - (rcLastViewPort.bottom - rcLastViewPort.top))); |
| | | Notify(MAPPOSWND_POSCHANGED, ptPox.x, ptPox.y); |
| | | break; |
| | | |
| | | case WM_LBUTTONUP: |
| | | ptNew = msg.pt; |
| | | ::ScreenToClient(m_hWnd, &ptNew); |
| | | ptPox.x = long(rcLastViewPort.left + (ptNew.x - pt.x) * scale); |
| | | ptPox.x = max(0, min(ptPox.x, m_nStageCx - (rcLastViewPort.right - rcLastViewPort.left))); |
| | | ptPox.y = long(rcLastViewPort.top + (ptNew.y - pt.y) * scale); |
| | | ptPox.y = max(0, min(ptPox.y, m_nStageCy - (rcLastViewPort.bottom - rcLastViewPort.top))); |
| | | Notify(MAPPOSWND_POSCHANGED, ptPox.x, ptPox.y); |
| | | |
| | | ReleaseCapture(); |
| | | ::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_LBUTTONDBLCLK |
| | | * é¼ æ å·¦é®åå» |
| | | */ |
| | | LRESULT CMapPosWnd::OnLButtonDblclk(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | POINT pt, ptDest; |
| | | pt.x = LOWORD(lParam); |
| | | pt.y = HIWORD(lParam); |
| | | |
| | | RECT rcClient, rcLast; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | rcLast = { 0, 0, 0, 0 }; |
| | | |
| | | // æ£æµç¹å»åæ æ¯å¦å¨ç©ºç½å¤ |
| | | // å°çªåæ 转æ¢ä¸ºå¯¹åºåæ |
| | | int nRet = HighTest(pt); |
| | | if (nRet == HT_NOWHERE || nRet == HT_INDICATOR) { |
| | | float scale = max(m_nStageCx / (float)(rcClient.right - rcClient.left), m_nStageCy / (float)(rcClient.bottom - rcClient.top)); |
| | | ptDest.x = (int)(scale * pt.x) - (m_rcViewPort.right - m_rcViewPort.left) / 2; |
| | | ptDest.x = max(0, min(ptDest.x, m_nStageCx - (m_rcViewPort.right - m_rcViewPort.left))); |
| | | ptDest.y = (int)(scale * pt.y) - (m_rcViewPort.bottom - m_rcViewPort.top) / 2; |
| | | ptDest.y = max(0, min(ptDest.y, m_nStageCy - (m_rcViewPort.bottom - m_rcViewPort.top))); |
| | | Notify(MAPPOSWND_POSCHANGED, ptDest.x, ptDest.y); |
| | | } |
| | | |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_LBUTTONDBLCLK, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_MOUSEWHEEL |
| | | * é¼ æ æ»å¨ |
| | | */ |
| | | LRESULT CMapPosWnd::OnMouseWheel(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | return ::DefWindowProc(m_hWnd, WM_MOUSEWHEEL, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_KEYDOWN |
| | | * é®çæ¶æ¯ï¼æä¸æé® |
| | | */ |
| | | LRESULT CMapPosWnd::OnKeyDown(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | BOOL bChanged = FALSE; |
| | | if (wParam == VK_DELETE) { |
| | | |
| | | } |
| | | |
| | | |
| | | if (bChanged) { |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_KEYDOWN, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_NCPAINT |
| | | */ |
| | | LRESULT CMapPosWnd::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 CMapPosWnd::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); |
| | | |
| | | |
| | | // æ é¢ |
| | | { |
| | | char szTitle[256]; |
| | | GetWindowText(m_hWnd, szTitle, 256); |
| | | RECT rcTitle; |
| | | rcTitle.left = rcClient.left + 2; |
| | | rcTitle.top = rcClient.top + 2; |
| | | rcTitle.bottom = rcClient.bottom - 2; |
| | | rcTitle.right = rcClient.right - 2; |
| | | ::DrawText(hMemDC, szTitle, (int)strlen(szTitle), &rcTitle, DT_LEFT | DT_TOP); |
| | | } |
| | | |
| | | |
| | | // View port |
| | | RECT rcViewPort; |
| | | GetViewPortRect(&rcClient, &rcViewPort); |
| | | HBRUSH hBrushFrame = CreateSolidBrush(m_crViewPort); |
| | | ::FrameRect(hMemDC, &rcViewPort, hBrushFrame); |
| | | ::DeleteObject(hBrushFrame); |
| | | |
| | | |
| | | // 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 CMapPosWnd::OnSize(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | LRESULT lRet = ::DefWindowProc(m_hWnd, WM_SIZE, wParam, lParam); |
| | | |
| | | return lRet; |
| | | } |
| | | |
| | | /* |
| | | * è®¾ç½®èæ¯é¢è² |
| | | * color -- èæ¯è² |
| | | */ |
| | | void CMapPosWnd::SetBkgndColor(COLORREF color) |
| | | { |
| | | m_crBkgnd = color; |
| | | } |
| | | |
| | | /* |
| | | * è¾¹æ¡é¢è² |
| | | * color -- è¾¹æ¡è² |
| | | */ |
| | | void CMapPosWnd::SetFrameColor(COLORREF color) |
| | | { |
| | | m_crFrame = color; |
| | | } |
| | | |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include <functional> |
| | | |
| | | |
| | | #ifndef MAPPOSWND_TAG |
| | | |
| | | #ifdef _WIN32 |
| | | |
| | | #define MAPPOSWND_CLASSA "MapPosWnd" |
| | | #define MAPPOSWND_CLASSW L"MapPosWnd" |
| | | |
| | | #ifdef UNICODE |
| | | #define MAPPOSWND_CLASS MAPPOSWND_CLASSW |
| | | #else |
| | | #define MAPPOSWND_CLASS MAPPOSWND_CLASSA |
| | | #endif |
| | | |
| | | #else |
| | | #define MAPPOSWND_CLASS "MapPosWnd" |
| | | #endif |
| | | |
| | | |
| | | #define MAPPOSWND_TAG _T("MAPPOSWND_TAG") |
| | | |
| | | #define MAPPOSWND_FIRST (0U-5850U) |
| | | #define MAPPOSWND_LAST (0U-2810U) |
| | | #define MAPPOSWND_POSCHANGED (MAPPOSWND_FIRST - 1) |
| | | |
| | | typedef struct tagMAPPOSWND_NMHDR |
| | | { |
| | | NMHDR nmhdr; |
| | | DWORD dwData; |
| | | DWORD dwData1; |
| | | DWORD dwData2; |
| | | } MAPPOSWND_NMHDR; |
| | | |
| | | #endif |
| | | |
| | | class CMapPosWnd |
| | | { |
| | | public: |
| | | CMapPosWnd(); |
| | | ~CMapPosWnd(); |
| | | |
| | | public: |
| | | static BOOL RegisterWndClass(); |
| | | static CMapPosWnd * FromHandle(HWND hWnd); |
| | | void SetFrameColor(COLORREF color); |
| | | void SetBkgndColor(COLORREF color); |
| | | void SetWndMaxSize(int nMaxSize); |
| | | void SetStageSize(int cx, int cy, BOOL bInvalidata); |
| | | void SetViewPort(LPRECT lpRect, BOOL bInvalidata); |
| | | void GetViewPortRect(LPRECT lprcClient, LPRECT lprcDest); |
| | | |
| | | private: |
| | | void Init(); |
| | | void Notify(int nCode, int dwData, int dwData1 = 0, int dwData2 = 0); |
| | | void Release(); |
| | | int HighTest(POINT pt); |
| | | static CMapPosWnd* Hook(HWND hWnd); |
| | | static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); |
| | | static LRESULT OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnDestroy(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnTimer(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnNcPaint(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnPaint(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnMouseMove(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnLButtonDblclk(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnMouseWheel(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnKeyDown(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnSize(WPARAM wParam, LPARAM lParam); |
| | | |
| | | private: |
| | | HWND m_hWnd; |
| | | COLORREF m_crBkgnd; |
| | | COLORREF m_crFrame; |
| | | COLORREF m_crViewPort; |
| | | |
| | | private: |
| | | int m_nWndMaxSize; |
| | | int m_nStageCx; |
| | | int m_nStageCy; |
| | | RECT m_rcViewPort; |
| | | }; |
| | | |
| | |
| | | #include "AlarmManager.h" |
| | | #include "SECSRuntimeManager.h" |
| | | #include "VerticalLine.h" |
| | | #include "EqsGraphWnd.h" |
| | | #include "MapPosWnd.h" |
| | | #include "HmTab.h" |
| | | |
| | | |
| | | // 声æå
¨å±åéï¼ç¨äºç®¡ç GDI+ åå§å |
| | |
| | | // æ³¨åæ§ä»¶ |
| | | CServoGraph::RegisterWndClass(); |
| | | CVerticalLine::RegisterWndClass(); |
| | | CEqsGraphWnd::RegisterWndClass(); |
| | | CMapPosWnd::RegisterWndClass(); |
| | | CHmTab::RegisterWndClass(); |
| | | |
| | | |
| | | // åå§åRxåº |
| | |
| | | <ClInclude Include="CFliper.h" /> |
| | | <ClInclude Include="CLoadPort.h" /> |
| | | <ClInclude Include="CMeasurement.h" /> |
| | | <ClInclude Include="ColorTransfer.h" /> |
| | | <ClInclude Include="CPageGraph1.h" /> |
| | | <ClInclude Include="CPageGraph2.h" /> |
| | | <ClInclude Include="CPanel.h" /> |
| | | <ClInclude Include="CPanelAttributes.h" /> |
| | | <ClInclude Include="CPanelEquipment.h" /> |
| | | <ClInclude Include="CPanelMaster.h" /> |
| | |
| | | <ClInclude Include="Common.h" /> |
| | | <ClInclude Include="Configuration.h" /> |
| | | <ClInclude Include="Context.h" /> |
| | | <ClInclude Include="EqsGraphWnd.h" /> |
| | | <ClInclude Include="HmTab.h" /> |
| | | <ClInclude Include="HsmsAction.h" /> |
| | | <ClInclude Include="HsmsPassive.h" /> |
| | | <ClInclude Include="Intent.h" /> |
| | |
| | | <ClInclude Include="Log.h" /> |
| | | <ClInclude Include="LogDlg.h" /> |
| | | <ClInclude Include="LogEdit.h" /> |
| | | <ClInclude Include="MapPosWnd.h" /> |
| | | <ClInclude Include="Model.h" /> |
| | | <ClInclude Include="Resource.h" /> |
| | | <ClInclude Include="SECSRuntimeManager.h" /> |
| | |
| | | <ClCompile Include="CFliper.cpp" /> |
| | | <ClCompile Include="CLoadPort.cpp" /> |
| | | <ClCompile Include="CMeasurement.cpp" /> |
| | | <ClCompile Include="ColorTransfer.cpp" /> |
| | | <ClCompile Include="CPageGraph1.cpp" /> |
| | | <ClCompile Include="CPageGraph2.cpp" /> |
| | | <ClCompile Include="CPanel.cpp" /> |
| | | <ClCompile Include="CPanelAttributes.cpp" /> |
| | | <ClCompile Include="CPanelEquipment.cpp" /> |
| | | <ClCompile Include="CPanelMaster.cpp" /> |
| | |
| | | <ClCompile Include="CMaster.cpp" /> |
| | | <ClCompile Include="Configuration.cpp" /> |
| | | <ClCompile Include="Context.cpp" /> |
| | | <ClCompile Include="EqsGraphWnd.cpp" /> |
| | | <ClCompile Include="HmTab.cpp" /> |
| | | <ClCompile Include="HsmsAction.cpp" /> |
| | | <ClCompile Include="HsmsPassive.cpp" /> |
| | | <ClCompile Include="Intent.cpp" /> |
| | |
| | | <ClCompile Include="Log.cpp" /> |
| | | <ClCompile Include="LogDlg.cpp" /> |
| | | <ClCompile Include="LogEdit.cpp" /> |
| | | <ClCompile Include="MapPosWnd.cpp" /> |
| | | <ClCompile Include="Model.cpp" /> |
| | | <ClCompile Include="SECSRuntimeManager.cpp" /> |
| | | <ClCompile Include="SecsTestDlg.cpp" /> |
| | |
| | | <ClCompile Include="CBakeCooling.cpp" /> |
| | | <ClCompile Include="CVacuumBake.cpp" /> |
| | | <ClCompile Include="Intent.cpp" /> |
| | | <ClCompile Include="CPanel.cpp" /> |
| | | <ClCompile Include="EqsGraphWnd.cpp" /> |
| | | <ClCompile Include="ColorTransfer.cpp" /> |
| | | <ClCompile Include="MapPosWnd.cpp" /> |
| | | <ClCompile Include="HmTab.cpp" /> |
| | | <ClCompile Include="CPageGraph1.cpp" /> |
| | | <ClCompile Include="CPageGraph2.cpp" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClInclude Include="AlarmManager.h" /> |
| | |
| | | <ClInclude Include="CBakeCooling.h" /> |
| | | <ClInclude Include="CVacuumBake.h" /> |
| | | <ClInclude Include="Intent.h" /> |
| | | <ClInclude Include="CPanel.h" /> |
| | | <ClInclude Include="EqsGraphWnd.h" /> |
| | | <ClInclude Include="ColorTransfer.h" /> |
| | | <ClInclude Include="MapPosWnd.h" /> |
| | | <ClInclude Include="HmTab.h" /> |
| | | <ClInclude Include="CPageGraph1.h" /> |
| | | <ClInclude Include="CPageGraph2.h" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ResourceCompile Include="Servo.rc" /> |
| | |
| | | #include <chrono> |
| | | #include <thread> |
| | | #include <cmath> |
| | | #include "HmTab.h" |
| | | |
| | | |
| | | #ifdef _DEBUG |
| | | #define new DEBUG_NEW |
| | | #endif |
| | | |
| | | // Image |
| | | #define IMAGE_ROBOT 2 |
| | | |
| | | #define INDICATE_BONDER1 1 |
| | | #define INDICATE_BONDER2 2 |
| | | #define INDICATE_FLIPER 3 |
| | | #define INDICATE_ALIGNER 4 |
| | | #define INDICATE_LPORT4 5 |
| | | #define INDICATE_LPORT3 6 |
| | | #define INDICATE_LPORT2 7 |
| | | #define INDICATE_LPORT1 8 |
| | | #define INDICATE_ROBOT_ARM1 9 |
| | | #define INDICATE_ROBOT_ARM2 10 |
| | | #define INDICATE_VACUUM_BAKE 11 |
| | | #define INDICATE_BAKE_COOLING 12 |
| | | #define INDICATE_MEASUREMENT 13 |
| | | |
| | | |
| | | /* å建ç»ç«¯ç宿¶å¨ */ |
| | |
| | | m_hbrBkgnd = nullptr; |
| | | m_bShowLogWnd = FALSE; |
| | | m_bShowAlarmWnd = FALSE; |
| | | m_bIsRobotMoving = FALSE; |
| | | m_pLogDlg = nullptr; |
| | | m_pAlarmDlg = nullptr; |
| | | m_pTerminalDisplayDlg = nullptr; |
| | |
| | | m_pPanelMaster = nullptr; |
| | | m_pPanelEquipment = nullptr; |
| | | m_pPanelAttributes = nullptr; |
| | | m_pPageGraph1 = nullptr; |
| | | m_pPageGraph2 = nullptr; |
| | | } |
| | | |
| | | void CServoDlg::DoDataExchange(CDataExchange* pDX) |
| | |
| | | ON_COMMAND(ID_MENU_HELP_ABOUT, &CServoDlg::OnMenuHelpAbout) |
| | | ON_WM_INITMENUPOPUP() |
| | | ON_WM_TIMER() |
| | | ON_WM_ERASEBKGND() |
| | | ON_BN_CLICKED(IDC_BUTTON_ALARM, &CServoDlg::OnBnClickedButtonAlarm) |
| | | ON_BN_CLICKED(IDC_BUTTON_ALARM, &CServoDlg::OnBnClickedButtonAlarm) |
| | | ON_NOTIFY(BYSERVOGRAPH_ITEM_CLICKED, IDC_SERVO_GRAPH1, &CServoDlg::OnGraphItemClicked) |
| | | ON_MESSAGE(ID_MSG_PANEL_RESIZE, OnPanelResize) |
| | | ON_NOTIFY(BYHMTAB_SEL_CHANGED, IDC_TAB1, &CServoDlg::OnTabSelChanged) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | |
| | | const char* pszText; |
| | | if (pAny->getStringValue("text", pszText)) { |
| | | ShowTerminalText(pszText); |
| | | } |
| | | } |
| | | else if (RX_CODE_EQ_ALIVE == code) { |
| | | // éç¥è®¾å¤ç¶æ |
| | | SERVO::CEquipment* pEquipment = nullptr; |
| | | if (pAny->getPtrValue("ptr", (void*&)pEquipment)) { |
| | | if (pEquipment != nullptr) { |
| | | int nID = pEquipment->getID(); |
| | | BOOL bAlive = pEquipment->isAlive(); |
| | | if (EQ_ID_EFEM == nID) { |
| | | DeviceStatus status = bAlive ? DeviceStatus::ONLINE : DeviceStatus::OFFLINE; |
| | | UpdateDeviceStatus(INDICATE_ROBOT_ARM1, status); |
| | | UpdateDeviceStatus(INDICATE_ROBOT_ARM2, status); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else if (RX_CODE_SELECT_EQUIPMENT == code) { |
| | |
| | | |
| | | |
| | | |
| | | // ͼʾ |
| | | m_pGraph = CServoGraph::Hook(GetDlgItem(IDC_SERVO_GRAPH1)->GetSafeHwnd()); |
| | | CString strPath; |
| | | strPath.Format(_T("%s\\res\\Servo001.bmp"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | m_pGraph->AddImage(1, (LPTSTR)(LPCTSTR)strPath, 0, 0); |
| | | // Tab |
| | | m_pPageGraph1 = new CPageGraph1(); |
| | | m_pPageGraph1->Create(IDD_PAGE_GRAPH1, this); |
| | | m_pPageGraph2 = new CPageGraph2(); |
| | | m_pPageGraph2->Create(IDD_PAGE_GRAPH2, this); |
| | | |
| | | strPath.Format(_T("%s\\res\\Robot001.bmp"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | m_pGraph->AddImage(IMAGE_ROBOT, (LPTSTR)(LPCTSTR)strPath, 170, 270); |
| | | |
| | | // æ·»å æç¤ºå¨ |
| | | // Bonder |
| | | m_pGraph->AddIndicateBox(INDICATE_BONDER1, 220, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_BONDER1, "10", "Bonder 1"); |
| | | m_pGraph->AddIndicateBox(INDICATE_BONDER2, 220, 516, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_BONDER2, "11", "Bonder 2"); |
| | | |
| | | |
| | | // 翻转 |
| | | m_pGraph->AddIndicateBox(INDICATE_FLIPER, 338, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_FLIPER, "8", "Fliper"); |
| | | |
| | | |
| | | // å¯¹ä½ |
| | | m_pGraph->AddIndicateBox(INDICATE_ALIGNER, 428, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_ALIGNER, "7", "Aligner"); |
| | | |
| | | |
| | | // Load port 4 |
| | | m_pGraph->AddIndicateBox(INDICATE_LPORT4, 518, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT4, "4", "LPort4"); |
| | | |
| | | |
| | | // Load port 3 |
| | | m_pGraph->AddIndicateBox(INDICATE_LPORT3, 606, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT3, "3", "LPort3"); |
| | | |
| | | |
| | | // Load port 2 |
| | | m_pGraph->AddIndicateBox(INDICATE_LPORT2, 690, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT2, "2", "LPort2"); |
| | | |
| | | |
| | | // Load port 1 |
| | | m_pGraph->AddIndicateBox(INDICATE_LPORT1, 774, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT1, "1", "LPort1"); |
| | | |
| | | |
| | | // Robot |
| | | m_pGraph->AddIndicateBox(INDICATE_ROBOT_ARM1, 190, 294, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_ROBOT_ARM1, "5", "Robot"); |
| | | m_pGraph->AddIndicateBox(INDICATE_ROBOT_ARM2, 243, 294, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_ROBOT_ARM2, "6", "Robot"); |
| | | |
| | | |
| | | |
| | | |
| | | // Vacuum bake |
| | | m_pGraph->AddIndicateBox(INDICATE_VACUUM_BAKE, 396, 516, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_VACUUM_BAKE, "9", "Vacuum bake"); |
| | | |
| | | |
| | | // Bake cooling |
| | | m_pGraph->AddIndicateBox(INDICATE_BAKE_COOLING, 566, 516, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_BAKE_COOLING, "12", "Bake cooling"); |
| | | |
| | | |
| | | // ç²¾åº¦æ£ |
| | | m_pGraph->AddIndicateBox(INDICATE_MEASUREMENT, 737, 516, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_MEASUREMENT, "13", "Measurement"); |
| | | |
| | | CHmTab* m_pTab = CHmTab::Hook(GetDlgItem(IDC_TAB1)->m_hWnd); |
| | | m_pTab->SetPaddingLeft(20); |
| | | m_pTab->SetItemMarginLeft(18); |
| | | m_pTab->AddItem("æ¥è¡¨", FALSE); |
| | | m_pTab->AddItem("æ¥å¿", TRUE); |
| | | m_pTab->SetCurSel(0); |
| | | m_pTab->SetBkgndColor(RGB(222, 222, 222)); |
| | | ShowChildPage(0); |
| | | |
| | | |
| | | m_pPanelMaster = new CPanelMaster(); |
| | |
| | | |
| | | // ç¸å½äºå»¶æ¶è°ç¨masterçåå§å |
| | | theApp.m_model.m_master.init(); |
| | | |
| | | |
| | | // ç»å®æ°æ® |
| | | { |
| | | SERVO::CEquipment* pEquipment = theApp.m_model.m_master.getEquipment(EQ_ID_EFEM); |
| | | m_pGraph->SetIndicateBoxData(INDICATE_ROBOT_ARM1, pEquipment); |
| | | } |
| | | |
| | | |
| | | return TRUE; // é¤éå°ç¦ç¹è®¾ç½®å°æ§ä»¶ï¼å¦åè¿å TRUE |
| | |
| | | |
| | | void CServoDlg::OnMenuTestMessageClear() |
| | | { |
| | | /* |
| | | SERVO::CEquipment* pEquipment = m_pPanelMaster->GetActiveEquipment(); |
| | | if (pEquipment != nullptr) { |
| | | SERVO::CEqCimMessageClearStep* pStep = (SERVO::CEqCimMessageClearStep*)pEquipment->getStepWithName(STEP_CIM_MESSAGE_CLEAR); |
| | | pStep->clearCimMessage(2, 3); |
| | | } |
| | | */ |
| | | |
| | | SERVO::CLoadPort* pLoadPort1 = |
| | | (SERVO::CLoadPort*)theApp.m_model.m_master.getEquipment(EQ_ID_LOADPORT1); |
| | | pLoadPort1->outputPanel(); |
| | | } |
| | | |
| | | void CServoDlg::OnUpdateMenuTestMessageClear(CCmdUI* pCmdUI) |
| | |
| | | m_pPanelAttributes->DestroyWindow(); |
| | | delete m_pPanelAttributes; |
| | | m_pPanelAttributes = nullptr; |
| | | } |
| | | |
| | | if (m_pPageGraph1 != nullptr) { |
| | | m_pPageGraph1->DestroyWindow(); |
| | | delete m_pPageGraph1; |
| | | m_pPageGraph1 = nullptr; |
| | | } |
| | | |
| | | if (m_pPageGraph2 != nullptr) { |
| | | m_pPageGraph2->DestroyWindow(); |
| | | delete m_pPageGraph2; |
| | | m_pPageGraph2 = nullptr; |
| | | } |
| | | |
| | | if (m_hbrBkgnd != nullptr) { |
| | |
| | | m_btnAlarm.Invalidate(); |
| | | } |
| | | |
| | | void CServoDlg::UpdateRobotPosition(float percentage) |
| | | { |
| | | // éå¶ç¾åæ¯èå´å¨ [0, 1] ä¹é´ |
| | | if (percentage < 0.0f) percentage = 0.0f; |
| | | if (percentage > 1.0f) percentage = 1.0f; |
| | | |
| | | // æ ¹æ®ç¾åæ¯è®¡ç®ç®æ X åæ |
| | | int startX = m_pGraph->GetImage(IMAGE_ROBOT)->x; |
| | | int endX = static_cast<int>(170 + percentage * (700 - 170)); |
| | | |
| | | int arm1Offset = 20; // ä»å¾çå°ARM1çåç§» |
| | | int arm2Offset = 73; // ä»å¾çå°ARM2çåç§» |
| | | |
| | | // 计ç®ç§»å¨æéçæ¶é´ |
| | | int distance = abs(endX - startX); |
| | | int duration = static_cast<int>((distance / 100.0) * 1000); |
| | | |
| | | auto startTime = std::chrono::steady_clock::now(); |
| | | auto endTime = startTime + std::chrono::milliseconds(duration); |
| | | |
| | | // å¼å§ç§»å¨ï¼è®¾ç½®æ è®° |
| | | m_bIsRobotMoving = TRUE; |
| | | |
| | | // å¼å§å¹³æ»ç§»å¨ |
| | | while (std::chrono::steady_clock::now() < endTime) { |
| | | auto currentTime = std::chrono::steady_clock::now(); |
| | | float progress = std::chrono::duration<float, std::milli>(currentTime - startTime).count() / duration; |
| | | progress = min(progress, 1.0f); |
| | | |
| | | // æ ¹æ®è¿åº¦è®¡ç®å½åä½ç½® |
| | | int currentX = static_cast<int>(startX + progress * (endX - startX)); |
| | | m_pGraph->UpdateImageCoordinates(IMAGE_ROBOT, currentX, 270); |
| | | m_pGraph->UpdateIndicateBoxCoordinates(INDICATE_ROBOT_ARM1, currentX + arm1Offset, 294); |
| | | m_pGraph->UpdateIndicateBoxCoordinates(INDICATE_ROBOT_ARM2, currentX + arm2Offset, 294); |
| | | |
| | | // å·æ°çé¢ |
| | | Invalidate(); |
| | | UpdateWindow(); |
| | | |
| | | // æ§å¶å¸§ç约为 60 FPS |
| | | std::this_thread::sleep_for(std::chrono::milliseconds(16)); |
| | | } |
| | | |
| | | // ç¡®ä¿æåä½ç½®ç²¾ç¡®å°ç®æ ä½ç½® |
| | | m_pGraph->UpdateImageCoordinates(IMAGE_ROBOT, endX, 270); |
| | | m_pGraph->UpdateIndicateBoxCoordinates(INDICATE_ROBOT_ARM1, endX + arm1Offset, 294); |
| | | m_pGraph->UpdateIndicateBoxCoordinates(INDICATE_ROBOT_ARM2, endX + arm2Offset, 294); |
| | | |
| | | // çé¢éç» |
| | | Invalidate(); |
| | | |
| | | // å¨ç»ç»æï¼è®¾ç½®æ è®° |
| | | m_bIsRobotMoving = FALSE; |
| | | } |
| | | |
| | | void CServoDlg::RotateRobot(float angleInDegrees) |
| | | { |
| | | // å°è§åº¦è½¬æ¢ä¸ºå¼§åº¦ |
| | | float angleInRadians = static_cast<float>(std::acos(-1)) / 180.0f * angleInDegrees; |
| | | |
| | | // è·åæºå¨äººå¾ççå½ååæ åä¸å¿ |
| | | auto* pImage = m_pGraph->GetImage(IMAGE_ROBOT); |
| | | if (!pImage) return; |
| | | |
| | | // æ´æ° Rotate å¾ççè§åº¦ï¼ç¡®ä¿è§åº¦ä¿æå¨ [0, 360) èå´å
|
| | | m_pGraph->UpdateImageAngle(IMAGE_ROBOT, static_cast<float>(fmod(pImage->angle + angleInDegrees + 360, 360))); |
| | | |
| | | int cx = pImage->x + pImage->bmWidth / 2; // å¾çä¸å¿ X |
| | | int cy = pImage->y + pImage->bmHeight / 2; // å¾çä¸å¿ Y |
| | | |
| | | // æè½¬æç¤ºæ¡çåæ |
| | | auto* pRobot1 = m_pGraph->GetIndicateBox(INDICATE_ROBOT_ARM1); |
| | | auto* pRobot2 = m_pGraph->GetIndicateBox(INDICATE_ROBOT_ARM2); |
| | | |
| | | if (pRobot1 && pRobot2) { |
| | | int newArmX1 = pImage->x + 20; |
| | | int newArmY1 = 294; |
| | | |
| | | int newArmX2 = pImage->x + 73; |
| | | int newArmY2 = 294; |
| | | |
| | | if (angleInDegrees != 0.0f) { |
| | | // è®¡ç®æç¤ºæ¡1çæ°åæ |
| | | newArmX1 = static_cast<int>(cx + (pRobot1->x - cx) * cos(angleInRadians) - (pRobot1->y - cy) * sin(angleInRadians)); |
| | | newArmY1 = static_cast<int>(cy + (pRobot1->x - cx) * sin(angleInRadians) + (pRobot1->y - cy) * cos(angleInRadians)); |
| | | |
| | | // è®¡ç®æç¤ºæ¡2çæ°åæ |
| | | newArmX2 = static_cast<int>(cx + (pRobot2->x - cx) * cos(angleInRadians) - (pRobot2->y - cy) * sin(angleInRadians)); |
| | | newArmY2 = static_cast<int>(cy + (pRobot2->x - cx) * sin(angleInRadians) + (pRobot2->y - cy) * cos(angleInRadians)); |
| | | } |
| | | |
| | | // æ´æ°æç¤ºæ¡çä½ç½® |
| | | m_pGraph->UpdateIndicateBoxCoordinates(INDICATE_ROBOT_ARM1, newArmX1, newArmY1); |
| | | m_pGraph->UpdateIndicateBoxCoordinates(INDICATE_ROBOT_ARM2, newArmX2, newArmY2); |
| | | } |
| | | |
| | | // 强å¶éç»çé¢ |
| | | Invalidate(); |
| | | } |
| | | |
| | | void CServoDlg::UpdateDeviceStatus(int id, DeviceStatus status) |
| | | { |
| | | // æ ¹æ®ç¶æè®¾ç½®é¢è² |
| | | COLORREF newBackgroundColor; |
| | | COLORREF newFrameColor1; |
| | | COLORREF newFrameColor2; |
| | | |
| | | switch (status) { |
| | | case ONLINE: |
| | | newBackgroundColor = EQ_BOX_ONLINE; |
| | | newFrameColor1 = EQ_BOX_FRAME1; |
| | | newFrameColor2 = EQ_BOX_FRAME2; |
| | | break; |
| | | case OFFLINE: |
| | | newBackgroundColor = RGB(222, 222, 222); |
| | | newFrameColor1 = EQ_BOX_FRAME1; |
| | | newFrameColor2 = EQ_BOX_FRAME2; |
| | | break; |
| | | default: |
| | | newBackgroundColor = RGB(255, 255, 255); // é»è®¤ç½è²èæ¯ |
| | | newFrameColor1 = RGB(0, 0, 0); // é»è®¤é»è²æ¡æ¶1 |
| | | newFrameColor2 = RGB(0, 0, 0); // é»è®¤é»è²æ¡æ¶2 |
| | | break; |
| | | } |
| | | |
| | | m_pGraph->UpdateIndicateBox1Colors(id, newBackgroundColor, newFrameColor1, newFrameColor2); |
| | | |
| | | // å·æ°çé¢ |
| | | Invalidate(); |
| | | UpdateWindow(); |
| | | } |
| | | |
| | | void CServoDlg::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | if (GetDlgItem(IDC_SERVO_GRAPH1) == nullptr) return; |
| | | if (GetDlgItem(IDC_TAB1) == nullptr) return; |
| | | if (m_pPageGraph1 == nullptr) return; |
| | | if (m_pPageGraph2 == nullptr) return; |
| | | |
| | | Resize(); |
| | | Invalidate(); |
| | | } |
| | |
| | | x += nPanelWidth; |
| | | } |
| | | |
| | | pItem = GetDlgItem(IDC_SERVO_GRAPH1); |
| | | pItem->GetClientRect(&rcItem); |
| | | pItem->MoveWindow(x, y, rcItem.Width(), rcItem.Height()); |
| | | |
| | | pItem = GetDlgItem(IDC_TAB1); |
| | | pItem->GetWindowRect(rcItem); |
| | | pItem->MoveWindow(x, y, rcClient.Width() - x, rcItem.Height()); |
| | | y += rcItem.Height(); |
| | | y += 8; |
| | | |
| | | |
| | | m_pPageGraph1->MoveWindow(x, y, rcClient.Width() - x, rcClient.Height()); |
| | | m_pPageGraph2->MoveWindow(x, y, rcClient.Width() - x, rcClient.Height()); |
| | | |
| | | |
| | | x = rcClient.right - 8; |
| | | pItem = GetDlgItem(IDC_BUTTON_LOG); |
| | |
| | | CDialogEx::OnTimer(nIDEvent); |
| | | } |
| | | |
| | | |
| | | BOOL CServoDlg::OnEraseBkgnd(CDC* pDC) |
| | | { |
| | | // TODO: 卿¤æ·»å æ¶æ¯å¤çç¨åºä»£ç å/æè°ç¨é»è®¤å¼ |
| | | if (m_bIsRobotMoving) { |
| | | // ç¦æ¢å·æ°èæ¯ï¼é¿å
éªç |
| | | return TRUE; |
| | | } |
| | | |
| | | return CDialogEx::OnEraseBkgnd(pDC); |
| | | } |
| | | |
| | | void CServoDlg::OnGraphItemClicked(NMHDR* pNMHDR, LRESULT* pResult) |
| | | { |
| | | BYSERVOGRAPH_NMHDR* pGraphNmhdr = reinterpret_cast<BYSERVOGRAPH_NMHDR*>(pNMHDR); |
| | | CString s; s.Format(_T("OnGraphItemClicked %d"), pGraphNmhdr->dwData); |
| | | SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)m_pGraph->GetIndicateBoxData(pGraphNmhdr->dwData); |
| | | if (pEquipment != nullptr) { |
| | | AfxMessageBox(pEquipment->getName().c_str()); |
| | | } |
| | | |
| | | |
| | | *pResult = 0; |
| | | } |
| | | |
| | | LRESULT CServoDlg::OnPanelResize(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | int width = wParam; |
| | |
| | | return 0; |
| | | } |
| | | |
| | | void CServoDlg::OnTabSelChanged(NMHDR* nmhdr, LRESULT* result) |
| | | { |
| | | BYHMTAB_NMHDR* pNmhdrex = (BYHMTAB_NMHDR*)nmhdr; |
| | | ShowChildPage((int)pNmhdrex->dwData); |
| | | |
| | | *result = 0; |
| | | } |
| | | |
| | | void CServoDlg::ShowChildPage(int index) |
| | | { |
| | | ASSERT(0 <= index && index < 3); |
| | | static CWnd* pPages[] = { m_pPageGraph1, m_pPageGraph2 }; |
| | | for (int i = 0; i < 2; i++) { |
| | | pPages[i]->ShowWindow(i == index ? SW_SHOW : SW_HIDE); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | // |
| | | |
| | | #pragma once |
| | | #include "ServoGraph.h" |
| | | #include "BlButton.h" |
| | | #include "LogDlg.h" |
| | | #include "AlarmDlg.h" |
| | |
| | | #include "CPanelMaster.h" |
| | | #include "CPanelEquipment.h" |
| | | #include "CPanelAttributes.h" |
| | | #include "CPageGraph1.h" |
| | | #include "CPageGraph2.h" |
| | | |
| | | |
| | | enum DeviceStatus { |
| | | ONLINE, // å¨çº¿ |
| | | OFFLINE, // 离线 |
| | | }; |
| | | |
| | | // CServoDlg å¯¹è¯æ¡ |
| | | class CServoDlg : public CDialogEx |
| | |
| | | void Resize(); |
| | | void UpdateLogBtn(); |
| | | void UpdateAlarmBtn(); |
| | | void UpdateRobotPosition(float percentage); |
| | | void RotateRobot(float angleInDegrees); |
| | | void UpdateDeviceStatus(int id, DeviceStatus status); |
| | | void ShowChildPage(int index); |
| | | |
| | | |
| | | private: |
| | |
| | | CLogDlg* m_pLogDlg; |
| | | CAlarmDlg* m_pAlarmDlg; |
| | | CTerminalDisplayDlg* m_pTerminalDisplayDlg; |
| | | CPageGraph1* m_pPageGraph1; |
| | | CPageGraph2* m_pPageGraph2; |
| | | |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | |
| | | |
| | | private: |
| | | BOOL m_bIsRobotMoving; |
| | | |
| | | // å®ç° |
| | | protected: |
| | | HICON m_hIcon; |
| | | CServoGraph* m_pGraph; |
| | | COLORREF m_crBkgnd; |
| | | HBRUSH m_hbrBkgnd; |
| | | CBlButton m_btnLog; |
| | |
| | | afx_msg void OnUpdateMenuTestMessageClear(CCmdUI* pCmdUI); |
| | | afx_msg void OnMenuHelpAbout(); |
| | | afx_msg void OnTimer(UINT_PTR nIDEvent); |
| | | afx_msg BOOL OnEraseBkgnd(CDC* pDC); |
| | | afx_msg void OnBnClickedButtonAlarm(); |
| | | afx_msg void OnGraphItemClicked(NMHDR* pNMHDR, LRESULT* pResult); |
| | | afx_msg LRESULT OnPanelResize(WPARAM wParam, LPARAM lParam); |
| | | afx_msg void OnTabSelChanged(NMHDR* nmhdr, LRESULT* result); |
| | | }; |