From 0275102b79ccf2c7fe1acf11117de8a89cca372f Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期五, 26 十二月 2025 15:27:03 +0800
Subject: [PATCH] 1.生产总览页面框架实现;
---
SourceCode/Bond/Servo/CPageProdOverview.cpp | 140 +++++
SourceCode/Bond/Servo/Servo.vcxproj | 8
SourceCode/Bond/Servo/resource.h | 9
SourceCode/Bond/Servo/Servo.cpp | 2
SourceCode/Bond/Servo/CPanelProduction.cpp | 24 +
SourceCode/Bond/BondEq/AccordionWnd.cpp | 16
SourceCode/Bond/Servo/AccordionWnd.h | 131 +++++
SourceCode/Bond/Servo/CPanelProduction.h | 5
SourceCode/Bond/Servo/CPageProdOverview.h | 37 +
SourceCode/Bond/Servo/Servo.vcxproj.filters | 8
SourceCode/Bond/Servo/AccordionWnd.cpp | 787 ++++++++++++++++++++++++++++++++
SourceCode/Bond/Servo/Servo.rc | 25 +
SourceCode/Bond/Servo/HmLabel.cpp | 177 +++++++
SourceCode/Bond/Servo/HmLabel.h | 33 +
14 files changed, 1,393 insertions(+), 9 deletions(-)
diff --git a/SourceCode/Bond/BondEq/AccordionWnd.cpp b/SourceCode/Bond/BondEq/AccordionWnd.cpp
index 5da6615..026628e 100644
--- a/SourceCode/Bond/BondEq/AccordionWnd.cpp
+++ b/SourceCode/Bond/BondEq/AccordionWnd.cpp
@@ -47,9 +47,16 @@
BOOL CAccordionWnd::RegisterWndClass()
{
- WNDCLASS wc;
+ WNDCLASS wcExisting = {};
+ HINSTANCE hInstance = AfxGetInstanceHandle();
+ if (::GetClassInfo(hInstance, ACCORDIONWND_CLASS, &wcExisting) ||
+ ::GetClassInfo(NULL, ACCORDIONWND_CLASS, &wcExisting)) {
+ return TRUE;
+ }
+
+ WNDCLASS wc = {};
wc.lpszClassName = ACCORDIONWND_CLASS;
- wc.hInstance = AfxGetInstanceHandle();
+ wc.hInstance = hInstance;
wc.lpfnWndProc = WindowProc;
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wc.hIcon = 0;
@@ -60,7 +67,10 @@
wc.cbWndExtra = 0;
// 注册自定义类
- return (::RegisterClass(&wc) != 0);
+ if (::RegisterClass(&wc) != 0) {
+ return TRUE;
+ }
+ return (::GetLastError() == ERROR_CLASS_ALREADY_EXISTS);
}
CAccordionWnd * CAccordionWnd::FromHandle(HWND hWnd)
diff --git a/SourceCode/Bond/Servo/AccordionWnd.cpp b/SourceCode/Bond/Servo/AccordionWnd.cpp
new file mode 100644
index 0000000..83af762
--- /dev/null
+++ b/SourceCode/Bond/Servo/AccordionWnd.cpp
@@ -0,0 +1,787 @@
+#include "stdafx.h"
+#include "AccordionWnd.h"
+
+
+#define ITEM_HEIGHT 32
+#define ITEM_SPACE 5
+#define TIMER_ID_CHECKHOVER 1
+#define EXPAND_ICON_WIDE 16
+
+#define BORDER 5
+#define SHADOWWIDE 5
+
+CAccordionWnd::CAccordionWnd()
+{
+ m_hWnd = NULL;
+ m_crFrame = GetSysColor(COLOR_WINDOWFRAME);
+ m_crBkgnd = RGB(255, 255, 255);//GetSysColor(COLOR_BTNFACE); ;
+ m_nPadding[PADDING_LEFT] = 5;
+ m_nPadding[PADDING_TOP] = 5;
+ m_nPadding[PADDING_RIGHT] = 5;
+ m_nPadding[PADDING_BOTTOM] = 5;
+ m_crItemBackground[0] = RGB(218, 218, 218);
+ m_crItemBackground[1] = RGB(34, 177, 76);
+ m_crItemFrame[0] = RGB(128, 128, 128);
+ m_crItemFrame[1] = RGB(128, 128, 128);
+ m_crItemText[0] = RGB(68, 84, 111);
+ m_crItemText[1] = RGB(0, 0, 0);
+ m_crSeparateLine = RGB(222, 222, 222);
+ m_crHoverItemBackground = RGB(244, 245, 247);
+ m_crHoverItemFrame = RGB(200, 222, 255);
+ m_hIconExpand = NULL;
+ m_hIconClose = NULL;
+ m_nHoverItem = -1;
+ m_nCheckHoverItem = -1;
+ m_bShadow = FALSE;
+ m_crShadowBkgnd = GetSysColor(COLOR_BTNFACE);
+}
+
+
+CAccordionWnd::~CAccordionWnd()
+{
+ for (size_t i = 0; i < m_vectorItems.size(); i++) {
+ delete m_vectorItems[i];
+ }
+ m_vectorItems.clear();
+}
+
+BOOL CAccordionWnd::RegisterWndClass()
+{
+ WNDCLASS wcExisting = {};
+ HINSTANCE hInstance = AfxGetInstanceHandle();
+ if (::GetClassInfo(hInstance, ACCORDIONWND_CLASS, &wcExisting) ||
+ ::GetClassInfo(NULL, ACCORDIONWND_CLASS, &wcExisting)) {
+ return TRUE;
+ }
+
+ WNDCLASS wc = {};
+ wc.lpszClassName = ACCORDIONWND_CLASS;
+ wc.hInstance = hInstance;
+ 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;
+
+ // 注册自定义类
+ if (::RegisterClass(&wc) != 0) {
+ return TRUE;
+ }
+ return (::GetLastError() == ERROR_CLASS_ALREADY_EXISTS);
+}
+
+CAccordionWnd* CAccordionWnd::FromHandle(HWND hWnd)
+{
+ CAccordionWnd* pAccordionWnd = (CAccordionWnd*)::GetProp(hWnd, ACCORDIONWND_TAG);
+ return pAccordionWnd;
+}
+
+CAccordionWnd* CAccordionWnd::Hook(HWND hWnd)
+{
+ CAccordionWnd* pAccordionWnd = (CAccordionWnd*)GetProp(hWnd, ACCORDIONWND_TAG);
+ if (pAccordionWnd == NULL) {
+ pAccordionWnd = new CAccordionWnd();
+ pAccordionWnd->m_hWnd = hWnd;
+
+ SetProp(hWnd, ACCORDIONWND_TAG, (HANDLE)pAccordionWnd);
+ }
+
+
+ return pAccordionWnd;
+}
+
+void CAccordionWnd::LoadExpandIcon(CString strExpandFile, CString strCloseFile)
+{
+ m_hIconExpand = (HICON)::LoadImage(AfxGetInstanceHandle(), strExpandFile, IMAGE_ICON, EXPAND_ICON_WIDE, EXPAND_ICON_WIDE,
+ LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+ m_hIconClose = (HICON)::LoadImage(AfxGetInstanceHandle(), strCloseFile, IMAGE_ICON, EXPAND_ICON_WIDE, EXPAND_ICON_WIDE,
+ LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+}
+
+void CAccordionWnd::Setpadding(int type, unsigned int nPadding)
+{
+ if (type >= PADDING_LEFT && PADDING_LEFT <= PADDING_BOTTOM) {
+ m_nPadding[type] = nPadding;
+ }
+}
+
+void CAccordionWnd::SetDefaultItemBackgroundColor(COLORREF crNormal, COLORREF crSel)
+{
+ m_crItemBackground[0] = crNormal;
+ m_crItemBackground[1] = crSel;
+}
+
+void CAccordionWnd::SetDefaultItemFrameColor(COLORREF crNormal, COLORREF crSel)
+{
+ m_crItemFrame[0] = crNormal;
+ m_crItemFrame[1] = crSel;
+}
+
+void CAccordionWnd::SetDefaultItemTextColor(COLORREF crNormal, COLORREF crSel)
+{
+ m_crItemText[0] = crNormal;
+ m_crItemText[1] = crSel;
+}
+
+void CAccordionWnd::Init()
+{
+}
+
+void CAccordionWnd::Release()
+{
+ // delete
+ delete this;
+}
+
+/*
+ * 添加项目
+ * pszName -- 名称
+ * pWnd -- 绑定的窗口
+ * nExpandHeight -- 展开高度,如果为0则自动设置为窗口高
+ */
+void CAccordionWnd::AddItem(char* pszName, CWnd* pWnd, int nExpandHeight, BOOL bExpand/* = TRUE*/, BOOL bEnable/* = TRUE*/)
+{
+ ACCORDIONITEM* pItem = new ACCORDIONITEM;
+ memset(pItem, 0, sizeof(ACCORDIONITEM));
+ pItem->pWnd = pWnd;
+ pItem->bExpand = bExpand;
+ pItem->bEnable = bEnable;
+ strcpy_s(pItem->text, sizeof(pItem->text), pszName);
+ if (nExpandHeight == 0) {
+ RECT rect;
+ pWnd->GetWindowRect(&rect);
+ pItem->nExpandHeight = rect.bottom - rect.top;
+ }
+ else if (nExpandHeight == -1) {
+ pItem->nExpandHeight = -1;
+ }
+ else {
+ pItem->nExpandHeight = nExpandHeight;
+ }
+ m_vectorItems.push_back(pItem);
+
+
+ // 重新调整个子窗口的位置
+ ResizeItemWnd();
+}
+
+void CAccordionWnd::ResizeItemWnd()
+{
+ RECT rcClient, rcItemClient;
+ GetClientRect(m_hWnd, &rcClient);
+
+ for (size_t i = 0; i < m_vectorItems.size(); i++) {
+ ACCORDIONITEM* pItem = m_vectorItems.at(i);
+ if (pItem->pWnd != NULL) {
+ GetItemRect(rcClient, (UINT)i, &rcItemClient);
+ rcItemClient.top += ITEM_HEIGHT;
+ if (pItem->nExpandHeight == -1) {
+ rcItemClient.bottom = rcClient.bottom;
+ }
+ else {
+ rcItemClient.bottom = rcItemClient.top + pItem->nExpandHeight;
+ }
+
+ pItem->pWnd->MoveWindow(&rcItemClient);
+ pItem->pWnd->ShowWindow(pItem->bExpand ? SW_SHOW : SW_HIDE);
+ }
+ }
+}
+
+BOOL CAccordionWnd::GetItemHeaderRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect)
+{
+ RECT rcItem;
+ if (!GetItemRect(rcClient, nIndex, &rcItem)) {
+ return FALSE;
+ }
+
+ rcItem.bottom = rcItem.top + ITEM_HEIGHT;
+ CopyRect(lpRect, &rcItem);
+ return TRUE;
+}
+
+BOOL CAccordionWnd::GetItemRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect)
+{
+ if (nIndex >= m_vectorItems.size()) {
+ return FALSE;
+ }
+
+ RECT rcItemHeader;
+ rcItemHeader.left = rcClient.left + m_nPadding[PADDING_LEFT];
+ rcItemHeader.right = rcClient.right - m_nPadding[PADDING_RIGHT];
+ rcItemHeader.top = rcClient.top + m_nPadding[PADDING_TOP];
+ rcItemHeader.bottom = rcItemHeader.top + ITEM_HEIGHT;
+ for (size_t i = 0; i < m_vectorItems.size(); i++) {
+ ACCORDIONITEM* pItem = m_vectorItems.at(i);
+ if (pItem->bExpand) {
+ rcItemHeader.bottom += pItem->nExpandHeight;
+ }
+
+ if (i == nIndex) {
+ break;;
+ }
+
+ rcItemHeader.top = rcItemHeader.bottom + ITEM_SPACE;
+ rcItemHeader.bottom = rcItemHeader.top + ITEM_HEIGHT;
+ }
+
+
+ CopyRect(lpRect, &rcItemHeader);
+ return TRUE;
+}
+
+int CAccordionWnd::HitTest(POINT pt, int& nHitTest)
+{
+ int nRet = -1;
+ nHitTest = -1;
+ RECT rcClient;
+ GetClientRect(m_hWnd, &rcClient);
+ if (PtInRect(&rcClient, pt)) {
+ nRet = 1;
+ }
+
+ int nItemIndex = -1;
+ RECT rcItemHeader;
+ for (size_t i = 0; i < m_vectorItems.size(); i++) {
+ GetItemHeaderRect(rcClient, (unsigned int)i, &rcItemHeader);
+
+ if (PtInRect(&rcItemHeader, pt)) {
+ nItemIndex = (unsigned int)i;
+
+ break;
+ }
+ }
+
+ if (nItemIndex != -1) {
+ nRet = 2;
+ nHitTest = nItemIndex;
+ }
+
+ return nRet;
+}
+
+BOOL CAccordionWnd::Togle(unsigned int nIndex)
+{
+ if (nIndex >= m_vectorItems.size()) {
+ return FALSE;
+ }
+
+ ACCORDIONITEM* pItem = m_vectorItems[nIndex];
+ pItem->bExpand = !pItem->bExpand;
+
+
+ // 重新调整个子窗口的位置
+ ResizeItemWnd();
+
+ RECT rcClient;
+ GetClientRect(m_hWnd, &rcClient);
+ ::InvalidateRect(m_hWnd, &rcClient, TRUE);
+
+ return TRUE;
+}
+
+void CAccordionWnd::Notify(int nCode, int dwData, int dwData1/* = 0*/, int dwData2/* = 0*/)
+{
+ HWND hParent;
+ hParent = GetParent(m_hWnd);
+ if (hParent != NULL) {
+ ACCORDION_NMHDR accordionWndnmhdr;
+ accordionWndnmhdr.nmhdr.hwndFrom = m_hWnd;
+ accordionWndnmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID);
+ accordionWndnmhdr.nmhdr.code = nCode;
+ accordionWndnmhdr.dwData = dwData;
+ accordionWndnmhdr.dwData1 = dwData1;
+ accordionWndnmhdr.dwData2 = dwData2;
+ SendMessage(hParent, WM_NOTIFY, (WPARAM)accordionWndnmhdr.nmhdr.idFrom, (LPARAM)&accordionWndnmhdr);
+ }
+}
+
+/*
+ * 拦截窗口消息函数
+ */
+LRESULT CALLBACK CAccordionWnd::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ CAccordionWnd* pAccordionWnd = (CAccordionWnd*)GetProp(hWnd, ACCORDIONWND_TAG);
+ if (pAccordionWnd == NULL && uMsg != WM_NCCREATE)
+ {
+ return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
+ }
+
+
+ // 如果Hook则响应消息
+ ASSERT(hWnd);
+ switch (uMsg)
+ {
+ case WM_NCCREATE:
+ return CAccordionWnd::OnNcCreate(hWnd, wParam, lParam);
+
+ case WM_DESTROY:
+ return pAccordionWnd->OnDestroy(wParam, lParam);
+
+ case WM_NCCALCSIZE:
+ return pAccordionWnd->OnNcCalcsize(wParam, lParam);
+
+ case WM_NCPAINT:
+ return pAccordionWnd->OnNcPaint(wParam, lParam);
+
+ case WM_PAINT:
+ return pAccordionWnd->OnPaint(wParam, lParam);
+
+ case WM_TIMER:
+ return pAccordionWnd->OnTimer(wParam, lParam);
+
+ case WM_MOUSEMOVE:
+ return pAccordionWnd->OnMouseMove(wParam, lParam);
+
+ case WM_LBUTTONDOWN:
+ return pAccordionWnd->OnLButtonDown(wParam, lParam);
+
+ case WM_LBUTTONUP:
+ return pAccordionWnd->OnLButtonUp(wParam, lParam);
+
+ case WM_MOUSEWHEEL:
+ return pAccordionWnd->OnMouseWheel(wParam, lParam);
+
+ case WM_SIZE:
+ return pAccordionWnd->OnSize(wParam, lParam);
+
+ case WM_GETDLGCODE:
+ return DLGC_WANTALLKEYS;
+
+ default:
+ break;
+ }
+
+ return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+/*
+ * WM_NCCREATE
+ * 窗口创建前的初始化工作
+ */
+LRESULT CAccordionWnd::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ CAccordionWnd* pAccordionWnd = (CAccordionWnd*)GetProp(hWnd, ACCORDIONWND_TAG);
+ ASSERT(pAccordionWnd == NULL);
+
+ Hook(hWnd);
+ return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam);
+}
+
+/*
+ * WM_NCCALCSIZE
+ */
+LRESULT CAccordionWnd::OnNcCalcsize(WPARAM wParam, LPARAM lParam)
+{
+ if (!m_bShadow) {
+ return ::DefWindowProc(m_hWnd, WM_NCCALCSIZE, wParam, lParam);
+ }
+
+
+ LPRECT lprcWnd = (LPRECT)lParam;
+ lprcWnd->left += BORDER;
+ lprcWnd->top += BORDER;
+ lprcWnd->right -= (BORDER + SHADOWWIDE);
+ lprcWnd->bottom -= (BORDER + SHADOWWIDE);
+
+ return 0;
+}
+
+/*
+ * WM_DESTROY
+ * 窗口销毁时
+ */
+LRESULT CAccordionWnd::OnDestroy(WPARAM wParam, LPARAM lParam)
+{
+ Release();
+ return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam);
+}
+
+
+/*
+ * WM_TIMER
+ */
+LRESULT CAccordionWnd::OnTimer(WPARAM wParam, LPARAM lParam)
+{
+ int nTimerId = (int)wParam;
+ if (m_nTimerId == nTimerId) {
+
+ POINT pt;
+ ::GetCursorPos(&pt);
+ ::ScreenToClient(m_hWnd, &pt);
+
+ int nRet, nHitTest;
+ nRet = HitTest(pt, nHitTest);
+ if (m_nCheckHoverItem != nHitTest) {
+ KillTimer(m_hWnd, m_nTimerId);
+ m_nHoverItem = nHitTest;
+ m_nCheckHoverItem = nHitTest;
+
+ RECT rcClient;
+ GetClientRect(m_hWnd, &rcClient);
+ ::InvalidateRect(m_hWnd, &rcClient, TRUE);
+ }
+ }
+
+
+ return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam);
+}
+
+/*
+ * WM_MOUSEMOVE
+ * 鼠标移动时,检测鼠标位置并回调给主窗口
+ */
+LRESULT CAccordionWnd::OnMouseMove(WPARAM wParam, LPARAM lParam)
+{
+ POINT pt;
+ pt.x = (int)LOWORD(lParam);
+ pt.y = (int)HIWORD(lParam);
+
+ int nRet, nHitTest;
+ nRet = HitTest(pt, nHitTest);
+
+ if (nRet == 2) {
+ ACCORDIONITEM* pItem = m_vectorItems[nHitTest];
+ if (pItem != NULL && pItem->bEnable) {
+ ::SetCursor(LoadCursor(NULL, IDC_HAND));
+ }
+ }
+ else {
+ ::SetCursor(LoadCursor(NULL, IDC_ARROW));
+ }
+
+ int nLastItem = m_nHoverItem;
+ if (m_nHoverItem != nHitTest) {
+ m_nHoverItem = nHitTest;
+
+ RECT rcClient, rcLastItemClient, rcCurItemClient;
+ GetClientRect(m_hWnd, &rcClient);
+ GetItemRect(rcClient, nLastItem, &rcLastItemClient);
+ ::InvalidateRect(m_hWnd, &rcLastItemClient, nHitTest < 0);
+
+ if (nHitTest >= 0) {
+ ACCORDIONITEM* pItem = m_vectorItems.at(nHitTest);
+ if (!pItem->bEnable) {
+ m_nHoverItem = -1;
+ }
+ else {
+ KillTimer(m_hWnd, m_nTimerId);
+ m_nTimerId = SetTimer(m_hWnd, TIMER_ID_CHECKHOVER, 200, NULL);
+ m_nCheckHoverItem = m_nHoverItem;
+
+ GetItemRect(rcClient, m_nHoverItem, &rcCurItemClient);
+ ::InvalidateRect(m_hWnd, &rcCurItemClient, TRUE);
+ }
+ }
+ }
+
+
+ return ::DefWindowProc(m_hWnd, WM_MOUSEMOVE, wParam, lParam);
+}
+
+/*
+ * WM_LBUTTONDOWN
+ * 鼠标左键下压
+ */
+LRESULT CAccordionWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam)
+{
+ POINT pt;
+ pt.x = (int)LOWORD(lParam);
+ pt.y = (int)HIWORD(lParam);
+
+ int nRet, nHitTest;
+ nRet = HitTest(pt, nHitTest);
+
+ if (nRet == 2) {
+ ACCORDIONITEM* pItem = m_vectorItems[nHitTest];
+ if (pItem != NULL && pItem->bEnable) {
+ ::SetCursor(LoadCursor(NULL, IDC_HAND));
+ }
+ }
+ else {
+ ::SetCursor(LoadCursor(NULL, IDC_ARROW));
+ }
+
+
+ return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam);
+}
+
+/*
+ * WM_LBUTTONUP
+ * 鼠标左键释放
+ */
+LRESULT CAccordionWnd::OnLButtonUp(WPARAM wParam, LPARAM lParam)
+{
+ POINT pt;
+ pt.x = (int)LOWORD(lParam);
+ pt.y = (int)HIWORD(lParam);
+
+ int nRet, nHitTest;
+ nRet = HitTest(pt, nHitTest);
+
+ if (nRet == 2) {
+ ACCORDIONITEM* pItem = m_vectorItems[nHitTest];
+ if (pItem != NULL && pItem->bEnable) {
+ ::SetCursor(LoadCursor(NULL, IDC_HAND));
+ Togle(nHitTest);
+ }
+ }
+ else {
+ ::SetCursor(LoadCursor(NULL, IDC_ARROW));
+ }
+
+
+ return ::DefWindowProc(m_hWnd, WM_LBUTTONUP, wParam, lParam);
+}
+
+/*
+ * WM_MOUSEWHEEL
+ * 鼠标滚轮滚动时,缩放图像
+ */
+LRESULT CAccordionWnd::OnMouseWheel(WPARAM wParam, LPARAM lParam)
+{
+ return ::DefWindowProc(m_hWnd, WM_MOUSEWHEEL, wParam, lParam);
+}
+
+/*
+ * WM_NCPAINT
+ */
+LRESULT CAccordionWnd::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 rcWindow, rcClient;
+ GetClientRect(m_hWnd, &rcClient);
+ ::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.left);
+ ::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.right);
+ GetWindowRect(m_hWnd, &rcWindow);
+ ::OffsetRect(&rcClient, -rcWindow.left, -rcWindow.top);
+ ::OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
+
+ HRGN hRgnWnd = CreateRectRgnIndirect(&rcWindow);
+ HRGN hRgnClient = CreateRectRgnIndirect(&rcClient);
+
+ HDC hDC = GetWindowDC(m_hWnd);
+ ::SelectClipRgn(hDC, hRgnWnd);
+ ::ExtSelectClipRgn(hDC, hRgnClient, RGN_DIFF);
+
+
+ // 没有阴影的边框
+ if (!m_bShadow) {
+ HBRUSH hBrushBK, hBrushFrame;
+ hBrushBK = CreateSolidBrush(m_crBkgnd);
+ ::FillRect(hDC, &rcWindow, hBrushBK);
+ DeleteObject(hBrushBK);
+
+ hBrushFrame = CreateSolidBrush(m_crFrame);
+ ::FrameRect(hDC, &rcWindow, hBrushFrame);
+ DeleteObject(hBrushFrame);
+ }
+
+ // 有阴影的边框
+ else {
+
+ RECT rcFrame0, rcFrame1;
+ rcFrame0.left = rcWindow.left + SHADOWWIDE;
+ rcFrame0.top = rcWindow.top + SHADOWWIDE;
+ rcFrame0.right = rcWindow.right;
+ rcFrame0.bottom = rcWindow.bottom;
+ rcFrame1.left = rcWindow.left;
+ rcFrame1.top = rcWindow.top;
+ rcFrame1.right = rcWindow.right - SHADOWWIDE;
+ rcFrame1.bottom = rcWindow.bottom - SHADOWWIDE;
+
+
+ // 背景框和对话框(父窗体)背景色一致
+ HBRUSH hBrushBK, hBrushFrame;
+ hBrushBK = CreateSolidBrush(m_crShadowBkgnd);
+ ::FillRect(hDC, &rcWindow, hBrushBK);
+ DeleteObject(hBrushBK);
+
+
+ // 阴影框
+ BYTE r = GetRValue(m_crShadowBkgnd);
+ BYTE g = GetGValue(m_crShadowBkgnd);
+ BYTE b = GetBValue(m_crShadowBkgnd);
+ BYTE rstep = (r - GetRValue(m_crFrame)) / SHADOWWIDE;
+ BYTE gstep = (r - GetGValue(m_crFrame)) / SHADOWWIDE;
+ BYTE bstep = (r - GetBValue(m_crFrame)) / SHADOWWIDE;
+
+ for (int i = 0; i < SHADOWWIDE; i++) {
+ hBrushBK = CreateSolidBrush(RGB(r - i * rstep, g - i * gstep, b - i * bstep));
+ ::FillRect(hDC, &rcFrame0, hBrushBK);
+ DeleteObject(hBrushBK);
+ rcFrame0.bottom -= 1;
+ rcFrame0.right -= 1;
+ }
+
+
+ // 前景框
+ hBrushBK = CreateSolidBrush(m_crBkgnd);
+ ::FillRect(hDC, &rcFrame1, hBrushBK);
+ DeleteObject(hBrushBK);
+
+ hBrushFrame = CreateSolidBrush(m_crFrame);
+ ::FrameRect(hDC, &rcFrame1, hBrushFrame);
+ DeleteObject(hBrushFrame);
+ }
+
+
+ ::DeleteObject(hRgnWnd);
+ ::DeleteObject(hRgnClient);
+ ReleaseDC(m_hWnd, hDC);
+ }
+
+ return lRet;
+}
+
+/*
+ * WM_PAINT
+ */
+LRESULT CAccordionWnd::OnPaint(WPARAM wParam, LPARAM lParam)
+{
+ HDC hDC, hMemDC;
+ HBITMAP hBitmap;
+ RECT rcClient;
+ CString strText;
+ HFONT hFont;
+ 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);
+
+
+ // 背景颜色
+ hBrushBK = CreateSolidBrush(m_crBkgnd);
+ ::FillRect(hMemDC, &rcClient, hBrushBK);
+ DeleteObject(hBrushBK);
+
+
+ // 绘子项列表
+ hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+ ::SelectObject(hMemDC, hFont);
+
+ HPEN hPenSeparate = ::CreatePen(PS_SOLID, 1, m_crSeparateLine);
+ RECT rcItem, rcItemHeader;
+ for (size_t i = 0; i < m_vectorItems.size(); i++) {
+ ACCORDIONITEM* pItem = m_vectorItems[i];
+ GetItemRect(rcClient, (UINT)i, &rcItem);
+ GetItemHeaderRect(rcClient, (UINT)i, &rcItemHeader);
+
+
+ // 热点项的背景色和边框
+ if (m_nHoverItem == (int)i) {
+ HBRUSH hbrItemHeaderBackground = CreateSolidBrush(m_crHoverItemBackground);
+ HBRUSH hbrItemFrame = CreateSolidBrush(m_crHoverItemFrame);
+
+ HRGN hRgn = CreateRoundRectRgn(rcItemHeader.left, rcItemHeader.top, rcItemHeader.right, rcItemHeader.bottom, 2, 2);
+ ::FillRgn(hMemDC, hRgn, hbrItemHeaderBackground);
+ ::FrameRgn(hMemDC, hRgn, hbrItemFrame, 1, 1);
+ ::DeleteObject(hbrItemHeaderBackground);
+ ::DeleteObject(hbrItemFrame);
+ ::DeleteObject(hRgn);
+ }
+
+
+ // 箭头
+ BOOL bDrawIcon = DrawIconEx(hMemDC, rcItemHeader.left + (ITEM_HEIGHT - EXPAND_ICON_WIDE) / 2, rcItemHeader.top + (ITEM_HEIGHT - EXPAND_ICON_WIDE) / 2,
+ pItem->bExpand ? m_hIconExpand : m_hIconClose, EXPAND_ICON_WIDE, EXPAND_ICON_WIDE, 0, 0, DI_NORMAL);
+
+
+ // 文本
+ ::SetTextColor(hMemDC, m_nHoverItem == (int)i ? m_crItemText[1] : m_crItemText[0]);
+ RECT rcText;
+ rcText.left = rcItemHeader.left + (bDrawIcon ? ITEM_HEIGHT : (ITEM_HEIGHT - EXPAND_ICON_WIDE) / 2);
+ rcText.top = rcItemHeader.top;
+ rcText.right = rcItemHeader.right;
+ rcText.bottom = rcItemHeader.bottom;
+ ::DrawText(hMemDC, pItem->text, (int)strlen(pItem->text), &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+
+
+ // 文本右边分隔线
+ SIZE sizeText;
+ GetTextExtentPoint32(hMemDC, pItem->text, (int)strlen(pItem->text), &sizeText);
+
+
+ HPEN hOldPen = (HPEN)::SelectObject(hMemDC, hPenSeparate);
+ MoveToEx(hMemDC, rcText.left + sizeText.cx + 10, rcItemHeader.top + (rcItemHeader.bottom - rcItemHeader.top - 1) / 2, NULL);
+ LineTo(hMemDC, rcItemHeader.right - 10, rcItemHeader.top + (rcItemHeader.bottom - rcItemHeader.top - 1) / 2);
+ ::SelectObject(hMemDC, hOldPen);
+
+
+ rcItemHeader.top = rcItemHeader.bottom + ITEM_SPACE;
+ rcItemHeader.bottom = rcItemHeader.top + ITEM_HEIGHT;
+ }
+ ::DeleteObject(hPenSeparate);
+
+
+ // 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 CAccordionWnd::OnSize(WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lRet = ::DefWindowProc(m_hWnd, WM_SIZE, wParam, lParam);
+
+ ResizeItemWnd();
+
+ return lRet;
+}
+
+/*
+ * 设置背景色
+ * color -- 背景色
+ */
+void CAccordionWnd::SetBkgndColor(COLORREF color)
+{
+ m_crBkgnd = color;
+}
+
+
+/*
+ * 设置阴影的背景色(即父窗口的背景)
+ * color -- 背景色
+ */
+void CAccordionWnd::SetShadowBkgnd(COLORREF color)
+{
+ m_crShadowBkgnd = color;
+}
+
+/*
+ * 设置边框颜色
+ * color -- 边框颜色
+ */
+void CAccordionWnd::SetFrameColor(COLORREF color, BOOL bShadow/* = FALSE*/)
+{
+ m_crFrame = color;
+ m_bShadow = bShadow;
+ SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
+}
+
diff --git a/SourceCode/Bond/Servo/AccordionWnd.h b/SourceCode/Bond/Servo/AccordionWnd.h
new file mode 100644
index 0000000..46fa7a1
--- /dev/null
+++ b/SourceCode/Bond/Servo/AccordionWnd.h
@@ -0,0 +1,131 @@
+#pragma once
+#include <functional>
+#include <vector>
+
+#ifndef ACCORDIONWND_TAG
+
+#ifdef _WIN32
+
+#define ACCORDIONWND_CLASSA "AccordionWnd"
+#define ACCORDIONWND_CLASSW L"AccordionWnd"
+
+#ifdef UNICODE
+#define ACCORDIONWND_CLASS ACCORDIONWND_CLASSW
+#else
+#define ACCORDIONWND_CLASS ACCORDIONWND_CLASSA
+#endif
+
+#else
+#define ACCORDIONWND_CLASS "AccordionWnd"
+#endif
+
+
+#define ACCORDIONWND_TAG _T("ACCORDIONWND_TAG")
+
+#define ACCORDIONWND_FIRST (0U-3590U)
+#define ACCORDIONWND_LAST (0U-5350U)
+#define ACCORDIONWND_ONTOGLE (ACCORDIONWND_FIRST - 1)
+
+typedef struct tagACCORDION_NMHDR
+{
+ NMHDR nmhdr;
+ DWORD dwData;
+ DWORD dwData1;
+ DWORD dwData2;
+} ACCORDION_NMHDR;
+
+typedef struct tagACCORDIONITEM
+{
+ unsigned int id;
+ int nExpandHeight;
+ COLORREF crBackground[2];
+ COLORREF crFrame[2];
+ COLORREF crText[2];
+ char text[256];
+ CWnd *pWnd;
+ BOOL bExpand;
+ BOOL bEnable; // 是否可以点击展开和收起
+} ACCORDIONITEM;
+
+#endif
+
+#define PADDING_LEFT 0
+#define PADDING_TOP 1
+#define PADDING_RIGHT 2
+#define PADDING_BOTTOM 3
+
+class CAccordionWnd
+{
+public:
+ CAccordionWnd();
+ ~CAccordionWnd();
+
+
+public:
+ static BOOL RegisterWndClass();
+ static CAccordionWnd * FromHandle(HWND hWnd);
+ void SetFrameColor(COLORREF color, BOOL bShadow = FALSE);
+ void SetBkgndColor(COLORREF color);
+ void SetShadowBkgnd(COLORREF color);
+
+public:
+ void LoadExpandIcon(CString strExpandFile, CString strCloseFile);
+ void Setpadding(int type, unsigned int nPadding);
+ void SetDefaultItemBackgroundColor(COLORREF crNormal, COLORREF crSel);
+ void SetDefaultItemFrameColor(COLORREF crNormal, COLORREF crSel);
+ void SetDefaultItemTextColor(COLORREF crNormal, COLORREF crSel);
+ void AddItem(char *pszName, CWnd *pWnd, int nExpandHeight, BOOL bExpand = TRUE, BOOL bEnable = TRUE);
+ BOOL Togle(unsigned int nIndex);
+ int GetItemHeaderHeight();
+ BOOL IsExpand(unsigned int nIndex);
+
+private:
+ void Init();
+ void Notify(int nCode, int dwData, int dwData1 = 0, int dwData2 = 0);
+ void Release();
+ void ResizeItemWnd();
+ static CAccordionWnd* 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 OnNcCalcsize(WPARAM wParam, LPARAM lParam);
+ LRESULT OnPaint(WPARAM wParam, LPARAM lParam);
+ LRESULT OnMouseMove(WPARAM wParam, LPARAM lParam);
+ LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam);
+ LRESULT OnLButtonUp(WPARAM wParam, LPARAM lParam);
+ LRESULT OnMouseWheel(WPARAM wParam, LPARAM lParam);
+ LRESULT OnSize(WPARAM wParam, LPARAM lParam);
+
+private:
+ HWND m_hWnd;
+ COLORREF m_crBkgnd;
+ COLORREF m_crFrame;
+ HICON m_hIconClose;
+ HICON m_hIconExpand;
+ int m_nHoverItem;
+ int m_nCheckHoverItem;
+ BOOL m_bShadow; // 阴影
+ COLORREF m_crShadowBkgnd; // 阴影背景色(即父窗口的颜色)
+
+private:
+ unsigned int m_nPadding[4];
+ COLORREF m_crItemBackground[2];
+ COLORREF m_crItemFrame[2];
+ COLORREF m_crItemText[2];
+ COLORREF m_crSeparateLine;
+ COLORREF m_crHoverItemBackground;
+ COLORREF m_crHoverItemFrame;
+ CString m_strExpandIconFilepath[2];
+
+private:
+ std::vector<ACCORDIONITEM *> m_vectorItems;
+ int m_nTimerId;
+
+private:
+ int HitTest(POINT pt, int &nHitTest);
+ BOOL GetItemHeaderRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect);
+ BOOL GetItemRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect);
+};
+
diff --git a/SourceCode/Bond/Servo/CPageProdOverview.cpp b/SourceCode/Bond/Servo/CPageProdOverview.cpp
new file mode 100644
index 0000000..6ca851e
--- /dev/null
+++ b/SourceCode/Bond/Servo/CPageProdOverview.cpp
@@ -0,0 +1,140 @@
+锘�// CPageProOverview.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "Servo.h"
+#include "CPageProdOverview.h"
+#include "afxdialogex.h"
+
+namespace
+{
+ constexpr UINT_PTR kTimerRefreshId = 2001;
+ constexpr UINT kTimerRefreshIntervalMs = 5000;
+}
+
+IMPLEMENT_DYNAMIC(CPageProdOverview, CDialogEx)
+
+CPageProdOverview::CPageProdOverview(CWnd* pParent /*=nullptr*/)
+ : CDialogEx(IDD_PROD_OVERVIEW, pParent)
+ , m_clrBackground(RGB(240, 240, 240))
+{
+}
+
+CPageProdOverview::~CPageProdOverview()
+{
+}
+
+void CPageProdOverview::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+}
+
+void CPageProdOverview::SetBackgroundColor(COLORREF color)
+{
+ m_clrBackground = color;
+ m_brushBackground.DeleteObject();
+ m_brushBackground.CreateSolidBrush(m_clrBackground);
+ if (::IsWindow(m_hWnd)) {
+ Invalidate();
+ }
+}
+
+BEGIN_MESSAGE_MAP(CPageProdOverview, CDialogEx)
+ ON_WM_CTLCOLOR()
+ ON_WM_DESTROY()
+ ON_WM_SIZE()
+ ON_WM_TIMER()
+END_MESSAGE_MAP()
+
+BOOL CPageProdOverview::OnInitDialog()
+{
+ CDialogEx::OnInitDialog();
+
+
+ // 浣跨敤鑷畾涔夋爣绛�
+ if (CWnd* pDay = GetDlgItem(IDC_PROD_DAY_OUTPUT)) {
+ m_labelDayOut.SubclassWindow(pDay->GetSafeHwnd());
+ m_labelDayOut.setFontSize(28);
+ m_labelDayOut.setNoteTextColor(RGB(128, 128, 128));
+ m_labelDayOut.setNote1(_T("鐧界彮浜у嚭"));
+ m_labelDayOut.setBackground(m_clrBackground);
+ m_labelDayOut.setForeground(RGB(18, 18, 18), TRUE);
+ }
+ if (CWnd* pNight = GetDlgItem(IDC_PROD_NIGHT_OUTPUT)) {
+ m_labelNightOut.SubclassWindow(pNight->GetSafeHwnd());
+ m_labelNightOut.setFontSize(28);
+ m_labelNightOut.setNoteTextColor(RGB(128, 128, 128));
+ m_labelNightOut.setNote1(_T("澶滅彮浜у嚭"));
+ m_labelNightOut.setBackground(m_clrBackground);
+ m_labelNightOut.setForeground(RGB(18, 18, 18), TRUE);
+ }
+ if (CWnd* pDayTakt = GetDlgItem(IDC_PROD_DAY_TAKT)) {
+ m_labelDayTakt.SubclassWindow(pDayTakt->GetSafeHwnd());
+ m_labelDayTakt.setFontSize(28);
+ m_labelDayTakt.setNoteTextColor(RGB(128, 128, 128));
+ m_labelDayTakt.setNote1(_T("鐧界彮骞冲潎TT"));
+ m_labelDayTakt.setBackground(m_clrBackground);
+ m_labelDayTakt.setForeground(RGB(18, 18, 18), TRUE);
+ }
+ if (CWnd* pNightTakt = GetDlgItem(IDC_PROD_NIGHT_TAKT)) {
+ m_labelNightTakt.SubclassWindow(pNightTakt->GetSafeHwnd());
+ m_labelNightTakt.setFontSize(28);
+ m_labelNightTakt.setNoteTextColor(RGB(128, 128, 128));
+ m_labelNightTakt.setNote1(_T("澶滅彮骞冲潎TT"));
+ m_labelNightTakt.setBackground(m_clrBackground);
+ m_labelNightTakt.setForeground(RGB(18, 18, 18), TRUE);
+ }
+
+ RefreshData();
+ m_timerId = SetTimer(kTimerRefreshId, kTimerRefreshIntervalMs, nullptr);
+ return TRUE;
+}
+
+HBRUSH CPageProdOverview::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+ HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+ if (nCtlColor == CTLCOLOR_DLG || nCtlColor == CTLCOLOR_STATIC) {
+ if (m_brushBackground.GetSafeHandle() == NULL) {
+ m_brushBackground.CreateSolidBrush(m_clrBackground);
+ }
+ pDC->SetBkMode(TRANSPARENT);
+ return (HBRUSH)m_brushBackground.GetSafeHandle();
+ }
+
+ return hbr;
+}
+
+void CPageProdOverview::OnDestroy()
+{
+ if (m_timerId != 0) {
+ KillTimer(m_timerId);
+ m_timerId = 0;
+ }
+ CDialogEx::OnDestroy();
+}
+
+void CPageProdOverview::OnSize(UINT nType, int cx, int cy)
+{
+ CDialogEx::OnSize(nType, cx, cy);
+}
+
+void CPageProdOverview::OnTimer(UINT_PTR nIDEvent)
+{
+ if (nIDEvent == kTimerRefreshId) {
+ RefreshData();
+ }
+ CDialogEx::OnTimer(nIDEvent);
+}
+
+void CPageProdOverview::RefreshData()
+{
+ CString text;
+ text.Format(_T("%d"), 123);
+ m_labelDayOut.setText(text);
+ text.Format(_T("%d"), 1235);
+ m_labelNightOut.setText(text);
+
+ m_labelDayTakt.setText(_T("1236"));
+ m_labelNightTakt.setText(_T("1238"));
+}
diff --git a/SourceCode/Bond/Servo/CPageProdOverview.h b/SourceCode/Bond/Servo/CPageProdOverview.h
new file mode 100644
index 0000000..6198d90
--- /dev/null
+++ b/SourceCode/Bond/Servo/CPageProdOverview.h
@@ -0,0 +1,37 @@
+锘�#pragma once
+#include <chrono>
+#include "HmLabel.h"
+
+// CPageProOverview 瀵硅瘽妗�
+class CPageProdOverview : public CDialogEx
+{
+ DECLARE_DYNAMIC(CPageProdOverview)
+
+public:
+ CPageProdOverview(CWnd* pParent = nullptr); // 鏍囧噯鏋勯�犲嚱鏁�
+ virtual ~CPageProdOverview();
+ void SetBackgroundColor(COLORREF color);
+
+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);
+
+private:
+ void RefreshData();
+
+private:
+ COLORREF m_clrBackground{ RGB(240, 240, 240) };
+ CBrush m_brushBackground;
+ UINT_PTR m_timerId = 0;
+ CHmLabel m_labelDayOut;
+ CHmLabel m_labelNightOut;
+ CHmLabel m_labelDayTakt;
+ CHmLabel m_labelNightTakt;
+};
diff --git a/SourceCode/Bond/Servo/CPanelProduction.cpp b/SourceCode/Bond/Servo/CPanelProduction.cpp
index bbc5900..814a631 100644
--- a/SourceCode/Bond/Servo/CPanelProduction.cpp
+++ b/SourceCode/Bond/Servo/CPanelProduction.cpp
@@ -22,6 +22,8 @@
m_hPlaceholder = nullptr;
m_bShiftSummaryValid = FALSE;
m_pStatsThread = nullptr;
+ m_pAccordionWnd = nullptr;
+ m_pPageProdOverview = nullptr;
}
CPanelProduction::~CPanelProduction()
@@ -61,6 +63,25 @@
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();
@@ -107,6 +128,9 @@
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
diff --git a/SourceCode/Bond/Servo/CPanelProduction.h b/SourceCode/Bond/Servo/CPanelProduction.h
index 527db4f..cbf285f 100644
--- a/SourceCode/Bond/Servo/CPanelProduction.h
+++ b/SourceCode/Bond/Servo/CPanelProduction.h
@@ -1,8 +1,9 @@
锘�#pragma once
#include "BlButton.h"
#include <afxmt.h>
-
+#include "AccordionWnd.h"
#include "ProductionStats.h"
+#include "CPageProdOverview.h"
// CPanelProduction dialog
class CPanelProduction : public CDialogEx
@@ -21,6 +22,7 @@
int m_nPanelWidth;
CBlButton m_btnClose;
HWND m_hPlaceholder;
+ CAccordionWnd* m_pAccordionWnd;
// Production shift summary (updated by background thread)
ProductionShiftSummary m_shiftSummary;
@@ -28,6 +30,7 @@
CCriticalSection m_csShiftSummary;
CWinThread* m_pStatsThread;
CEvent m_evStopStats;
+ CPageProdOverview* m_pPageProdOverview;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
diff --git a/SourceCode/Bond/Servo/HmLabel.cpp b/SourceCode/Bond/Servo/HmLabel.cpp
new file mode 100644
index 0000000..c60cacb
--- /dev/null
+++ b/SourceCode/Bond/Servo/HmLabel.cpp
@@ -0,0 +1,177 @@
+#include "stdafx.h"
+#include "HmLabel.h"
+
+
+CHmLabel::CHmLabel()
+{
+ m_crFrame = RGB(128, 128, 128);
+ m_crBackground = RGB(255, 0, 0);
+ m_crForeground = RGB(255, 255, 255);
+ m_hFont = NULL;
+ m_hFontNote = NULL;
+}
+
+
+CHmLabel::~CHmLabel()
+{
+ if (m_hFont != NULL) {
+ ::DeleteObject(m_hFont);
+ m_hFont = NULL;
+ }
+
+ if (m_hFontNote != NULL) {
+ ::DeleteObject(m_hFontNote);
+ m_hFontNote = NULL;
+ }
+}
+
+BEGIN_MESSAGE_MAP(CHmLabel, CStatic)
+ ON_WM_PAINT()
+ ON_WM_NCPAINT()
+END_MESSAGE_MAP()
+
+void CHmLabel::setText(CString strText)
+{
+ SetWindowText(strText);
+ Invalidate();
+}
+
+void CHmLabel::setNote1(CString strNote1)
+{
+ m_strNote1 = strNote1;
+}
+
+void CHmLabel::setFontSize(int size)
+{
+ if (m_hFont != NULL) {
+ ::DeleteObject(m_hFont);
+ m_hFont = NULL;
+ }
+
+ m_hFont = CreateFont(size, 0, 0, 0, FW_MEDIUM,
+ FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS,
+ CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, _T("宋体"));
+}
+
+void CHmLabel::setNoteFontSize(int size)
+{
+ if (m_hFontNote != NULL) {
+ ::DeleteObject(m_hFontNote);
+ m_hFontNote = NULL;
+ }
+
+ m_hFontNote = CreateFont(size, 0, 0, 0, FW_MEDIUM,
+ FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS,
+ CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, _T("宋体"));
+}
+
+void CHmLabel::setNoteTextColor(COLORREF color, BOOL bInvalidate/* = FALSE*/)
+{
+ m_crNote = color;
+ if (bInvalidate) Invalidate(TRUE);
+}
+
+void CHmLabel::setBackground(COLORREF color, BOOL bInvalidate/* = FALSE*/)
+{
+ m_crBackground = color;
+ if (bInvalidate) Invalidate(TRUE);
+}
+
+void CHmLabel::setForeground(COLORREF color, BOOL bInvalidate/* = FALSE*/)
+{
+ m_crForeground = color;
+ if (bInvalidate) Invalidate(TRUE);
+}
+
+void CHmLabel::OnPaint()
+{
+ CPaintDC dc(this); // device context for painting
+ // TODO: 在此处添加消息处理程序代码
+ // 不为绘图消息调用 CStatic::OnPaint()
+
+
+ HDC hMemDC;
+ HBITMAP hBitmap;
+ RECT rcClient;
+ CString strText;
+ HBRUSH hBrushBK;
+
+
+ GetClientRect(&rcClient);
+ hMemDC = ::CreateCompatibleDC(dc.m_hDC);
+ hBitmap = ::CreateCompatibleBitmap(dc.m_hDC, rcClient.right - rcClient.left,
+ rcClient.bottom - rcClient.top);
+ ::SelectObject(hMemDC, hBitmap);
+
+
+ // 背景颜色
+ hBrushBK = CreateSolidBrush(m_crBackground);
+ ::FillRect(hMemDC, &rcClient, hBrushBK);
+ DeleteObject(hBrushBK);
+
+
+ // 文字
+ char szText[256];
+ GetWindowText(szText, 256);
+ RECT rcText = rcClient;
+ SetBkMode(hMemDC, TRANSPARENT);
+ SetTextColor(hMemDC, m_crForeground);
+ ::SelectObject(hMemDC, m_hFont == NULL ? (HFONT)GetStockObject(DEFAULT_GUI_FONT) : m_hFont);
+ ::DrawTextA(hMemDC, szText, (int)strlen(szText), &rcText, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
+
+
+ // Note1
+ SetTextColor(hMemDC, m_crNote);
+ ::SelectObject(hMemDC, m_hFontNote == NULL ? (HFONT)GetStockObject(DEFAULT_GUI_FONT) : m_hFontNote);
+ ::DrawText(hMemDC, m_strNote1, m_strNote1.GetLength(), &rcClient, DT_CENTER | DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS);
+
+
+ // EndPaint
+ ::BitBlt(dc.m_hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
+ hMemDC, 0, 0, SRCCOPY);
+ ::DeleteObject(hBitmap);
+ ::DeleteDC(hMemDC);
+}
+
+
+void CHmLabel::OnNcPaint()
+{
+ // TODO: 在此处添加消息处理程序代码
+ // 不为绘图消息调用 CStatic::OnNcPaint()
+ long styleEx = GetWindowLong(m_hWnd, GWL_EXSTYLE);
+ if ((styleEx & WS_EX_CLIENTEDGE) == WS_EX_CLIENTEDGE) {
+
+ RECT rect, rcClient;
+ GetClientRect(&rcClient);
+ ::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.left);
+ ::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.right);
+ GetWindowRect(&rect);
+ ::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_crBackground);
+ ::FillRect(hDC, &rect, hBrushBK);
+ DeleteObject(hBrushBK);
+
+ hBrushFrame = CreateSolidBrush(m_crFrame);
+ ::FrameRect(hDC, &rect, hBrushFrame);
+
+ ::DeleteObject(hRgnWnd);
+ ::DeleteObject(hRgnClient);
+ DeleteObject(hBrushFrame);
+ ::ReleaseDC(m_hWnd, hDC);
+ }
+}
+
diff --git a/SourceCode/Bond/Servo/HmLabel.h b/SourceCode/Bond/Servo/HmLabel.h
new file mode 100644
index 0000000..d7623e1
--- /dev/null
+++ b/SourceCode/Bond/Servo/HmLabel.h
@@ -0,0 +1,33 @@
+#pragma once
+class CHmLabel : public CStatic
+{
+public:
+ CHmLabel();
+ ~CHmLabel();
+
+public:
+ void setText(CString strText);
+ void setNote1(CString strNote1);
+ void setFontSize(int size);
+ void setNoteFontSize(int size);
+ void setBackground(COLORREF color, BOOL bInvalidate = FALSE);
+ void setForeground(COLORREF color, BOOL bInvalidate = FALSE);
+ void setNoteTextColor(COLORREF color, BOOL bInvalidate = FALSE);
+
+private:
+ COLORREF m_crFrame;
+ COLORREF m_crBackground;
+ COLORREF m_crForeground;
+ COLORREF m_crNote;
+ HFONT m_hFont;
+ HFONT m_hFontNote;
+
+private:
+ CString m_strNote1;
+
+public:
+ DECLARE_MESSAGE_MAP()
+ afx_msg void OnPaint();
+ afx_msg void OnNcPaint();
+};
+
diff --git a/SourceCode/Bond/Servo/Servo.cpp b/SourceCode/Bond/Servo/Servo.cpp
index f4f67b4..c46246e 100644
--- a/SourceCode/Bond/Servo/Servo.cpp
+++ b/SourceCode/Bond/Servo/Servo.cpp
@@ -19,6 +19,7 @@
#include "CControlJobManagerDlg.h"
#include "ToolUnits.h"
#include "CUserManager2.h"
+#include "AccordionWnd.h"
// 澹版槑鍏ㄥ眬鍙橀噺锛岀敤浜庣鐞� GDI+ 鍒濆鍖�
@@ -116,6 +117,7 @@
CEqsGraphWnd::RegisterWndClass();
CMapPosWnd::RegisterWndClass();
CHmTab::RegisterWndClass();
+ CAccordionWnd::RegisterWndClass();
// 鍒濆鍖朢x搴�
diff --git a/SourceCode/Bond/Servo/Servo.rc b/SourceCode/Bond/Servo/Servo.rc
index 3f3b197..1cc02ae 100644
--- a/SourceCode/Bond/Servo/Servo.rc
+++ b/SourceCode/Bond/Servo/Servo.rc
@@ -812,8 +812,18 @@
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
- LTEXT "Test",IDC_STATIC,95,67,15,8
CONTROL "Custom1",IDC_LINE1,"BYVerticalLine",WS_TABSTOP,286,7,18,240
+ CONTROL "Custom1",IDC_ACCORDION_WND1,"AccordionWnd",WS_TABSTOP,7,7,271,240
+END
+
+IDD_PROD_OVERVIEW DIALOGEX 0, 0, 271, 159
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CTEXT "0",IDC_PROD_DAY_OUTPUT,16,12,68,45,SS_CENTERIMAGE
+ CTEXT "0",IDC_PROD_NIGHT_OUTPUT,126,12,68,45,SS_CENTERIMAGE
+ CTEXT "-",IDC_PROD_DAY_TAKT,16,82,68,45,SS_CENTERIMAGE
+ CTEXT "-",IDC_PROD_NIGHT_TAKT,126,82,68,45,SS_CENTERIMAGE
END
@@ -1253,6 +1263,14 @@
TOPMARGIN, 7
BOTTOMMARGIN, 247
END
+
+ IDD_PROD_OVERVIEW, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 264
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 152
+ END
END
#endif // APSTUDIO_INVOKED
@@ -1507,6 +1525,11 @@
0
END
+IDD_PROD_OVERVIEW AFX_DIALOG_LAYOUT
+BEGIN
+ 0
+END
+
/////////////////////////////////////////////////////////////////////////////
//
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj b/SourceCode/Bond/Servo/Servo.vcxproj
index ddcddc3..8b7b8a4 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj
+++ b/SourceCode/Bond/Servo/Servo.vcxproj
@@ -222,6 +222,7 @@
<ClInclude Include="..\jsoncpp\include\json\value.h" />
<ClInclude Include="..\jsoncpp\include\json\writer.h" />
<ClInclude Include="..\jsoncpp\lib_json\json_batchallocator.h" />
+ <ClInclude Include="AccordionWnd.h" />
<ClInclude Include="CBaseDlg.h" />
<ClInclude Include="CCarrierSlotGrid.h" />
<ClInclude Include="CCarrierSlotSelector.h" />
@@ -243,9 +244,11 @@
<ClInclude Include="CPageCollectionEvent.h" />
<ClInclude Include="CPageGlassList.h" />
<ClInclude Include="CPageLinkSignal.h" />
+ <ClInclude Include="CPageProdOverview.h" />
<ClInclude Include="CPageReport.h" />
<ClInclude Include="CPageVarialbles.h" />
<ClInclude Include="CPanelProduction.h" />
+ <ClInclude Include="HmLabel.h" />
<ClInclude Include="ProductionStats.h" />
<ClInclude Include="CParam.h" />
<ClInclude Include="CCjPage1.h" />
@@ -445,6 +448,7 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
+ <ClCompile Include="AccordionWnd.cpp" />
<ClCompile Include="CBaseDlg.cpp" />
<ClCompile Include="CCarrierSlotGrid.cpp" />
<ClCompile Include="CCarrierSlotSelector.cpp" />
@@ -466,10 +470,12 @@
<ClCompile Include="CPageCollectionEvent.cpp" />
<ClCompile Include="CPageGlassList.cpp" />
<ClCompile Include="CPageLinkSignal.cpp" />
+ <ClCompile Include="CPageProdOverview.cpp" />
<ClCompile Include="CPageReport.cpp" />
<ClCompile Include="CPageVarialbles.cpp" />
<ClCompile Include="ConfigurationProduction.cpp" />
<ClCompile Include="CPanelProduction.cpp" />
+ <ClCompile Include="HmLabel.cpp" />
<ClCompile Include="ProductionStats.cpp" />
<ClCompile Include="CParam.cpp" />
<ClCompile Include="CCjPage1.cpp" />
@@ -662,4 +668,4 @@
<Error Condition="!Exists('..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.240803.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.ImplementationLibrary.1.0.240803.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
</Target>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.filters b/SourceCode/Bond/Servo/Servo.vcxproj.filters
index 652252b..ccbde0c 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.filters
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -239,6 +239,9 @@
<ClCompile Include="ConfigurationProduction.cpp" />
<ClCompile Include="CPanelProduction.cpp" />
<ClCompile Include="ProductionStats.cpp" />
+ <ClCompile Include="AccordionWnd.cpp" />
+ <ClCompile Include="CPageProdOverview.cpp" />
+ <ClCompile Include="HmLabel.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AlarmManager.h" />
@@ -520,6 +523,9 @@
<ClInclude Include="CEventEditDlg.h" />
<ClInclude Include="CReportEditDlg.h" />
<ClInclude Include="CPanelProduction.h" />
+ <ClInclude Include="AccordionWnd.h" />
+ <ClInclude Include="CPageProdOverview.h" />
+ <ClInclude Include="HmLabel.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Servo.rc" />
@@ -563,4 +569,4 @@
<UniqueIdentifier>{885738f6-3122-4bb9-8308-46b7f692fb13}</UniqueIdentifier>
</Filter>
</ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/resource.h b/SourceCode/Bond/Servo/resource.h
index e81edcd..8f303c6 100644
--- a/SourceCode/Bond/Servo/resource.h
+++ b/SourceCode/Bond/Servo/resource.h
@@ -61,7 +61,7 @@
#define IDD_CJ_PAGE3 180
#define IDD_DIALOG_USER_MANAGER2 181
#define IDD_DIALOG_USER_EDIT2 182
-#define IDD_DIALOG1 184
+#define IDD_PROD_OVERVIEW 183
#define IDD_DIALOG_USERX_LOG 184
#define IDD_DIALOG_VARIABLE_EDIT2 186
#define IDD_DIALOG_REPORT_EDIT 187
@@ -323,6 +323,11 @@
#define IDC_EDIT_EVT_NAME 1244
#define IDC_EDIT_EVT_DESC 1245
#define IDC_LIST_EVT_RPTS 1246
+#define IDC_ACCORDION_WND1 1247
+#define IDC_PROD_DAY_OUTPUT 1248
+#define IDC_PROD_NIGHT_OUTPUT 1249
+#define IDC_PROD_DAY_TAKT 1250
+#define IDC_PROD_NIGHT_TAKT 1251
#define ID_MENU_HELP_ABOUT 32771
#define ID_MENU_FILE_EXIT 32772
#define ID_MENU_FILE_SECSTEST 32773
@@ -362,7 +367,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 191
#define _APS_NEXT_COMMAND_VALUE 32804
-#define _APS_NEXT_CONTROL_VALUE 1247
+#define _APS_NEXT_CONTROL_VALUE 1252
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
--
Gitblit v1.9.3