// CClientLog.cpp: 实现文件 #include "stdafx.h" #include "afxdialogex.h" #include "CClientLog.h" #include "resource.h" #include "../../common/commands.h" IMPLEMENT_DYNAMIC(CClientLog, CDialogEx) CClientLog::CClientLog(CWnd* pParent, Server* pServer, CONTEXT_OBJECT* pContext) : CDialogBase(IDD_DIALOG_CLIENT_LOG, pParent, pServer, pContext, 0) { } CClientLog::~CClientLog() { } void CClientLog::DoDataExchange(CDataExchange* pDX) { CDialogBase::DoDataExchange(pDX); DDX_Control(pDX, IDC_EDIT_LOG, m_editLog); } BEGIN_MESSAGE_MAP(CClientLog, CDialogBase) ON_WM_DESTROY() ON_WM_SIZE() ON_MESSAGE(WM_REPORT_CLIENT_LOG, OnReportLog) END_MESSAGE_MAP() BOOL CClientLog::OnInitDialog() { CDialogBase::OnInitDialog(); SetWindowText(_TR("客户端日志") + " - " + m_IPAddress); HICON hIcon = AfxGetApp()->LoadIcon(IDI_CLIENTLOG); SetIcon(hIcon, TRUE); SetIcon(hIcon, FALSE); CFont* pFont = new CFont(); pFont->CreatePointFont(85, _T("Consolas")); m_editLog.SetFont(pFont); return TRUE; } void CClientLog::OnSize(UINT nType, int cx, int cy) { CDialogBase::OnSize(nType, cx, cy); if (m_editLog.GetSafeHwnd() && cx > 0 && cy > 0) m_editLog.MoveWindow(7, 7, cx - 14, cy - 14); } void CClientLog::OnDestroy() { if (m_ContextObject && m_bConnected) { BYTE cmd = COMMAND_BYE; m_ContextObject->Send2Client(&cmd, 1); } CDialogBase::OnDestroy(); } void CClientLog::AppendLog(const std::string& text) { if (text.empty()) return; // \n → \r\n,Windows 编辑框换行需要 \r\n std::string norm; norm.reserve(text.size() + 64); for (size_t i = 0; i < text.size(); ++i) { if (text[i] == '\n' && (i == 0 || text[i - 1] != '\r')) norm += '\r'; norm += text[i]; } // 超过 512KB 时截断旧内容 int existing = m_editLog.GetWindowTextLength(); if (existing > 512 * 1024) { CString cur; m_editLog.GetWindowText(cur); m_editLog.SetWindowText(cur.Mid(cur.GetLength() - 256 * 1024)); } // 追加到末尾并滚动 CString add = CA2T(norm.c_str(), CP_UTF8); m_editLog.SetSel(-1, -1); m_editLog.ReplaceSel(add); m_editLog.SendMessage(EM_SCROLLCARET); } void CClientLog::OnReceiveComplete() { auto& buf = m_ContextObject->InDeCompressedBuffer; if (buf.GetBYTE(0) != TOKEN_REPORT_LOG) return; unsigned len = buf.GetBufferLen(); auto* pText = new std::string((char*)(buf.GetBuffer() + 1), len > 1 ? len - 1 : 0); if (!PostMessage(WM_REPORT_CLIENT_LOG, 0, (LPARAM)pText)) delete pText; } LRESULT CClientLog::OnReportLog(WPARAM /*wParam*/, LPARAM lParam) { std::string* pText = reinterpret_cast(lParam); if (pText) { AppendLog(*pText); delete pText; } return 0; }