1. 修改报警的显示模式(包括日志,需要后期修复)
2. 添加Release模式编译
已修改15个文件
1534 ■■■■ 文件已修改
SourceCode/Bond/Servo/AlarmDlg.cpp 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/AlarmDlg.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPin.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/LogDlg.cpp 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/LogDlg.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ProductionLogDlg.cpp 908 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ProductionLogDlg.h 126 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.cpp 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj.filters 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj.user 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoDlg.cpp 358 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoDlg.h 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/x64/Release/configuration.ini 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/AlarmDlg.cpp
@@ -187,6 +187,7 @@
    ON_WM_DESTROY()
    ON_WM_CLOSE()
    ON_WM_SIZE()
    ON_WM_TIMER()
    ON_CBN_SELCHANGE(IDC_COMBO_DATETIME, &CAlarmDlg::OnCbnSelchangeComboDatetime)
    ON_BN_CLICKED(IDC_BUTTON_SEARCH, &CAlarmDlg::OnBnClickedButtonSearch)
    ON_BN_CLICKED(IDC_BUTTON_EXPORT, &CAlarmDlg::OnBnClickedButtonExport)
@@ -199,7 +200,7 @@
BOOL CAlarmDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    InitRxWindow();
    SetTimer(1, 3000, nullptr);
    // 下拉框控件
    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DATETIME);
@@ -244,7 +245,6 @@
    pListCtrl->InsertColumn(6, _T("解除时间"), LVCFMT_LEFT, width[6]);
    pListCtrl->InsertColumn(7, _T("描述"), LVCFMT_LEFT, width[7]);
    pListCtrl->SetColumnWidth(7, LVSCW_AUTOSIZE_USEHEADER);
    // 计算总页数
@@ -315,6 +315,14 @@
    Resize();
}
void CAlarmDlg::OnTimer(UINT_PTR nIDEvent)
{
    if (1 == nIDEvent) {
        KillTimer(1);
        InitRxWindow();
    }
}
void CAlarmDlg::OnCbnSelchangeComboDatetime()
{
    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DATETIME);
SourceCode/Bond/Servo/AlarmDlg.h
@@ -63,6 +63,7 @@
    afx_msg void OnDestroy();
    afx_msg void OnClose();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnTimer(UINT_PTR nIDEvent);
    afx_msg void OnCbnSelchangeComboDatetime();
    afx_msg void OnBnClickedButtonSearch();
    afx_msg void OnBnClickedButtonExport();
SourceCode/Bond/Servo/CPin.cpp
@@ -53,7 +53,7 @@
    // 返回 >= 0连接成功
    int CPin::accpetConnect(CPin* pPin)
    {
        assert(pPin);
        ASSERT(pPin);
        // 是否已经连接
@@ -73,7 +73,7 @@
    int CPin::connectPin(CPin* pPin)
    {
        assert(pPin);
        ASSERT(pPin);
        // 是否已经连接
@@ -105,7 +105,7 @@
            return -1;
        }
        assert(m_pConnectedPin->m_pConnectedPin == this);
        ASSERT(m_pConnectedPin->m_pConnectedPin == this);
        m_pConnectedPin->m_pConnectedPin = NULL;
        m_pConnectedPin = NULL;
@@ -123,7 +123,7 @@
    int CPin::recvIntent(CIntent* pIntent)
    {
        assert(m_pEquipment);
        ASSERT(m_pEquipment);
        return m_pEquipment->recvIntent(this, pIntent);
    }
}
SourceCode/Bond/Servo/LogDlg.cpp
@@ -40,6 +40,7 @@
BEGIN_MESSAGE_MAP(CLogDlg, CDialogEx)
    ON_WM_CTLCOLOR()
    ON_WM_SIZE()
    ON_WM_TIMER()
    ON_WM_DESTROY()
    ON_WM_CLOSE()
    ON_NOTIFY(BLBUTTON_MENU_ITEM_CLICKED, IDC_BUTTON_LEVEL, &CLogDlg::OnButtonLevelMenuClicked)
@@ -105,6 +106,7 @@
BOOL CLogDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    SetTimer(1, 3000, nullptr);
    // 缓存
@@ -158,7 +160,7 @@
    m_logEdit.SetLimitText(-1);
    InitRxWindow();
    //InitRxWindow();
    Resize();
