| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // CPanelProduction.cpp |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "CPanelProduction.h" |
| | | #include "afxdialogex.h" |
| | | #include "Common.h" |
| | | #include "VerticalLine.h" |
| | | |
| | | |
| | | // CPanelProduction dialog |
| | | |
| | | IMPLEMENT_DYNAMIC(CPanelProduction, CDialogEx) |
| | | |
| | | CPanelProduction::CPanelProduction(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_PANEL_PRODUCTION, pParent) |
| | | { |
| | | m_crBkgnd = PANEL_PRODUCTION_BACKGROUND_COLOR; |
| | | m_hbrBkgnd = nullptr; |
| | | m_nPanelWidth = 288; |
| | | m_hPlaceholder = nullptr; |
| | | m_bShiftSummaryValid = FALSE; |
| | | m_pStatsThread = nullptr; |
| | | m_pAccordionWnd = nullptr; |
| | | m_pPageProdOverview = nullptr; |
| | | m_pPageCtrlState = nullptr; |
| | | } |
| | | |
| | | CPanelProduction::~CPanelProduction() |
| | | { |
| | | } |
| | | |
| | | void CPanelProduction::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CPanelProduction, CDialogEx) |
| | | ON_WM_CTLCOLOR() |
| | | ON_WM_DESTROY() |
| | | ON_WM_SIZE() |
| | | ON_NOTIFY(BYVERTICALLINE_MOVEX, IDC_LINE1, &CPanelProduction::OnVLineMoveX) |
| | | ON_BN_CLICKED(IDC_BUTTON_CLOSE, &CPanelProduction::OnBnClickedButtonClose) |
| | | ON_WM_TIMER() |
| | | END_MESSAGE_MAP() |
| | | |
| | | int CPanelProduction::getPanelWidth() |
| | | { |
| | | return m_nPanelWidth; |
| | | } |
| | | |
| | | void CPanelProduction::setPanelWidth(int width) |
| | | { |
| | | m_nPanelWidth = width; |
| | | } |
| | | |
| | | BOOL CPanelProduction::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | CVerticalLine* pLine1 = CVerticalLine::Hook(GetDlgItem(IDC_LINE1)->GetSafeHwnd()); |
| | | pLine1->SetBkgndColor(RGB(225, 225, 225)); |
| | | pLine1->SetLineColor(RGB(198, 198, 198)); |
| | | pLine1->EnableResize(); |
| | | |
| | | CString strExpandIcon, strCloseIcon; |
| | | strExpandIcon.Format(_T("%s\\res\\arrow_down.ico"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | strCloseIcon.Format(_T("%s\\res\\arrow_right.ico"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | |
| | | m_pAccordionWnd = CAccordionWnd::FromHandle(GetDlgItem(IDC_ACCORDION_WND1)->m_hWnd); |
| | | m_pAccordionWnd->SetBkgndColor(m_crBkgnd); |
| | | m_pAccordionWnd->SetFrameColor(RGB(220, 220, 200), TRUE); |
| | | m_pAccordionWnd->Setpadding(PADDING_LEFT, 2); |
| | | m_pAccordionWnd->Setpadding(PADDING_TOP, 2); |
| | | m_pAccordionWnd->Setpadding(PADDING_RIGHT, 2); |
| | | m_pAccordionWnd->Setpadding(PADDING_BOTTOM, 2); |
| | | m_pAccordionWnd->LoadExpandIcon(strExpandIcon, strCloseIcon); |
| | | |
| | | m_pPageCtrlState = new CPageCtrlState(); |
| | | m_pPageCtrlState->SetBackgroundColor(m_crBkgnd); |
| | | m_pPageCtrlState->Create(IDD_PROD_CTRL_STATE, GetDlgItem(IDC_ACCORDION_WND1)); |
| | | m_pPageCtrlState->ShowWindow(SW_HIDE); |
| | | m_pAccordionWnd->AddItem("ç¶æ", m_pPageCtrlState, 120, TRUE, TRUE); |
| | | |
| | | m_pPageProdOverview = new CPageProdOverview(); |
| | | m_pPageProdOverview->SetBackgroundColor(m_crBkgnd); |
| | | m_pPageProdOverview->Create(IDD_PROD_OVERVIEW, GetDlgItem(IDC_ACCORDION_WND1)); |
| | | m_pPageProdOverview->ShowWindow(SW_HIDE); |
| | | m_pAccordionWnd->AddItem("ç产æ»è§", m_pPageProdOverview, 280, TRUE, TRUE); |
| | | |
| | | SetTimer(1, 1000 * 10, nullptr); |
| | | StartStatsThread(); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // Exception: OCX property pages should return FALSE |
| | | } |
| | | |
| | | HBRUSH CPanelProduction::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 CPanelProduction::OnDestroy() |
| | | { |
| | | StopStatsThread(); |
| | | |
| | | CDialogEx::OnDestroy(); |
| | | |
| | | if (m_pPageCtrlState != nullptr) { |
| | | m_pPageCtrlState->DestroyWindow(); |
| | | delete m_pPageCtrlState; |
| | | m_pPageCtrlState = nullptr; |
| | | } |
| | | if (m_pPageProdOverview != nullptr) { |
| | | m_pPageProdOverview->DestroyWindow(); |
| | | delete m_pPageProdOverview; |
| | | m_pPageProdOverview = nullptr; |
| | | } |
| | | |
| | | if (m_hbrBkgnd != nullptr) { |
| | | ::DeleteObject(m_hbrBkgnd); |
| | | } |
| | | } |
| | | |
| | | void CPanelProduction::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | if (GetDlgItem(IDC_LINE1) == nullptr) return; |
| | | |
| | | CWnd* pItem; |
| | | CRect rcClient, rcItem; |
| | | |
| | | GetClientRect(&rcClient); |
| | | pItem = GetDlgItem(IDC_LINE1); |
| | | pItem->MoveWindow(rcClient.right - 3, 0, 3, rcClient.Height()); |
| | | |
| | | pItem = GetDlgItem(IDC_ACCORDION_WND1); |
| | | pItem->MoveWindow(5, 5, rcClient.Width() - 10, rcClient.Height() - 10); |
| | | } |
| | | |
| | | #define PRODUCTION_PANEL_MIN_WIDTH 88 |
| | | #define PRODUCTION_PANEL_MAX_WIDTH 588 |
| | | void CPanelProduction::OnVLineMoveX(NMHDR* nmhdr, LRESULT* result) |
| | | { |
| | | BYVERTICALLINE_NMHDR* pNmhdrex = (BYVERTICALLINE_NMHDR*)nmhdr; |
| | | int x = pNmhdrex->dwData; |
| | | m_nPanelWidth += x; |
| | | m_nPanelWidth = max(m_nPanelWidth, PRODUCTION_PANEL_MIN_WIDTH); |
| | | m_nPanelWidth = min(m_nPanelWidth, PRODUCTION_PANEL_MAX_WIDTH); |
| | | GetParent()->SendMessage(ID_MSG_PANEL_RESIZE, m_nPanelWidth, 0); |
| | | OnSize(0, 0, 0); |
| | | |
| | | *result = 0; |
| | | } |
| | | |
| | | void CPanelProduction::OnBnClickedButtonClose() |
| | | { |
| | | CWnd* pParent = GetParent(); |
| | | if (pParent != nullptr) { |
| | | pParent->PostMessage(WM_COMMAND, ID_MENU_WND_TEST_PANEL, 0); |
| | | } |
| | | } |
| | | |
| | | BOOL CPanelProduction::TryGetDayNightSummaries(ProductionShiftSummary& outDay, ProductionShiftSummary& outNight) |
| | | { |
| | | CSingleLock lock(&m_csShiftSummary, TRUE); |
| | | if (!m_bShiftSummaryValid) return FALSE; |
| | | outDay = m_daySummary; |
| | | outNight = m_nightSummary; |
| | | return TRUE; |
| | | } |
| | | |
| | | void CPanelProduction::StartStatsThread() |
| | | { |
| | | if (m_pStatsThread != nullptr) return; |
| | | |
| | | m_evStopStats.ResetEvent(); |
| | | |
| | | m_pStatsThread = AfxBeginThread(&CPanelProduction::StatsThreadProc, this, THREAD_PRIORITY_BELOW_NORMAL, 0, 0); |
| | | if (m_pStatsThread != nullptr) { |
| | | m_pStatsThread->m_bAutoDelete = FALSE; |
| | | } |
| | | } |
| | | |
| | | void CPanelProduction::StopStatsThread() |
| | | { |
| | | if (m_pStatsThread == nullptr) return; |
| | | |
| | | m_evStopStats.SetEvent(); |
| | | const DWORD rc = WaitForSingleObject(m_pStatsThread->m_hThread, 5000); |
| | | if (rc == WAIT_OBJECT_0) { |
| | | delete m_pStatsThread; |
| | | } |
| | | m_pStatsThread = nullptr; |
| | | } |
| | | |
| | | UINT CPanelProduction::StatsThreadProc(LPVOID pParam) |
| | | { |
| | | CPanelProduction* self = reinterpret_cast<CPanelProduction*>(pParam); |
| | | if (self == nullptr) return 0; |
| | | |
| | | const DWORD intervalMs = 5000; |
| | | for (;;) { |
| | | if (self->m_evStopStats.Lock(intervalMs)) break; |
| | | |
| | | ProductionShiftSummary daySummary; |
| | | ProductionShiftSummary nightSummary; |
| | | if (ProductionStats::ComputeDayNightSummaries(theApp.m_model.m_configuration, daySummary, nightSummary)) { |
| | | CSingleLock lock(&self->m_csShiftSummary, TRUE); |
| | | self->m_daySummary = std::move(daySummary); |
| | | self->m_nightSummary = std::move(nightSummary); |
| | | self->m_bShiftSummaryValid = TRUE; |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | void CPanelProduction::OnTimer(UINT_PTR nIDEvent) |
| | | { |
| | | // TODO: 卿¤æ·»å æ¶æ¯å¤çç¨åºä»£ç å/æè°ç¨é»è®¤å¼ |
| | | CDialogEx::OnTimer(nIDEvent); |
| | | } |