From 829fe6c6bc33d53fda9c31fd45a37e1df87befff Mon Sep 17 00:00:00 2001
From: mrDarker <mr.darker@163.com>
Date: 星期五, 30 一月 2026 11:16:24 +0800
Subject: [PATCH] Merge branch 'clh' into liuyang
---
SourceCode/Bond/Servo/CUserXLogDlg.cpp | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 178 insertions(+), 0 deletions(-)
diff --git a/SourceCode/Bond/Servo/CUserXLogDlg.cpp b/SourceCode/Bond/Servo/CUserXLogDlg.cpp
new file mode 100644
index 0000000..58e8950
--- /dev/null
+++ b/SourceCode/Bond/Servo/CUserXLogDlg.cpp
@@ -0,0 +1,178 @@
+锘�#include "stdafx.h"
+#include "Servo.h"
+#include "CUserXLogDlg.h"
+#include "afxdialogex.h"
+#include <functional>
+#include <vector>
+#include <sstream>
+
+namespace
+{
+ std::wstring ReadBufferVia(const std::function<int(wchar_t*, int)>& fn)
+ {
+ int need = fn(nullptr, 0);
+ if (need <= 0) {
+ return L"";
+ }
+
+ std::wstring buffer;
+ buffer.resize(static_cast<size_t>(need));
+ if (fn(buffer.data(), need) == UX_OK) {
+ if (!buffer.empty() && buffer.back() == L'\0') {
+ buffer.pop_back();
+ }
+ return buffer;
+ }
+
+ return L"";
+ }
+
+ std::vector<std::wstring> SplitLines(const std::wstring& text)
+ {
+ std::vector<std::wstring> lines;
+ std::wstringstream ss(text);
+ std::wstring line;
+ while (std::getline(ss, line)) {
+ lines.push_back(line);
+ }
+ return lines;
+ }
+}
+
+IMPLEMENT_DYNAMIC(CUserXLogDlg, CDialogEx)
+
+CUserXLogDlg::CUserXLogDlg(CWnd* pParent)
+ : CDialogEx(IDD_DIALOG_USERX_LOG, pParent)
+{
+}
+
+CUserXLogDlg::~CUserXLogDlg()
+{
+}
+
+void CUserXLogDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_LIST1, m_listLogs);
+}
+
+BEGIN_MESSAGE_MAP(CUserXLogDlg, CDialogEx)
+ ON_WM_SIZE()
+ ON_WM_DESTROY()
+END_MESSAGE_MAP()
+
+BOOL CUserXLogDlg::OnInitDialog()
+{
+ CDialogEx::OnInitDialog();
+
+ InitListCtrl();
+ RefreshLogs();
+ AdjustLayout();
+
+ return TRUE;
+}
+
+void CUserXLogDlg::InitListCtrl()
+{
+ DWORD dwStyle = m_listLogs.GetExtendedStyle();
+ m_listLogs.SetExtendedStyle(dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
+ m_listLogs.InsertColumn(0, _T("鏃堕棿"), LVCFMT_LEFT, 180);
+ m_listLogs.InsertColumn(1, _T("鐢ㄦ埛"), LVCFMT_LEFT, 120);
+ m_listLogs.InsertColumn(2, _T("鍔ㄤ綔"), LVCFMT_LEFT, 120);
+ m_listLogs.InsertColumn(3, _T("鎻忚堪"), LVCFMT_LEFT, 200);
+}
+
+void CUserXLogDlg::RefreshLogs()
+{
+ m_logs.clear();
+ m_listLogs.DeleteAllItems();
+
+ auto allLogs = ReadBufferVia([](wchar_t* buffer, int size) {
+ return UX_QueryLogs(200, buffer, size);
+ });
+
+ for (auto& rawLine : SplitLines(allLogs)) {
+ if (rawLine.empty()) continue;
+
+ auto trim = [](std::wstring value) {
+ size_t first = value.find_first_not_of(L" \t\r\n");
+ size_t last = value.find_last_not_of(L" \t\r\n");
+ if (first == std::wstring::npos || last == std::wstring::npos) {
+ return std::wstring();
+ }
+ return value.substr(first, last - first + 1);
+ };
+
+ auto takeField = [&](size_t& cursor) {
+ if (cursor == std::wstring::npos || cursor >= rawLine.length()) {
+ return std::wstring();
+ }
+ size_t pos = rawLine.find(L',', cursor);
+ std::wstring part = (pos == std::wstring::npos) ? rawLine.substr(cursor) : rawLine.substr(cursor, pos - cursor);
+ cursor = (pos == std::wstring::npos) ? std::wstring::npos : pos + 1;
+ return trim(part);
+ };
+
+ size_t cursor = 0;
+ LogItem item;
+ item.time = takeField(cursor).c_str();
+ item.user = takeField(cursor).c_str();
+ item.action = takeField(cursor).c_str();
+ if (cursor != std::wstring::npos && cursor < rawLine.length()) {
+ item.detail = trim(rawLine.substr(cursor)).c_str();
+ }
+
+ m_logs.push_back(item);
+ }
+
+ for (size_t i = 0; i < m_logs.size(); ++i) {
+ const auto& log = m_logs[i];
+ int row = m_listLogs.InsertItem(static_cast<int>(i), log.time);
+ m_listLogs.SetItemText(row, 1, log.user);
+ m_listLogs.SetItemText(row, 2, log.action);
+ m_listLogs.SetItemText(row, 3, log.detail);
+ }
+}
+
+void CUserXLogDlg::AdjustLayout()
+{
+ if (!::IsWindow(m_listLogs.GetSafeHwnd())) {
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect(&rcClient);
+ const int margin = 7;
+
+ CRect rcList(margin, margin, rcClient.right - margin, rcClient.bottom - 40);
+ m_listLogs.MoveWindow(rcList);
+
+ auto moveButton = [&](int id, int order) {
+ if (CWnd* pBtn = GetDlgItem(id)) {
+ CRect rc;
+ pBtn->GetWindowRect(&rc);
+ ScreenToClient(&rc);
+ int width = rc.Width();
+ int height = rc.Height();
+ rc.left = rcClient.right - margin - width - order * (width + margin);
+ rc.right = rc.left + width;
+ rc.top = rcClient.bottom - margin - height;
+ rc.bottom = rc.top + height;
+ pBtn->MoveWindow(rc);
+ }
+ };
+
+ moveButton(IDOK, 1);
+ moveButton(IDCANCEL, 0);
+}
+
+void CUserXLogDlg::OnSize(UINT nType, int cx, int cy)
+{
+ CDialogEx::OnSize(nType, cx, cy);
+ AdjustLayout();
+}
+
+void CUserXLogDlg::OnDestroy()
+{
+ CDialogEx::OnDestroy();
+}
--
Gitblit v1.9.3