@@ -173,6 +175,14 @@
    Resize();
}
void CLogDlg::OnTimer(UINT_PTR nIDEvent)
{
    if (1 == nIDEvent) {
        KillTimer(1);
        InitRxWindow();
    }
}
void CLogDlg::Resize()
{
    int x, y, y2, temp;
SourceCode/Bond/Servo/LogDlg.h
@@ -51,6 +51,7 @@
public:
    virtual BOOL OnInitDialog();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnTimer(UINT_PTR nIDEvent);
    afx_msg void OnDestroy();
    afx_msg void OnClose();
    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
SourceCode/Bond/Servo/ProductionLogDlg.cpp
@@ -8,457 +8,457 @@
#include "Common.h"
#include <iomanip>
#define PAGE_SIZE                        100
#define PAGE_BACKGROUND_COLOR            RGB(252, 252, 255)
// CProductionLogDlg 对话框
IMPLEMENT_DYNAMIC(CProductionLogDlg, CDialogEx)
CProductionLogDlg::CProductionLogDlg(CWnd* pParent /*=nullptr*/)
    : CDialogEx(IDD_DIALOG_PRODUCTION_LOG, pParent)
{
    m_crBkgnd = PAGE_BACKGROUND_COLOR;
    m_hbrBkgnd = nullptr;
    m_pObserver = nullptr;
    m_strKeyword = "";
    m_strProductId = "";
    m_strBatchNo = "";
    m_strDeviceId = "";
    m_strOperatorName = "";
    m_strStatus = "";
    m_nCurPage = 0;
    m_nTotalPages = 0;
    m_nDateTimeFlag = 0;
    memset(m_szTimeStart, 0, sizeof(m_szTimeStart));
    memset(m_szTimeEnd, 0, sizeof(m_szTimeEnd));
    m_szTimeStart[0] = '\0';
    m_szTimeEnd[0] = '\0';
}
CProductionLogDlg::~CProductionLogDlg()
{
}
void CProductionLogDlg::InitRxWindow()
{
    /* 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_ALARM_SET == code) {
            //}
        pAny->release();
        }, [&]() -> void {
        // onComplete
        }, [&](IThrowable* pThrowable) -> void {
        // onErrorm
        pThrowable->printf();
        });
        theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())->subscribe(m_pObserver);
    }
}
void CProductionLogDlg::Resize()
{
    CRect rcClient;
    GetClientRect(&rcClient);
    m_listCtrl.MoveWindow(12, 58, rcClient.Width() - 24, rcClient.Height() - 64);
}
void CProductionLogDlg::UpdatePageData()
{
    // 根据过滤条件加载数据(支持分页、模糊查询、时间范围)
    auto vecData = ProductionLogManager::getInstance().getFilteredSteps(
        m_strProductId,         // 产品ID
        m_strBatchNo,           // 批次号
        m_strDeviceId,          // 设备ID
        m_strOperatorName,      // 操作员
        m_strStatus,            // 状态
        m_szTimeStart,          // 起始时间
        m_szTimeEnd,            // 结束时间
        m_nCurPage,             // 当前页码
        PAGE_SIZE               // 每页条数
    );
    // 填充数据到列表控件
    FillDataToListCtrl(&m_listCtrl, vecData);
    // 更新分页控件
    UpdatePageControls();
}
void CProductionLogDlg::UpdatePageControls()
{
    // 更新分页信息
    CString strPage;
    strPage.Format(_T("第 %d 页"), m_nCurPage);
    SetDlgItemText(IDC_LABEL_PAGE_NUMBER, strPage);
    // 启用/禁用翻页按钮
    GetDlgItem(IDC_BUTTON_PREV_PAGE)->EnableWindow(m_nCurPage > 1);
    GetDlgItem(IDC_BUTTON_NEXT_PAGE)->EnableWindow(m_nCurPage < m_nTotalPages);
}
void CProductionLogDlg::FillDataToListCtrl(CListCtrl* pListCtrl, const std::vector<ProductionStep>& vecSteps)
{
    if (pListCtrl == nullptr || pListCtrl->m_hWnd == nullptr) {
        return;
    }
    // 清空当前CListCtrl中的所有项
    pListCtrl->DeleteAllItems();
    // 遍历数据并插入到CListCtrl中
    for (const auto& step : vecSteps) {
        InsertStepData(pListCtrl, step);
    }
    // 获取列数
    int nColCount = pListCtrl->GetHeaderCtrl()->GetItemCount();
    pListCtrl->SetColumnWidth(nColCount - 1, LVSCW_AUTOSIZE_USEHEADER);
}
void CProductionLogDlg::InsertStepData(CListCtrl* pListCtrl, const ProductionStep& step)
{
    if (pListCtrl == nullptr || pListCtrl->m_hWnd == nullptr) {
        return;
    }
    int nRowCount = pListCtrl->GetItemCount();
    if (nRowCount >= PAGE_SIZE) {
        pListCtrl->DeleteItem(nRowCount - 1);
    }
    CString str;
    int nNewItem = pListCtrl->InsertItem(0, _T(""));
    str.Format(_T("%d"), step.nStepId);          pListCtrl->SetItemText(nNewItem, 1, str);
    pListCtrl->SetItemText(nNewItem, 2, step.strProductId.c_str());
    pListCtrl->SetItemText(nNewItem, 3, step.strBatchNo.c_str());
    str.Format(_T("%d"), step.nDeviceId);     pListCtrl->SetItemText(nNewItem, 4, str);
    pListCtrl->SetItemText(nNewItem, 5, step.strOperator.c_str());
    pListCtrl->SetItemText(nNewItem, 6, step.strStartTime.c_str());
    pListCtrl->SetItemText(nNewItem, 7, step.strEndTime.c_str());
    str.Format(_T("%d"), step.nYield);        pListCtrl->SetItemText(nNewItem, 8, str);
    str.Format(_T("%d"), step.nGoodCount);    pListCtrl->SetItemText(nNewItem, 9, str);
    str.Format(_T("%d"), step.nBadCount);     pListCtrl->SetItemText(nNewItem, 10, str);
    pListCtrl->SetItemText(nNewItem, 11, step.strStatus.c_str());
}
std::string CProductionLogDlg::getCurrentTimeString()
{
    auto now = std::chrono::system_clock::now();
    auto time_t_now = std::chrono::system_clock::to_time_t(now);
    std::tm tm_now = {};
    localtime_s(&tm_now, &time_t_now);
    std::stringstream ss;
    ss << std::put_time(&tm_now, "%Y-%m-%d %H:%M:%S");
    return ss.str();
}
void CProductionLogDlg::DoDataExchange(CDataExchange* pDX)
{
    DDX_Control(pDX, IDC_DATETIMEPICKER_START, m_dateTimeStart);
    DDX_Control(pDX, IDC_DATETIMEPICKER_END, m_dateTimeEnd);
    DDX_Control(pDX, IDC_LIST_PRODUCTION_LOG, m_listCtrl);
    CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CProductionLogDlg, CDialogEx)
    ON_WM_CTLCOLOR()
    ON_WM_DESTROY()
    ON_WM_CLOSE()
    ON_WM_SIZE()
    ON_CBN_SELCHANGE(IDC_COMBO_DATETIME, &CProductionLogDlg::OnCbnSelchangeComboDatetime)
    ON_BN_CLICKED(IDC_BUTTON_SEARCH, &CProductionLogDlg::OnBnClickedButtonSearch)
    ON_BN_CLICKED(IDC_BUTTON_EXPORT, &CProductionLogDlg::OnBnClickedButtonExport)
    ON_BN_CLICKED(IDC_BUTTON_PREV_PAGE, &CProductionLogDlg::OnBnClickedButtonPrevPage)
    ON_BN_CLICKED(IDC_BUTTON_NEXT_PAGE, &CProductionLogDlg::OnBnClickedButtonNextPage)
END_MESSAGE_MAP()
// CProductionLogDlg 消息处理程序
BOOL CProductionLogDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    InitRxWindow();
    // 初始化时间范围选择
    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DATETIME);
    pComboBox->AddString(_T("不限"));
    pComboBox->AddString(_T("今天"));
    pComboBox->AddString(_T("七天内"));
    pComboBox->AddString(_T("本月"));
    pComboBox->AddString(_T("今年"));
    pComboBox->AddString(_T("自定义"));
    pComboBox->SetCurSel(0);
    m_dateTimeStart.EnableWindow(FALSE);
    m_dateTimeEnd.EnableWindow(FALSE);
    // 读取列宽配置
    CString strIniFile, strItem;
    strIniFile.Format(_T("%s\\configuration.ini"), (LPCTSTR)theApp.m_strAppDir);
    int width[12] = { 0, 60, 100, 100, 70, 100, 140, 140, 60, 60, 60, 80 };
    for (int i = 0; i < 12; ++i) {
        strItem.Format(_T("Col_%d_Width"), i);
        width[i] = GetPrivateProfileInt("ProductionListCtrl", strItem, width[i], strIniFile);
    }
    // 初始化列表控件
    CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_PRODUCTION_LOG);
    DWORD dwStyle = pListCtrl->GetExtendedStyle();
    dwStyle |= LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES;
    pListCtrl->SetExtendedStyle(dwStyle);
    HIMAGELIST imageList = ImageList_Create(24, 24, ILC_COLOR24, 1, 1);
    ListView_SetImageList(pListCtrl->GetSafeHwnd(), imageList, LVSIL_SMALL);
    pListCtrl->InsertColumn(0, _T(""), LVCFMT_RIGHT, width[0]);
    pListCtrl->InsertColumn(1, _T("步骤ID"), LVCFMT_LEFT, width[1]);
    pListCtrl->InsertColumn(2, _T("产品ID"), LVCFMT_LEFT, width[2]);
    pListCtrl->InsertColumn(3, _T("批次号"), LVCFMT_LEFT, width[3]);
    pListCtrl->InsertColumn(4, _T("设备ID"), LVCFMT_LEFT, width[4]);
    pListCtrl->InsertColumn(5, _T("操作员"), LVCFMT_LEFT, width[5]);
    pListCtrl->InsertColumn(6, _T("开始时间"), LVCFMT_LEFT, width[6]);
    pListCtrl->InsertColumn(7, _T("结束时间"), LVCFMT_LEFT, width[7]);
    pListCtrl->InsertColumn(8, _T("产量"), LVCFMT_LEFT, width[8]);
    pListCtrl->InsertColumn(9, _T("良品数"), LVCFMT_LEFT, width[9]);
    pListCtrl->InsertColumn(10, _T("不良品数"), LVCFMT_LEFT, width[10]);
    pListCtrl->InsertColumn(11, _T("状态"), LVCFMT_LEFT, width[11]);
    // 初始化分页数据
    int totalRecords = ProductionLogManager::getInstance().getTotalStepCount(
        m_strProductId, m_strBatchNo, m_strDeviceId, m_strOperatorName,
        m_strStatus, m_szTimeStart, m_szTimeEnd);
    m_nTotalPages = (totalRecords + PAGE_SIZE - 1) / PAGE_SIZE;
    m_nCurPage = 1;
    Resize();
    UpdatePageData();
    return TRUE;  // return TRUE unless you set the focus to a control
    // 异常: OCX 属性页应返回 FALSE
}
HBRUSH CProductionLogDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
    if (nCtlColor == CTLCOLOR_STATIC) {
        pDC->SetBkColor(m_crBkgnd);
    }
    if (m_hbrBkgnd == nullptr) {
        m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
    }
    return m_hbrBkgnd;
}
void CProductionLogDlg::OnDestroy()
{
    CDialogEx::OnDestroy();
    // 保存列宽
    CString strIniFile, strItem, strTemp;
    strIniFile.Format(_T("%s\\configuration.ini"), (LPCTSTR)theApp.m_strAppDir);
    CHeaderCtrl* pHeader = m_listCtrl.GetHeaderCtrl();
    for (int i = 0; i < pHeader->GetItemCount(); ++i) {
        RECT rect;
        pHeader->GetItemRect(i, &rect);
        strItem.Format(_T("Col_%d_Width"), i);
        strTemp.Format(_T("%d"), rect.right - rect.left);
        WritePrivateProfileString("ProductionListCtrl", strItem, strTemp, strIniFile);
    }
    if (m_hbrBkgnd != nullptr) {
        ::DeleteObject(m_hbrBkgnd);
    }
    if (m_pObserver != NULL) {
        m_pObserver->unsubscribe();
        m_pObserver = NULL;
    }
}
void CProductionLogDlg::OnClose()
{
    ShowWindow(SW_HIDE);
    //GetParent()->PostMessage(ID_MSG_ALARMDLG_HIDE, 0, 0);
    CDialogEx::OnClose();
}
void CProductionLogDlg::OnSize(UINT nType, int cx, int cy)
{
    CDialogEx::OnSize(nType, cx, cy);
    if (GetDlgItem(IDC_LIST_PRODUCTION_LOG) == nullptr) return;
    Resize();
}
void CProductionLogDlg::OnCbnSelchangeComboDatetime()
{
    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DATETIME);
    int nIndex = pComboBox->GetCurSel();
    int nCount = pComboBox->GetCount();
    m_dateTimeStart.EnableWindow(nIndex == nCount - 1);
    m_dateTimeEnd.EnableWindow(nIndex == nCount - 1);
}
void CProductionLogDlg::OnBnClickedButtonSearch()
{
    // 获取关键字
    CString cstrKeyword;
    GetDlgItemText(IDC_EDIT_KEYWORD, cstrKeyword);
    m_strKeyword = CT2A(cstrKeyword);
    // 获取日期
    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DATETIME);
    m_nDateTimeFlag = pComboBox->GetCurSel();
    if (m_nDateTimeFlag == 0) {
        memset(m_szTimeStart, 0, sizeof(m_szTimeStart));
        memset(m_szTimeEnd, 0, sizeof(m_szTimeEnd));
        m_szTimeStart[0] = '\0';
        m_szTimeEnd[0] = '\0';
    }
    else {
        CTime time = CTime::GetCurrentTime();
        if (m_nDateTimeFlag == 1) {
            // 今天
            sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d 00:00:00", time.GetYear(), time.GetMonth(), time.GetDay());
            sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", time.GetYear(), time.GetMonth(), time.GetDay());
        }
        else if (m_nDateTimeFlag == 2) {
            // 7天内
            CTime time2 = time - CTimeSpan(7, 0, 0, 0);
            sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d 00:00:00", time2.GetYear(), time2.GetMonth(), time2.GetDay());
            sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", time.GetYear(), time.GetMonth(), time.GetDay());
        }
        else if (m_nDateTimeFlag == 3) {
            // 本月
            sprintf_s(m_szTimeStart, 64, "%d-%02d-01 00:00:00", time.GetYear(), time.GetMonth());
            sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", time.GetYear(), time.GetMonth(), time.GetDay());
        }
        else if (m_nDateTimeFlag == 4) {
            // 今年
            sprintf_s(m_szTimeStart, 64, "%d-01-01 00:00:00", time.GetYear());
            sprintf_s(m_szTimeEnd, 64, "%d-12-31 23:59:59", time.GetYear());
        }
        else if (m_nDateTimeFlag == 5) {
            // 自定义
            SYSTEMTIME t1, t2;
            m_dateTimeStart.GetTime(&t1);
            m_dateTimeEnd.GetTime(&t2);
            sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d %02d:%02d:%02d",
                t1.wYear, t1.wMonth, t1.wDay, t1.wHour, t1.wMinute, t1.wSecond);
            sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d %02d:%02d:%02d",
                t2.wYear, t2.wMonth, t2.wDay, t2.wHour, t2.wMinute, t2.wSecond);
        }
    }
    // 计算总页数
    int totalRecords = ProductionLogManager::getInstance().getTotalStepCount(
        m_strProductId, m_strBatchNo, m_strDeviceId, m_strOperatorName,
        m_strStatus, m_szTimeStart, m_szTimeEnd);
    m_nTotalPages = (totalRecords + PAGE_SIZE - 1) / PAGE_SIZE;
    m_nCurPage = 1;
    UpdatePageData();  // 调用分页更新函数
}
void CProductionLogDlg::OnBnClickedButtonExport()
{
    CFileDialog fileDialog(FALSE, "csv", "", OFN_HIDEREADONLY, "CSV Files (*.csv)|*.csv||");
    if (fileDialog.DoModal() != IDOK) {
        return;
    }
    CStdioFile file;
    if (!file.Open(fileDialog.GetPathName(), CFile::modeCreate | CFile::modeWrite | CFile::typeText)) {
        CString err;
        err.Format(_T("无法创建文件: %s"), fileDialog.GetPathName());
        AfxMessageBox(err);
        return;
    }
    const int MAX_COLS = 32;
    char szItem[256] = { 0 };
    HDITEM hdItem[MAX_COLS];
    for (int i = 0; i < MAX_COLS; i++) {
        hdItem[i].pszText = szItem;
        hdItem[i].cchTextMax = 256;
        hdItem[i].mask = HDI_TEXT | HDI_WIDTH;
    }
    // 获取列数
    CHeaderCtrl* pHeader = m_listCtrl.GetHeaderCtrl();
    int nSubItemCount = min(pHeader->GetItemCount(), MAX_COLS);
    // 表头
    CString strHeader;
    for (int i = 0; i < nSubItemCount; i++) {
        pHeader->GetItem(i, &hdItem[i]);
        if (hdItem[i].cxy > 0) {
            if (!strHeader.IsEmpty()) strHeader += ",";
            strHeader += CString(hdItem[i].pszText);
        }
    }
    strHeader += "\n";
    file.WriteString(strHeader);
    // 表格内容
    int nItemCount = m_listCtrl.GetItemCount();
    for (int i = 0; i < nItemCount; i++) {
        CStringArray arrRow;
        for (int j = 0; j < nSubItemCount; j++) {
            if (hdItem[j].cxy > 0) {
                CString strText = m_listCtrl.GetItemText(i, j);
                strText.Replace(_T("* "), _T(""));
                // 如果字段中含逗号,包裹双引号
                if (strText.Find(',') != -1) {
                    strText = _T("\"") + strText + _T("\"");
                }
                arrRow.Add(strText);
            }
        }
        CString strRow;
        for (int k = 0; k < arrRow.GetCount(); ++k) {
            if (k > 0) strRow += ",";
            strRow += arrRow[k];
        }
        strRow += "\n";
        file.WriteString(strRow);
    }
    file.Close();
}
void CProductionLogDlg::OnBnClickedButtonPrevPage()
{
    // 点击上一页
    m_nCurPage--;
    UpdatePageData();  // 调用分页更新函数
}
void CProductionLogDlg::OnBnClickedButtonNextPage()
{
    // 点击下一页
    m_nCurPage++;
    UpdatePageData();  // 调用分页更新函数
}
//#define PAGE_SIZE                        100
//#define PAGE_BACKGROUND_COLOR            RGB(252, 252, 255)
//
//// CProductionLogDlg 对话框
//
//IMPLEMENT_DYNAMIC(CProductionLogDlg, CDialogEx)
//
//CProductionLogDlg::CProductionLogDlg(CWnd* pParent /*=nullptr*/)
//    : CDialogEx(IDD_DIALOG_PRODUCTION_LOG, pParent)
//{
//    m_crBkgnd = PAGE_BACKGROUND_COLOR;
//    m_hbrBkgnd = nullptr;
//    m_pObserver = nullptr;
//
//    m_strKeyword = "";
//    m_strProductId = "";
//    m_strBatchNo = "";
//    m_strDeviceId = "";
//    m_strOperatorName = "";
//    m_strStatus = "";
//
//    m_nCurPage = 0;
//    m_nTotalPages = 0;
//    m_nDateTimeFlag = 0;
//
//    memset(m_szTimeStart, 0, sizeof(m_szTimeStart));
//    memset(m_szTimeEnd, 0, sizeof(m_szTimeEnd));
//    m_szTimeStart[0] = '\0';
//    m_szTimeEnd[0] = '\0';
//}
//
//CProductionLogDlg::~CProductionLogDlg()
//{
//}
//
//void CProductionLogDlg::InitRxWindow()
//{
//    /* 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_ALARM_SET == code) {
//            //}
//
//        pAny->release();
//        }, [&]() -> void {
//        // onComplete
//        }, [&](IThrowable* pThrowable) -> void {
//        // onErrorm
//        pThrowable->printf();
//        });
//
//        theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())->subscribe(m_pObserver);
//    }
//}
//
//void CProductionLogDlg::Resize()
//{
//    CRect rcClient;
//    GetClientRect(&rcClient);
//
//    m_listCtrl.MoveWindow(12, 58, rcClient.Width() - 24, rcClient.Height() - 64);
//}
//
//void CProductionLogDlg::UpdatePageData()
//{
//    // 根据过滤条件加载数据(支持分页、模糊查询、时间范围)
//    auto vecData = ProductionLogManager::getInstance().getFilteredSteps(
//        m_strProductId,         // 产品ID
//        m_strBatchNo,           // 批次号
//        m_strDeviceId,          // 设备ID
//        m_strOperatorName,      // 操作员
//        m_strStatus,            // 状态
//        m_szTimeStart,          // 起始时间
//        m_szTimeEnd,            // 结束时间
//        m_nCurPage,             // 当前页码
//        PAGE_SIZE               // 每页条数
//    );
//
//    // 填充数据到列表控件
//    FillDataToListCtrl(&m_listCtrl, vecData);
//
//    // 更新分页控件
//    UpdatePageControls();
//}
//
//void CProductionLogDlg::UpdatePageControls()
//{
//    // 更新分页信息
//    CString strPage;
//    strPage.Format(_T("第 %d 页"), m_nCurPage);
//    SetDlgItemText(IDC_LABEL_PAGE_NUMBER, strPage);
//
//    // 启用/禁用翻页按钮
//    GetDlgItem(IDC_BUTTON_PREV_PAGE)->EnableWindow(m_nCurPage > 1);
//    GetDlgItem(IDC_BUTTON_NEXT_PAGE)->EnableWindow(m_nCurPage < m_nTotalPages);
//}
//
//void CProductionLogDlg::FillDataToListCtrl(CListCtrl* pListCtrl, const std::vector<ProductionStep>& vecSteps)
//{
//    if (pListCtrl == nullptr || pListCtrl->m_hWnd == nullptr) {
//        return;
//    }
//
//    // 清空当前CListCtrl中的所有项
//    pListCtrl->DeleteAllItems();
//
//    // 遍历数据并插入到CListCtrl中
//    for (const auto& step : vecSteps) {
//        InsertStepData(pListCtrl, step);
//    }
//
//    // 获取列数
//    int nColCount = pListCtrl->GetHeaderCtrl()->GetItemCount();
//    pListCtrl->SetColumnWidth(nColCount - 1, LVSCW_AUTOSIZE_USEHEADER);
//}
//
//void CProductionLogDlg::InsertStepData(CListCtrl* pListCtrl, const ProductionStep& step)
//{
//    if (pListCtrl == nullptr || pListCtrl->m_hWnd == nullptr) {
//        return;
//    }
//
//    int nRowCount = pListCtrl->GetItemCount();
//    if (nRowCount >= PAGE_SIZE) {
//        pListCtrl->DeleteItem(nRowCount - 1);
//    }
//
//    CString str;
//    int nNewItem = pListCtrl->InsertItem(0, _T(""));
//    str.Format(_T("%d"), step.nStepId);          pListCtrl->SetItemText(nNewItem, 1, str);
//    pListCtrl->SetItemText(nNewItem, 2, step.strProductId.c_str());
//    pListCtrl->SetItemText(nNewItem, 3, step.strBatchNo.c_str());
//    str.Format(_T("%d"), step.nDeviceId);     pListCtrl->SetItemText(nNewItem, 4, str);
//    pListCtrl->SetItemText(nNewItem, 5, step.strOperator.c_str());
//    pListCtrl->SetItemText(nNewItem, 6, step.strStartTime.c_str());
//    pListCtrl->SetItemText(nNewItem, 7, step.strEndTime.c_str());
//    str.Format(_T("%d"), step.nYield);        pListCtrl->SetItemText(nNewItem, 8, str);
//    str.Format(_T("%d"), step.nGoodCount);    pListCtrl->SetItemText(nNewItem, 9, str);
//    str.Format(_T("%d"), step.nBadCount);     pListCtrl->SetItemText(nNewItem, 10, str);
//    pListCtrl->SetItemText(nNewItem, 11, step.strStatus.c_str());
//}
//
//std::string CProductionLogDlg::getCurrentTimeString()
//{
//    auto now = std::chrono::system_clock::now();
//    auto time_t_now = std::chrono::system_clock::to_time_t(now);
//
//    std::tm tm_now = {};
//    localtime_s(&tm_now, &time_t_now);
//
//    std::stringstream ss;
//    ss << std::put_time(&tm_now, "%Y-%m-%d %H:%M:%S");
//    return ss.str();
//}
//
//void CProductionLogDlg::DoDataExchange(CDataExchange* pDX)
//{
//    DDX_Control(pDX, IDC_DATETIMEPICKER_START, m_dateTimeStart);
//    DDX_Control(pDX, IDC_DATETIMEPICKER_END, m_dateTimeEnd);
//    DDX_Control(pDX, IDC_LIST_PRODUCTION_LOG, m_listCtrl);
//    CDialogEx::DoDataExchange(pDX);
//}
//
//BEGIN_MESSAGE_MAP(CProductionLogDlg, CDialogEx)
//    ON_WM_CTLCOLOR()
//    ON_WM_DESTROY()
//    ON_WM_CLOSE()
//    ON_WM_SIZE()
//    ON_CBN_SELCHANGE(IDC_COMBO_DATETIME, &CProductionLogDlg::OnCbnSelchangeComboDatetime)
//    ON_BN_CLICKED(IDC_BUTTON_SEARCH, &CProductionLogDlg::OnBnClickedButtonSearch)
//    ON_BN_CLICKED(IDC_BUTTON_EXPORT, &CProductionLogDlg::OnBnClickedButtonExport)
//    ON_BN_CLICKED(IDC_BUTTON_PREV_PAGE, &CProductionLogDlg::OnBnClickedButtonPrevPage)
//    ON_BN_CLICKED(IDC_BUTTON_NEXT_PAGE, &CProductionLogDlg::OnBnClickedButtonNextPage)
//END_MESSAGE_MAP()
//
//// CProductionLogDlg 消息处理程序
//BOOL CProductionLogDlg::OnInitDialog()
//{
//    CDialogEx::OnInitDialog();
//    InitRxWindow();
//
//    // 初始化时间范围选择
//    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DATETIME);
//    pComboBox->AddString(_T("不限"));
//    pComboBox->AddString(_T("今天"));
//    pComboBox->AddString(_T("七天内"));
//    pComboBox->AddString(_T("本月"));
//    pComboBox->AddString(_T("今年"));
//    pComboBox->AddString(_T("自定义"));
//    pComboBox->SetCurSel(0);
//
//    m_dateTimeStart.EnableWindow(FALSE);
//    m_dateTimeEnd.EnableWindow(FALSE);
//
//    // 读取列宽配置
//    CString strIniFile, strItem;
//    strIniFile.Format(_T("%s\\configuration.ini"), (LPCTSTR)theApp.m_strAppDir);
//    int width[12] = { 0, 60, 100, 100, 70, 100, 140, 140, 60, 60, 60, 80 };
//    for (int i = 0; i < 12; ++i) {
//        strItem.Format(_T("Col_%d_Width"), i);
//        width[i] = GetPrivateProfileInt("ProductionListCtrl", strItem, width[i], strIniFile);
//    }
//
//    // 初始化列表控件
//    CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST_PRODUCTION_LOG);
//    DWORD dwStyle = pListCtrl->GetExtendedStyle();
//    dwStyle |= LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES;
//    pListCtrl->SetExtendedStyle(dwStyle);
//
//    HIMAGELIST imageList = ImageList_Create(24, 24, ILC_COLOR24, 1, 1);
//    ListView_SetImageList(pListCtrl->GetSafeHwnd(), imageList, LVSIL_SMALL);
//
//    pListCtrl->InsertColumn(0, _T(""), LVCFMT_RIGHT, width[0]);
//    pListCtrl->InsertColumn(1, _T("步骤ID"), LVCFMT_LEFT, width[1]);
//    pListCtrl->InsertColumn(2, _T("产品ID"), LVCFMT_LEFT, width[2]);
//    pListCtrl->InsertColumn(3, _T("批次号"), LVCFMT_LEFT, width[3]);
//    pListCtrl->InsertColumn(4, _T("设备ID"), LVCFMT_LEFT, width[4]);
//    pListCtrl->InsertColumn(5, _T("操作员"), LVCFMT_LEFT, width[5]);
//    pListCtrl->InsertColumn(6, _T("开始时间"), LVCFMT_LEFT, width[6]);
//    pListCtrl->InsertColumn(7, _T("结束时间"), LVCFMT_LEFT, width[7]);
//    pListCtrl->InsertColumn(8, _T("产量"), LVCFMT_LEFT, width[8]);
//    pListCtrl->InsertColumn(9, _T("良品数"), LVCFMT_LEFT, width[9]);
//    pListCtrl->InsertColumn(10, _T("不良品数"), LVCFMT_LEFT, width[10]);
//    pListCtrl->InsertColumn(11, _T("状态"), LVCFMT_LEFT, width[11]);
//
//    // 初始化分页数据
//    int totalRecords = ProductionLogManager::getInstance().getTotalStepCount(
//        m_strProductId, m_strBatchNo, m_strDeviceId, m_strOperatorName,
//        m_strStatus, m_szTimeStart, m_szTimeEnd);
//    m_nTotalPages = (totalRecords + PAGE_SIZE - 1) / PAGE_SIZE;
//    m_nCurPage = 1;
//
//    Resize();
//    UpdatePageData();
//
//    return TRUE;  // return TRUE unless you set the focus to a control
//    // 异常: OCX 属性页应返回 FALSE
//}
//
//HBRUSH CProductionLogDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
//{
//    HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
//
//    if (nCtlColor == CTLCOLOR_STATIC) {
//        pDC->SetBkColor(m_crBkgnd);
//    }
//
//    if (m_hbrBkgnd == nullptr) {
//        m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
//    }
//
//    return m_hbrBkgnd;
//}
//
//void CProductionLogDlg::OnDestroy()
//{
//    CDialogEx::OnDestroy();
//
//    // 保存列宽
//    CString strIniFile, strItem, strTemp;
//    strIniFile.Format(_T("%s\\configuration.ini"), (LPCTSTR)theApp.m_strAppDir);
//    CHeaderCtrl* pHeader = m_listCtrl.GetHeaderCtrl();
//    for (int i = 0; i < pHeader->GetItemCount(); ++i) {
//        RECT rect;
//        pHeader->GetItemRect(i, &rect);
//        strItem.Format(_T("Col_%d_Width"), i);
//        strTemp.Format(_T("%d"), rect.right - rect.left);
//        WritePrivateProfileString("ProductionListCtrl", strItem, strTemp, strIniFile);
//    }
//
//    if (m_hbrBkgnd != nullptr) {
//        ::DeleteObject(m_hbrBkgnd);
//    }
//
//    if (m_pObserver != NULL) {
//        m_pObserver->unsubscribe();
//        m_pObserver = NULL;
//    }
//}
//
//void CProductionLogDlg::OnClose()
//{
//    ShowWindow(SW_HIDE);
//    //GetParent()->PostMessage(ID_MSG_ALARMDLG_HIDE, 0, 0);
//    CDialogEx::OnClose();
//}
//
//void CProductionLogDlg::OnSize(UINT nType, int cx, int cy)
//{
//    CDialogEx::OnSize(nType, cx, cy);
//    if (GetDlgItem(IDC_LIST_PRODUCTION_LOG) == nullptr) return;
//    Resize();
//}
//
//void CProductionLogDlg::OnCbnSelchangeComboDatetime()
//{
//    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DATETIME);
//    int nIndex = pComboBox->GetCurSel();
//    int nCount = pComboBox->GetCount();
//    m_dateTimeStart.EnableWindow(nIndex == nCount - 1);
//    m_dateTimeEnd.EnableWindow(nIndex == nCount - 1);
//}
//
//void CProductionLogDlg::OnBnClickedButtonSearch()
//{
//    // 获取关键字
//    CString cstrKeyword;
//    GetDlgItemText(IDC_EDIT_KEYWORD, cstrKeyword);
//    m_strKeyword = CT2A(cstrKeyword);
//
//    // 获取日期
//    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DATETIME);
//    m_nDateTimeFlag = pComboBox->GetCurSel();
//    if (m_nDateTimeFlag == 0) {
//        memset(m_szTimeStart, 0, sizeof(m_szTimeStart));
//        memset(m_szTimeEnd, 0, sizeof(m_szTimeEnd));
//        m_szTimeStart[0] = '\0';
//        m_szTimeEnd[0] = '\0';
//    }
//    else {
//        CTime time = CTime::GetCurrentTime();
//        if (m_nDateTimeFlag == 1) {
//            // 今天
//            sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d 00:00:00", time.GetYear(), time.GetMonth(), time.GetDay());
//            sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", time.GetYear(), time.GetMonth(), time.GetDay());
//        }
//        else if (m_nDateTimeFlag == 2) {
//            // 7天内
//            CTime time2 = time - CTimeSpan(7, 0, 0, 0);
//            sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d 00:00:00", time2.GetYear(), time2.GetMonth(), time2.GetDay());
//            sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", time.GetYear(), time.GetMonth(), time.GetDay());
//        }
//        else if (m_nDateTimeFlag == 3) {
//            // 本月
//            sprintf_s(m_szTimeStart, 64, "%d-%02d-01 00:00:00", time.GetYear(), time.GetMonth());
//            sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", time.GetYear(), time.GetMonth(), time.GetDay());
//        }
//        else if (m_nDateTimeFlag == 4) {
//            // 今年
//            sprintf_s(m_szTimeStart, 64, "%d-01-01 00:00:00", time.GetYear());
//            sprintf_s(m_szTimeEnd, 64, "%d-12-31 23:59:59", time.GetYear());
//        }
//        else if (m_nDateTimeFlag == 5) {
//            // 自定义
//            SYSTEMTIME t1, t2;
//            m_dateTimeStart.GetTime(&t1);
//            m_dateTimeEnd.GetTime(&t2);
//
//            sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d %02d:%02d:%02d",
//                t1.wYear, t1.wMonth, t1.wDay, t1.wHour, t1.wMinute, t1.wSecond);
//            sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d %02d:%02d:%02d",
//                t2.wYear, t2.wMonth, t2.wDay, t2.wHour, t2.wMinute, t2.wSecond);
//        }
//    }
//
//    // 计算总页数
//    int totalRecords = ProductionLogManager::getInstance().getTotalStepCount(
//        m_strProductId, m_strBatchNo, m_strDeviceId, m_strOperatorName,
//        m_strStatus, m_szTimeStart, m_szTimeEnd);
//    m_nTotalPages = (totalRecords + PAGE_SIZE - 1) / PAGE_SIZE;
//    m_nCurPage = 1;
//
//    UpdatePageData();  // 调用分页更新函数
//}
//
//void CProductionLogDlg::OnBnClickedButtonExport()
//{
//    CFileDialog fileDialog(FALSE, "csv", "", OFN_HIDEREADONLY, "CSV Files (*.csv)|*.csv||");
//    if (fileDialog.DoModal() != IDOK) {
//        return;
//    }
//
//    CStdioFile file;
//    if (!file.Open(fileDialog.GetPathName(), CFile::modeCreate | CFile::modeWrite | CFile::typeText)) {
//        CString err;
//        err.Format(_T("无法创建文件: %s"), fileDialog.GetPathName());
//        AfxMessageBox(err);
//        return;
//    }
//
//    const int MAX_COLS = 32;
//    char szItem[256] = { 0 };
//    HDITEM hdItem[MAX_COLS];
//
//    for (int i = 0; i < MAX_COLS; i++) {
//        hdItem[i].pszText = szItem;
//        hdItem[i].cchTextMax = 256;
//        hdItem[i].mask = HDI_TEXT | HDI_WIDTH;
//    }
//
//    // 获取列数
//    CHeaderCtrl* pHeader = m_listCtrl.GetHeaderCtrl();
//    int nSubItemCount = min(pHeader->GetItemCount(), MAX_COLS);
//
//    // 表头
//    CString strHeader;
//    for (int i = 0; i < nSubItemCount; i++) {
//        pHeader->GetItem(i, &hdItem[i]);
//        if (hdItem[i].cxy > 0) {
//            if (!strHeader.IsEmpty()) strHeader += ",";
//            strHeader += CString(hdItem[i].pszText);
//        }
//    }
//    strHeader += "\n";
//    file.WriteString(strHeader);
//
//    // 表格内容
//    int nItemCount = m_listCtrl.GetItemCount();
//    for (int i = 0; i < nItemCount; i++) {
//        CStringArray arrRow;
//        for (int j = 0; j < nSubItemCount; j++) {
//            if (hdItem[j].cxy > 0) {
//                CString strText = m_listCtrl.GetItemText(i, j);
//                strText.Replace(_T("* "), _T(""));
//                // 如果字段中含逗号,包裹双引号
//                if (strText.Find(',') != -1) {
//                    strText = _T("\"") + strText + _T("\"");
//                }
//                arrRow.Add(strText);
//            }
//        }
//
//        CString strRow;
//        for (int k = 0; k < arrRow.GetCount(); ++k) {
//            if (k > 0) strRow += ",";
//            strRow += arrRow[k];
//        }
//        strRow += "\n";
//        file.WriteString(strRow);
//    }
//
//    file.Close();
//}
//
//void CProductionLogDlg::OnBnClickedButtonPrevPage()
//{
//    // 点击上一页
//    m_nCurPage--;
//    UpdatePageData();  // 调用分页更新函数
//}
//
//void CProductionLogDlg::OnBnClickedButtonNextPage()
//{
//    // 点击下一页
//    m_nCurPage++;
//    UpdatePageData();  // 调用分页更新函数
//}
SourceCode/Bond/Servo/ProductionLogDlg.h
@@ -6,66 +6,66 @@
// CProductionLogDlg 对话框
class CProductionLogDlg : public CDialogEx
{
    DECLARE_DYNAMIC(CProductionLogDlg)
public:
    CProductionLogDlg(CWnd* pParent = nullptr);   // 标准构造函数
    virtual ~CProductionLogDlg();
private:
    void InitRxWindow();
    void Resize();
    void UpdatePageData();
    void UpdatePageControls();
    void FillDataToListCtrl(CListCtrl* pListCtrl, const std::vector<ProductionStep>& vecSteps);
    void InsertStepData(CListCtrl* pListCtrl, const ProductionStep& step);
    std::string getCurrentTimeString();
private:
    COLORREF m_crBkgnd;
    HBRUSH m_hbrBkgnd;
    IObserver* m_pObserver;
    // 搜索关键字
    std::string m_strKeyword;
    std::string m_strProductId;
    std::string m_strBatchNo;
    std::string m_strDeviceId;
    std::string m_strOperatorName;
    std::string m_strStatus;
    // 页码
    int m_nCurPage;
    int m_nTotalPages;
    // 日期
    int m_nDateTimeFlag;
    char m_szTimeStart[64];
    char m_szTimeEnd[64];
    // 控件
    CDateTimeCtrl m_dateTimeStart;
    CDateTimeCtrl m_dateTimeEnd;
    CListCtrlEx m_listCtrl;
// 对话框数据
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_DIALOG_PRODUCTION_LOG };
#endif
protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    virtual BOOL OnInitDialog();
    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
    afx_msg void OnDestroy();
    afx_msg void OnClose();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnCbnSelchangeComboDatetime();
    afx_msg void OnBnClickedButtonSearch();
    afx_msg void OnBnClickedButtonExport();
    afx_msg void OnBnClickedButtonPrevPage();
    afx_msg void OnBnClickedButtonNextPage();
    DECLARE_MESSAGE_MAP()
};
//class CProductionLogDlg : public CDialogEx
//{
//    DECLARE_DYNAMIC(CProductionLogDlg)
//
//public:
//    CProductionLogDlg(CWnd* pParent = nullptr);   // 标准构造函数
//    virtual ~CProductionLogDlg();
//
//private:
//    void InitRxWindow();
//    void Resize();
//    void UpdatePageData();
//    void UpdatePageControls();
//    void FillDataToListCtrl(CListCtrl* pListCtrl, const std::vector<ProductionStep>& vecSteps);
//    void InsertStepData(CListCtrl* pListCtrl, const ProductionStep& step);
//    std::string getCurrentTimeString();
//
//private:
//    COLORREF m_crBkgnd;
//    HBRUSH m_hbrBkgnd;
//    IObserver* m_pObserver;
//
//    // 搜索关键字
//    std::string m_strKeyword;
//    std::string m_strProductId;
//    std::string m_strBatchNo;
//    std::string m_strDeviceId;
//    std::string m_strOperatorName;
//    std::string m_strStatus;
//
//    // 页码
//    int m_nCurPage;
//    int m_nTotalPages;
//
//    // 日期
//    int m_nDateTimeFlag;
//    char m_szTimeStart[64];
//    char m_szTimeEnd[64];
//
//    // 控件
//    CDateTimeCtrl m_dateTimeStart;
//    CDateTimeCtrl m_dateTimeEnd;
//    CListCtrlEx m_listCtrl;
//
//// 对话框数据
//#ifdef AFX_DESIGN_TIME
//    enum { IDD = IDD_DIALOG_PRODUCTION_LOG };
//#endif
//
//protected:
//    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
//    virtual BOOL OnInitDialog();
//    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
//    afx_msg void OnDestroy();
//    afx_msg void OnClose();
//    afx_msg void OnSize(UINT nType, int cx, int cy);
//    afx_msg void OnCbnSelchangeComboDatetime();
//    afx_msg void OnBnClickedButtonSearch();
//    afx_msg void OnBnClickedButtonExport();
//    afx_msg void OnBnClickedButtonPrevPage();
//    afx_msg void OnBnClickedButtonNextPage();
//    DECLARE_MESSAGE_MAP()
//};
SourceCode/Bond/Servo/Servo.cpp
@@ -130,33 +130,33 @@
    // 初始化生产履历管理器
    try {
        if (!ProductionLogManager::getInstance().initProductionTable()) {
            AfxMessageBox("初始化生产履历管理器失败!");
            return FALSE;
        }
    }
    catch (const std::exception& ex) {
        CString errorMsg;
        errorMsg.Format(_T("初始化生产履历管理器失败:%s"), CString(ex.what()));
        AfxMessageBox(errorMsg, MB_ICONERROR);
        return FALSE;
    }
    //try {
    //    if (!ProductionLogManager::getInstance().initProductionTable()) {
    //        AfxMessageBox("初始化生产履历管理器失败!");
    //        return FALSE;
    //    }
    //}
    //catch (const std::exception& ex) {
    //    CString errorMsg;
    //    errorMsg.Format(_T("初始化生产履历管理器失败:%s"), CString(ex.what()));
    //    AfxMessageBox(errorMsg, MB_ICONERROR);
    //    return FALSE;
    //}
    // 初始化SECS运行设置管理库
    try {
        if (!SECSRuntimeManager::getInstance().initRuntimeSetting()) {
            AfxMessageBox("初始化SECS运行设置失败!");
            return FALSE;
        }
    }
    catch (const std::exception& ex) {
        CString errorMsg;
        errorMsg.Format(_T("初始化SECS运行设置失败:%s"), CString(ex.what()));
        AfxMessageBox(errorMsg, MB_ICONERROR);
        return FALSE;
    }
    //try {
    //    if (!SECSRuntimeManager::getInstance().initRuntimeSetting()) {
    //        AfxMessageBox("初始化SECS运行设置失败!");
    //        return FALSE;
    //    }
    //}
    //catch (const std::exception& ex) {
    //    CString errorMsg;
    //    errorMsg.Format(_T("初始化SECS运行设置失败:%s"), CString(ex.what()));
    //    AfxMessageBox(errorMsg, MB_ICONERROR);
    //    return FALSE;
    //}
    CServoDlg dlg;
