#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();
|
}
|