mrDarker
6 天以前 829fe6c6bc33d53fda9c31fd45a37e1df87befff
SourceCode/Bond/Servo/CPanelProduction.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,236 @@
// 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);
}