SourceCode/Bond/Servo/Servo.rc
Binary files differ
SourceCode/Bond/Servo/Servo.vcxproj
@@ -50,9 +50,9 @@
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v140</PlatformToolset>
    <PlatformToolset>v142</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
    <CharacterSet>MultiByte</CharacterSet>
    <UseOfMfc>Dynamic</UseOfMfc>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -133,7 +133,8 @@
      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ResourceCompile>
    <PostBuildEvent>
      <Command>copy "$(TargetDir)$(ProjectName).exe" "\\Boounion-0106\Servo\\$(ProjectName).exe"</Command>
      <Command>
      </Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -97,6 +97,8 @@
    <ClCompile Include="CEqReadStep.cpp" />
    <ClCompile Include="CRecipesManager.cpp" />
    <ClCompile Include="CRecipeList.cpp" />
    <ClCompile Include="ProductionLogDlg.cpp" />
    <ClCompile Include="ProductionLogManager.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="AlarmManager.h" />
@@ -192,6 +194,8 @@
    <ClInclude Include="CEqReadStep.h" />
    <ClInclude Include="CRecipesManager.h" />
    <ClInclude Include="CRecipeList.h" />
    <ClInclude Include="ProductionLogDlg.h" />
    <ClInclude Include="ProductionLogManager.h" />
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="Servo.rc" />
SourceCode/Bond/Servo/Servo.vcxproj.user
@@ -4,9 +4,9 @@
    <RESOURCE_FILE>Servo.rc</RESOURCE_FILE>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <RemoteDebuggerCommand>D:\CLH\Servo\Servo.exe</RemoteDebuggerCommand>
    <RemoteDebuggerWorkingDirectory>D:\CLH\Servo\</RemoteDebuggerWorkingDirectory>
    <RemoteDebuggerServerName>Boounion-0106</RemoteDebuggerServerName>
    <RemoteDebuggerCommand>\\DESKTOP-IODBVIQ\Servo\Debug\Servo.exe</RemoteDebuggerCommand>
    <RemoteDebuggerWorkingDirectory>\\DESKTOP-IODBVIQ\Servo\Debug</RemoteDebuggerWorkingDirectory>
    <RemoteDebuggerServerName>DESKTOP-IODBVIQ</RemoteDebuggerServerName>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
  </PropertyGroup>
