// 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; } 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_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_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::TryGetShiftSummary(ProductionShiftSummary& outSummary) { CSingleLock lock(&m_csShiftSummary, TRUE); if (!m_bShiftSummaryValid) return FALSE; outSummary = m_shiftSummary; 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(pParam); if (self == nullptr) return 0; const DWORD intervalMs = 5000; for (;;) { if (self->m_evStopStats.Lock(intervalMs)) break; ProductionShiftSummary summary; if (ProductionStats::ComputeCurrentShiftSummary(theApp.m_model.m_configuration, summary)) { CSingleLock lock(&self->m_csShiftSummary, TRUE); self->m_shiftSummary = std::move(summary); self->m_bShiftSummaryValid = TRUE; } } return 0; } void CPanelProduction::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (nIDEvent == 1) { ProductionShiftSummary outSummary; if (TryGetShiftSummary(outSummary)) { TRACE("OnTimer outSummary.output.pairsPass:%d\n", outSummary.output.pairsPass); } } CDialogEx::OnTimer(nIDEvent); }