Files
SimpleRemoter/server/2015Remote/CClientLog.cpp
yuanyuanxiang 23c9a4f242 Feature: add client log dialog with auto-refresh, icon and menu bitmap
- CClientLogManager: push thread sends incremental logs every 3s; join() instead of detach() prevents use-after-free on shutdown
- CClientLog::OnReceiveComplete: handles TOKEN_REPORT_LOG on IOCP thread via PostMessage, fixing incremental packets being silently dropped
- Dialog icon (ClientLog.ico) and menu bitmap (ClientLog.bmp) added; OnInitDialog loads icon; IDR_MENU_LIST_ONLINE "运行日志" item gets the bitmap

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-13 19:02:25 +02:00

107 lines
2.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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\nWindows 编辑框换行需要 \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;
}