</Project>
SourceCode/Bond/Servo/ServoDlg.cpp
@@ -68,10 +68,10 @@
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    m_crBkgnd = APPDLG_BACKGROUND_COLOR;
    m_hbrBkgnd = nullptr;
    m_bShowLogWnd = FALSE;
    m_bShowAlarmWnd = FALSE;
    m_pLogDlg = nullptr;
    m_pAlarmDlg = nullptr;
    //m_bShowLogWnd = FALSE;
    //m_bShowAlarmWnd = FALSE;
    //m_pLogDlg = nullptr;
    //m_pAlarmDlg = nullptr;
    m_pTerminalDisplayDlg = nullptr;
    m_pObserver = nullptr;
    m_pPanelMaster = nullptr;
@@ -79,13 +79,15 @@
    m_pPanelAttributes = nullptr;
    m_pPageGraph1 = nullptr;
    m_pPageGraph2 = nullptr;
    m_pPageGraph3 = nullptr;
    m_pPageGraph4 = nullptr;
}
void CServoDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_BUTTON_LOG, m_btnLog);
    DDX_Control(pDX, IDC_BUTTON_ALARM, m_btnAlarm);
    //DDX_Control(pDX, IDC_BUTTON_LOG, m_btnLog);
    //DDX_Control(pDX, IDC_BUTTON_ALARM, m_btnAlarm);
}
BEGIN_MESSAGE_MAP(CServoDlg, CDialogEx)
@@ -96,11 +98,11 @@
    ON_BN_CLICKED(IDCANCEL, &CServoDlg::OnBnClickedCancel)
    ON_WM_CTLCOLOR()
    ON_WM_DESTROY()
    ON_BN_CLICKED(IDC_BUTTON_LOG, &CServoDlg::OnBnClickedButtonLog)
    //ON_BN_CLICKED(IDC_BUTTON_LOG, &CServoDlg::OnBnClickedButtonLog)
    ON_WM_SIZE()
    ON_WM_CLOSE()
    ON_MESSAGE(ID_MSG_LOGDLG_HIDE, &CServoDlg::OnLogDlgHide)
    ON_MESSAGE(ID_MSG_ALARMDLG_HIDE, &CServoDlg::OnAlarmDlgHide)
    //ON_MESSAGE(ID_MSG_LOGDLG_HIDE, &CServoDlg::OnLogDlgHide)
    //ON_MESSAGE(ID_MSG_ALARMDLG_HIDE, &CServoDlg::OnAlarmDlgHide)
    ON_WM_MOVING()
    ON_WM_MOVE()
    ON_COMMAND(ID_MENU_FILE_EXIT, &CServoDlg::OnMenuFileExit)
