The Win32 EDIT control caps text at ~32K/64K chars by default, so the client log dialog silently stopped accepting appends long before the 512KB truncation logic could run. Call SetLimitText(0) in both CClientLog and CActivityDialog to lift the cap. Also unify newline handling in Logger: each entry now ends with exactly one '\n' at the source, so the in-memory ring-buffer dump (used by the TCP log query) splits into lines correctly instead of relying on every Mprintf caller ending its format with '\n'. writeToFile drops the extra std::endl accordingly. Additionally fix a CFont leak in CClientLog::OnInitDialog by moving the font to a member. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
107 lines
2.9 KiB
C++
107 lines
2.9 KiB
C++
// 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);
|
||
m_font.CreatePointFont(85, _T("Consolas"));
|
||
m_editLog.SetFont(&m_font);
|
||
m_editLog.SetLimitText(0); // 解除 EDIT 控件默认长度上限,改由 AppendLog 的 512KB 逻辑管理
|
||
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<std::string*>(lParam);
|
||
if (pText) {
|
||
AppendLog(*pText);
|
||
delete pText;
|
||
}
|
||
return 0;
|
||
}
|