@@ -109,10 +111,10 @@
    ON_UPDATE_COMMAND_UI(ID_MENU_FILE_SETTINGS, &CServoDlg::OnUpdateMenuFileSettings)
    ON_COMMAND(ID_MENU_FILE_SECSTEST, &CServoDlg::OnMenuFileSecsTest)
    ON_UPDATE_COMMAND_UI(ID_MENU_FILE_SECSTEST, &CServoDlg::OnUpdateMenuFileSecsTest)
    ON_COMMAND(ID_MENU_WND_LOG, &CServoDlg::OnMenuWndLog)
    ON_UPDATE_COMMAND_UI(ID_MENU_WND_LOG, &CServoDlg::OnUpdateMenuWndLog)
    ON_COMMAND(ID_MENU_WND_ALARM, &CServoDlg::OnMenuWndAlarm)
    ON_UPDATE_COMMAND_UI(ID_MENU_WND_ALARM, &CServoDlg::OnUpdateMenuWndAlarm)
    //ON_COMMAND(ID_MENU_WND_LOG, &CServoDlg::OnMenuWndLog)
    //ON_UPDATE_COMMAND_UI(ID_MENU_WND_LOG, &CServoDlg::OnUpdateMenuWndLog)
    //ON_COMMAND(ID_MENU_WND_ALARM, &CServoDlg::OnMenuWndAlarm)
    //ON_UPDATE_COMMAND_UI(ID_MENU_WND_ALARM, &CServoDlg::OnUpdateMenuWndAlarm)
    ON_COMMAND(ID_MENU_TEST_MESSAGE_SET, &CServoDlg::OnMenuTestMessageSet)
    ON_UPDATE_COMMAND_UI(ID_MENU_TEST_MESSAGE_SET, &CServoDlg::OnUpdateMenuTestMessageSet)
    ON_COMMAND(ID_MENU_TEST_MESSAGE_CLEAR, &CServoDlg::OnMenuTestMessageClear)
@@ -120,8 +122,7 @@
    ON_COMMAND(ID_MENU_HELP_ABOUT, &CServoDlg::OnMenuHelpAbout)
    ON_WM_INITMENUPOPUP()
    ON_WM_TIMER()
    ON_BN_CLICKED(IDC_BUTTON_ALARM, &CServoDlg::OnBnClickedButtonAlarm)
    ON_BN_CLICKED(IDC_BUTTON_ALARM, &CServoDlg::OnBnClickedButtonAlarm)
    //ON_BN_CLICKED(IDC_BUTTON_ALARM, &CServoDlg::OnBnClickedButtonAlarm)
    ON_MESSAGE(ID_MSG_PANEL_RESIZE, OnPanelResize)
    ON_NOTIFY(BYHMTAB_SEL_CHANGED, IDC_TAB1, &CServoDlg::OnTabSelChanged)
END_MESSAGE_MAP()
@@ -229,13 +230,18 @@
    m_pPageGraph1->Create(IDD_PAGE_GRAPH1, this);
    m_pPageGraph2 = new CPageGraph2();
    m_pPageGraph2->Create(IDD_PAGE_GRAPH2, this);
    m_pPageGraph3 = new CAlarmDlg();
    m_pPageGraph3->Create(IDD_DIALOG_ALARM, this);
    m_pPageGraph4 = new CLogDlg();
    m_pPageGraph4->Create(IDD_DIALOG_LOG, this);
    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->AddItem("报警", TRUE);
    m_pTab->AddItem("日志", TRUE);
    m_pTab->SetCurSel(0);
    m_pTab->SetBkgndColor(RGB(222, 222, 222));
    ShowChildPage(0);
@@ -264,9 +270,9 @@
    SetTimer(TIMER_ID_CREATE_TERMINAL, 3000, nullptr);
    InitRxWindows();
    OnBnClickedButtonLog();
    UpdateLogBtn();
    UpdateAlarmBtn();
    //OnBnClickedButtonLog();
    //UpdateLogBtn();
    //UpdateAlarmBtn();
    Resize();
@@ -422,25 +428,25 @@
    pCmdUI->Enable(TRUE);
}
void CServoDlg::OnMenuWndLog()
{
    OnBnClickedButtonLog();
}
//void CServoDlg::OnMenuWndLog()
//{
//    OnBnClickedButtonLog();
//}
void CServoDlg::OnUpdateMenuWndLog(CCmdUI* pCmdUI)
{
    pCmdUI->SetCheck(m_bShowLogWnd);
}
//void CServoDlg::OnUpdateMenuWndLog(CCmdUI* pCmdUI)
//{
//    pCmdUI->SetCheck(m_bShowLogWnd);
//}
void CServoDlg::OnMenuWndAlarm()
{
    OnBnClickedButtonAlarm();
}
//void CServoDlg::OnMenuWndAlarm()
//{
//    OnBnClickedButtonAlarm();
//}
void CServoDlg::OnUpdateMenuWndAlarm(CCmdUI* pCmdUI)
{
    pCmdUI->SetCheck(m_bShowAlarmWnd);
}
//void CServoDlg::OnUpdateMenuWndAlarm(CCmdUI* pCmdUI)
//{
//    pCmdUI->SetCheck(m_bShowAlarmWnd);
//}
void CServoDlg::OnMenuFileExit()
{
@@ -519,17 +525,17 @@
{
    CDialogEx::OnDestroy();
    if (m_pLogDlg != nullptr) {
        m_pLogDlg->DestroyWindow();
        delete m_pLogDlg;
        m_pLogDlg = nullptr;
    }
    //if (m_pLogDlg != nullptr) {
    //    m_pLogDlg->DestroyWindow();
    //    delete m_pLogDlg;
    //    m_pLogDlg = nullptr;
    //}
    if (m_pAlarmDlg != nullptr) {
        m_pAlarmDlg->DestroyWindow();
        delete m_pAlarmDlg;
        m_pAlarmDlg = nullptr;
    }
    //if (m_pAlarmDlg != nullptr) {
    //    m_pAlarmDlg->DestroyWindow();
    //    delete m_pAlarmDlg;
    //    m_pAlarmDlg = nullptr;
    //}
    if (m_pTerminalDisplayDlg != nullptr) {
        m_pTerminalDisplayDlg->DestroyWindow();
@@ -567,6 +573,18 @@
        m_pPageGraph2 = nullptr;
    }
    if (m_pPageGraph3 != nullptr) {
        m_pPageGraph3->DestroyWindow();
        delete m_pPageGraph3;
        m_pPageGraph3 = nullptr;
    }
    if (m_pPageGraph4 != nullptr) {
        m_pPageGraph4->DestroyWindow();
        delete m_pPageGraph4;
        m_pPageGraph4 = nullptr;
    }
    if (m_hbrBkgnd != nullptr) {
        ::DeleteObject(m_hbrBkgnd);
    }
@@ -578,85 +596,85 @@
}
void CServoDlg::OnBnClickedButtonAlarm()
{
    m_bShowAlarmWnd = !m_bShowAlarmWnd;
//void CServoDlg::OnBnClickedButtonAlarm()
//{
//    m_bShowAlarmWnd = !m_bShowAlarmWnd;
//
//    // 如果要显示报警窗口,则隐藏日志窗口
//    if (m_bShowLogWnd) {
//        m_bShowLogWnd = false;
//        if (m_pLogDlg != nullptr) {
//            m_pLogDlg->ShowWindow(SW_HIDE);
//            UpdateLogBtn();
//        }
//    }
//
//    if (m_pAlarmDlg == nullptr) {
//        m_pAlarmDlg = new CAlarmDlg();
//        m_pAlarmDlg->Create(IDD_DIALOG_ALARM, this);
//
//        CRect rcWnd;
//        GetWindowRect(&rcWnd);
//        int nHeight = GetSystemMetrics(SM_CYSCREEN) - rcWnd.bottom - 38;
//        if (nHeight < 280) nHeight = 280;
//        m_pAlarmDlg->MoveWindow(rcWnd.left, rcWnd.bottom - 8, rcWnd.Width(), nHeight);
//    }
//    ASSERT(m_pAlarmDlg);
//    m_pAlarmDlg->ShowWindow(m_bShowAlarmWnd ? SW_SHOW : SW_HIDE);
//
//    UpdateAlarmBtn();
//}
    // 如果要显示报警窗口,则隐藏日志窗口
    if (m_bShowLogWnd) {
        m_bShowLogWnd = false;
        if (m_pLogDlg != nullptr) {
            m_pLogDlg->ShowWindow(SW_HIDE);
            UpdateLogBtn();
        }
    }
//void CServoDlg::OnBnClickedButtonLog()
//{
//    m_bShowLogWnd = !m_bShowLogWnd;
//
//    // 如果要显示日志窗口,则隐藏报警窗口
//    if (m_bShowLogWnd) {
//        m_bShowAlarmWnd = false;
//        if (m_pAlarmDlg != nullptr) {
//            m_pAlarmDlg->ShowWindow(SW_HIDE);
//            UpdateAlarmBtn();
//        }
//    }
//
//    if (m_pLogDlg == nullptr) {
//        m_pLogDlg = new CLogDlg();
//        m_pLogDlg->Create(IDD_DIALOG_LOG, this);
//
//        CRect rcWnd;
//        GetWindowRect(&rcWnd);
//        int nHeight = GetSystemMetrics(SM_CYSCREEN) - rcWnd.bottom - 38;
//        if (nHeight < 280) nHeight = 280;
//        m_pLogDlg->MoveWindow(rcWnd.left, rcWnd.bottom - 8, rcWnd.Width(), nHeight);
//    }
//    ASSERT(m_pLogDlg);
//    m_pLogDlg->ShowWindow(m_bShowLogWnd ? SW_SHOW : SW_HIDE);
//
//    UpdateLogBtn();
//}
    if (m_pAlarmDlg == nullptr) {
        m_pAlarmDlg = new CAlarmDlg();
        m_pAlarmDlg->Create(IDD_DIALOG_ALARM, this);
//void CServoDlg::UpdateLogBtn()
//{
//    m_btnLog.SetFrameColor(BS_NORMAL, BTN_LOG_FRAME_NORMAL);
//    m_btnLog.SetFrameColor(BS_HOVER, BTN_LOG_FRAME_HOVER);
//    m_btnLog.SetFrameColor(BS_PRESS, BTN_LOG_FRAME_PRESS);
//    m_btnLog.SetBkgndColor(BS_NORMAL, m_bShowLogWnd ? BTN_LOG_BKGND_PRESS : BTN_LOG_BKGND_NORMAL);
//    m_btnLog.SetBkgndColor(BS_HOVER, BTN_LOG_BKGND_HOVER);
//    m_btnLog.SetBkgndColor(BS_PRESS, BTN_LOG_BKGND_PRESS);
//    m_btnLog.Invalidate();
//}
        CRect rcWnd;
        GetWindowRect(&rcWnd);
        int nHeight = GetSystemMetrics(SM_CYSCREEN) - rcWnd.bottom - 38;
        if (nHeight < 280) nHeight = 280;
        m_pAlarmDlg->MoveWindow(rcWnd.left, rcWnd.bottom - 8, rcWnd.Width(), nHeight);
    }
    ASSERT(m_pAlarmDlg);
    m_pAlarmDlg->ShowWindow(m_bShowAlarmWnd ? SW_SHOW : SW_HIDE);
    UpdateAlarmBtn();
}
void CServoDlg::OnBnClickedButtonLog()
{
    m_bShowLogWnd = !m_bShowLogWnd;
    // 如果要显示日志窗口,则隐藏报警窗口
    if (m_bShowLogWnd) {
        m_bShowAlarmWnd = false;
        if (m_pAlarmDlg != nullptr) {
            m_pAlarmDlg->ShowWindow(SW_HIDE);
            UpdateAlarmBtn();
        }
    }
    if (m_pLogDlg == nullptr) {
        m_pLogDlg = new CLogDlg();
        m_pLogDlg->Create(IDD_DIALOG_LOG, this);
        CRect rcWnd;
        GetWindowRect(&rcWnd);
        int nHeight = GetSystemMetrics(SM_CYSCREEN) - rcWnd.bottom - 38;
        if (nHeight < 280) nHeight = 280;
        m_pLogDlg->MoveWindow(rcWnd.left, rcWnd.bottom - 8, rcWnd.Width(), nHeight);
    }
    ASSERT(m_pLogDlg);
    m_pLogDlg->ShowWindow(m_bShowLogWnd ? SW_SHOW : SW_HIDE);
    UpdateLogBtn();
}
void CServoDlg::UpdateLogBtn()
{
    m_btnLog.SetFrameColor(BS_NORMAL, BTN_LOG_FRAME_NORMAL);
    m_btnLog.SetFrameColor(BS_HOVER, BTN_LOG_FRAME_HOVER);
    m_btnLog.SetFrameColor(BS_PRESS, BTN_LOG_FRAME_PRESS);
    m_btnLog.SetBkgndColor(BS_NORMAL, m_bShowLogWnd ? BTN_LOG_BKGND_PRESS : BTN_LOG_BKGND_NORMAL);
    m_btnLog.SetBkgndColor(BS_HOVER, BTN_LOG_BKGND_HOVER);
    m_btnLog.SetBkgndColor(BS_PRESS, BTN_LOG_BKGND_PRESS);
    m_btnLog.Invalidate();
}
void CServoDlg::UpdateAlarmBtn()
{
    m_btnAlarm.SetFrameColor(BS_NORMAL, BTN_ALARM_FRAME_NORMAL);
    m_btnAlarm.SetFrameColor(BS_HOVER, BTN_ALARM_FRAME_HOVER);
    m_btnAlarm.SetFrameColor(BS_PRESS, BTN_ALARM_FRAME_PRESS);
    m_btnAlarm.SetBkgndColor(BS_NORMAL, m_bShowAlarmWnd ? BTN_ALARM_BKGND_PRESS : BTN_ALARM_BKGND_NORMAL);
    m_btnAlarm.SetBkgndColor(BS_HOVER, BTN_ALARM_BKGND_HOVER);
    m_btnAlarm.SetBkgndColor(BS_PRESS, BTN_ALARM_BKGND_PRESS);
    m_btnAlarm.Invalidate();
}
//void CServoDlg::UpdateAlarmBtn()
//{
//    m_btnAlarm.SetFrameColor(BS_NORMAL, BTN_ALARM_FRAME_NORMAL);
//    m_btnAlarm.SetFrameColor(BS_HOVER, BTN_ALARM_FRAME_HOVER);
//    m_btnAlarm.SetFrameColor(BS_PRESS, BTN_ALARM_FRAME_PRESS);
//    m_btnAlarm.SetBkgndColor(BS_NORMAL, m_bShowAlarmWnd ? BTN_ALARM_BKGND_PRESS : BTN_ALARM_BKGND_NORMAL);
//    m_btnAlarm.SetBkgndColor(BS_HOVER, BTN_ALARM_BKGND_HOVER);
//    m_btnAlarm.SetBkgndColor(BS_PRESS, BTN_ALARM_BKGND_PRESS);
//    m_btnAlarm.Invalidate();
//}
void CServoDlg::OnSize(UINT nType, int cx, int cy)
{
@@ -664,6 +682,8 @@
    if (GetDlgItem(IDC_TAB1) == nullptr) return;
    if (m_pPageGraph1 == nullptr) return;
    if (m_pPageGraph2 == nullptr) return;
    if (m_pPageGraph3 == nullptr) return;
    if (m_pPageGraph4 == nullptr) return;
    
    Resize();
    Invalidate();
@@ -706,19 +726,21 @@
    m_pPageGraph1->MoveWindow(x, y, rcClient.Width() - x, rcClient.Height());
    m_pPageGraph2->MoveWindow(x, y, rcClient.Width() - x, rcClient.Height());
    m_pPageGraph3->MoveWindow(x, y, rcClient.Width() - x, rcClient.Height());
    m_pPageGraph4->MoveWindow(x, y, rcClient.Width() - x, rcClient.Height());
    x = rcClient.right - 8;
    pItem = GetDlgItem(IDC_BUTTON_LOG);
    pItem->GetClientRect(&rcItem);
    x -= rcItem.Width();
    pItem->MoveWindow(x, rcClient.bottom - 8 - rcItem.Height(), rcItem.Width(), rcItem.Height());
    x -= 8;
    //x = rcClient.right - 8;
    //pItem = GetDlgItem(IDC_BUTTON_LOG);
    //pItem->GetClientRect(&rcItem);
    //x -= rcItem.Width();
    //pItem->MoveWindow(x, rcClient.bottom - 8 - rcItem.Height(), rcItem.Width(), rcItem.Height());
    //x -= 8;
    pItem = GetDlgItem(IDC_BUTTON_ALARM);
    pItem->GetClientRect(&rcItem);
    x -= rcItem.Width();
    pItem->MoveWindow(x, rcClient.bottom - 8 - rcItem.Height(), rcItem.Width(), rcItem.Height());
    //pItem = GetDlgItem(IDC_BUTTON_ALARM);
    //pItem->GetClientRect(&rcItem);
    //x -= rcItem.Width();
    //pItem->MoveWindow(x, rcClient.bottom - 8 - rcItem.Height(), rcItem.Width(), rcItem.Height());
}
void CServoDlg::OnClose()
@@ -728,31 +750,31 @@
    CDialogEx::OnClose();
}
LRESULT CServoDlg::OnLogDlgHide(WPARAM wParam, LPARAM lParam)
{
    m_bShowLogWnd = FALSE;
    UpdateLogBtn();
    LOGE("OnLogDlgHide");
//LRESULT CServoDlg::OnLogDlgHide(WPARAM wParam, LPARAM lParam)
//{
//    m_bShowLogWnd = FALSE;
//    UpdateLogBtn();
//    LOGE("OnLogDlgHide");
//
//    unsigned int DATAID, RPTID;
//    DATAID = 111;
//    RPTID = 1001;
//    std::vector<std::string> v;
//    v.push_back("abc");
//    v.push_back("def");
//    theApp.m_model.m_hsmsPassive.requestEventReportSend(DATAID, RPTID, v);
//
//    return 0;
//}
    unsigned int DATAID, RPTID;
    DATAID = 111;
    RPTID = 1001;
    std::vector<std::string> v;
    v.push_back("abc");
    v.push_back("def");
    theApp.m_model.m_hsmsPassive.requestEventReportSend(DATAID, RPTID, v);
    return 0;
}
LRESULT CServoDlg::OnAlarmDlgHide(WPARAM wParam, LPARAM lParam)
{
    m_bShowAlarmWnd = FALSE;
    UpdateAlarmBtn();
    LOGE("OnAlarmDlgHide");
    return 0;
}
//LRESULT CServoDlg::OnAlarmDlgHide(WPARAM wParam, LPARAM lParam)
//{
//    m_bShowAlarmWnd = FALSE;
//    UpdateAlarmBtn();
//    LOGE("OnAlarmDlgHide");
//
//    return 0;
//}
void CServoDlg::OnMoving(UINT fwSide, LPRECT pRect)
{
@@ -761,17 +783,17 @@
void CServoDlg::OnMove(int x, int y)
{
    if (m_pLogDlg != nullptr && !m_pLogDlg->IsZoomed()) {
        CRect rcWnd;
        GetWindowRect(&rcWnd);
        m_pLogDlg->SetWindowPos(nullptr, rcWnd.left, rcWnd.bottom - 8, 0, 0, SWP_NOSIZE);
    }
    //if (m_pLogDlg != nullptr && !m_pLogDlg->IsZoomed()) {
    //    CRect rcWnd;
    //    GetWindowRect(&rcWnd);
    //    m_pLogDlg->SetWindowPos(nullptr, rcWnd.left, rcWnd.bottom - 8, 0, 0, SWP_NOSIZE);
    //}
    if (m_pAlarmDlg != nullptr && !m_pAlarmDlg->IsZoomed()) {
        CRect rcWnd;
        GetWindowRect(&rcWnd);
        m_pAlarmDlg->SetWindowPos(nullptr, rcWnd.left, rcWnd.bottom - 8, 0, 0, SWP_NOSIZE);
    }
    //if (m_pAlarmDlg != nullptr && !m_pAlarmDlg->IsZoomed()) {
    //    CRect rcWnd;
    //    GetWindowRect(&rcWnd);
    //    m_pAlarmDlg->SetWindowPos(nullptr, rcWnd.left, rcWnd.bottom - 8, 0, 0, SWP_NOSIZE);
    //}
    CDialogEx::OnMove(x, y);
}
@@ -816,9 +838,9 @@
void CServoDlg::ShowChildPage(int index)
{
    ASSERT(0 <= index && index < 3);
    static CWnd* pPages[] = { m_pPageGraph1, m_pPageGraph2 };
    for (int i = 0; i < 2; i++) {
    ASSERT(0 <= index && index < 4);
    static CWnd* pPages[] = { m_pPageGraph1, m_pPageGraph2, m_pPageGraph3, m_pPageGraph4 };
    for (int i = 0; i < 3; i++) {
        pPages[i]->ShowWindow(i == index ? SW_SHOW : SW_HIDE);
    }
}
SourceCode/Bond/Servo/ServoDlg.h
@@ -28,20 +28,22 @@
private:
    void InitRxWindows();
    void Resize();
    void UpdateLogBtn();
    void UpdateAlarmBtn();
    //void UpdateLogBtn();
    //void UpdateAlarmBtn();
    void ShowChildPage(int index);
private:
    IObserver* m_pObserver;
    BOOL m_bShowLogWnd;
    BOOL m_bShowAlarmWnd;
    CLogDlg* m_pLogDlg;
    CAlarmDlg* m_pAlarmDlg;
    //BOOL m_bShowLogWnd;
    //BOOL m_bShowAlarmWnd;
    //CLogDlg* m_pLogDlg;
    //CAlarmDlg* m_pAlarmDlg;
    CTerminalDisplayDlg* m_pTerminalDisplayDlg;
    CPageGraph1* m_pPageGraph1;
    CPageGraph2* m_pPageGraph2;
    CAlarmDlg*     m_pPageGraph3;
    CLogDlg*     m_pPageGraph4;
// 对话框数据
@@ -58,8 +60,8 @@
    HICON m_hIcon;
    COLORREF m_crBkgnd;
    HBRUSH m_hbrBkgnd;
    CBlButton m_btnLog;
    CBlButton m_btnAlarm;
    //CBlButton m_btnLog;
    //CBlButton m_btnAlarm;
    CPanelMaster* m_pPanelMaster;
    CPanelEquipment* m_pPanelEquipment;
    CPanelAttributes* m_pPanelAttributes;
@@ -75,11 +77,11 @@
    afx_msg void OnBnClickedCancel();
    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
    afx_msg void OnDestroy();
    afx_msg void OnBnClickedButtonLog();
    //afx_msg void OnBnClickedButtonLog();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnClose();
    afx_msg LRESULT OnLogDlgHide(WPARAM wParam, LPARAM lParam);
    afx_msg LRESULT OnAlarmDlgHide(WPARAM wParam, LPARAM lParam);
    //afx_msg LRESULT OnLogDlgHide(WPARAM wParam, LPARAM lParam);
    //afx_msg LRESULT OnAlarmDlgHide(WPARAM wParam, LPARAM lParam);
    afx_msg void OnMoving(UINT fwSide, LPRECT pRect);
    afx_msg void OnMove(int x, int y);
    afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu);
@@ -87,10 +89,10 @@
    afx_msg void OnUpdateMenuFileSettings(CCmdUI* pCmdUI);
    afx_msg void OnMenuFileSecsTest();
    afx_msg void OnUpdateMenuFileSecsTest(CCmdUI* pCmdUI);
    afx_msg void OnMenuWndLog();
    afx_msg void OnUpdateMenuWndLog(CCmdUI* pCmdUI);
    afx_msg void OnMenuWndAlarm();
    afx_msg void OnUpdateMenuWndAlarm(CCmdUI* pCmdUI);
    //afx_msg void OnMenuWndLog();
    //afx_msg void OnUpdateMenuWndLog(CCmdUI* pCmdUI);
    //afx_msg void OnMenuWndAlarm();
    //afx_msg void OnUpdateMenuWndAlarm(CCmdUI* pCmdUI);
    afx_msg void OnMenuFileExit();
    afx_msg void OnUpdateMenuFileExit(CCmdUI* pCmdUI);
    afx_msg void OnMenuTestMessageSet();
@@ -99,7 +101,7 @@
    afx_msg void OnUpdateMenuTestMessageClear(CCmdUI* pCmdUI);
    afx_msg void OnMenuHelpAbout();
    afx_msg void OnTimer(UINT_PTR nIDEvent);
    afx_msg void OnBnClickedButtonAlarm();
    //afx_msg void OnBnClickedButtonAlarm();
    afx_msg LRESULT OnPanelResize(WPARAM wParam, LPARAM lParam);
    afx_msg void OnTabSelChanged(NMHDR* nmhdr, LRESULT* result);
};
SourceCode/Bond/x64/Release/configuration.ini
@@ -120,3 +120,12 @@
Col_0_Width=0
Col_1_Width=222
Col_2_Width=1137
[AlarmListCtrl]
Col_0_Width=0
Col_1_Width=80
Col_2_Width=180
Col_3_Width=80
Col_4_Width=80
Col_5_Width=100
Col_6_Width=80
Col_7_Width=248