// CActivityDialog.cpp: 历史活动展示对话框(一次性快照,无子连接) #include "stdafx.h" #include "afxdialogex.h" #include "CActivityDialog.h" #include "resource.h" #include "../../common/commands.h" IMPLEMENT_DYNAMIC(CActivityDialog, CDialogEx) CActivityDialog::CActivityDialog(CWnd* pParent, Server* pServer, CONTEXT_OBJECT* pContext) : CDialogBase(IDD_DIALOG_CLIENT_LOG, pParent, pServer, pContext, 0) { } CActivityDialog::~CActivityDialog() { } void CActivityDialog::DoDataExchange(CDataExchange* pDX) { CDialogBase::DoDataExchange(pDX); DDX_Control(pDX, IDC_EDIT_LOG, m_editLog); } BEGIN_MESSAGE_MAP(CActivityDialog, CDialogBase) ON_WM_SIZE() END_MESSAGE_MAP() BOOL CActivityDialog::OnInitDialog() { CDialogBase::OnInitDialog(); SetWindowText(_TR("历史活动") + " - " + m_IPAddress); HICON hIcon = AfxGetApp()->LoadIcon(IDI_CLIENTLOG); SetIcon(hIcon, TRUE); SetIcon(hIcon, FALSE); // 用 Segoe UI:MBCS 工程里模板默认字体是 Microsoft Sans Serif(无 Dingbats 字形), // 显式指定 Segoe UI,中文走字体链接到微软雅黑、Dingbats(✻/✦)走 Segoe UI Symbol 回退。 m_font.CreatePointFont(90, _T("Segoe UI")); m_editLog.SetFont(&m_font); // 重建为 Unicode 编辑框:这是 ✻/✦ 能正确显示的关键。重建时已保留上面的字体。 RebuildEdit(m_editLog); return TRUE; } void CActivityDialog::RebuildEdit(CEdit& m_edit) { CRect rc; m_edit.GetWindowRect(&rc); ScreenToClient(&rc); DWORD style = m_edit.GetStyle(); DWORD exStyle = m_edit.GetExStyle(); HFONT hFont = (HFONT)m_edit.SendMessage(WM_GETFONT, 0, 0); UINT ctrlID = m_edit.GetDlgCtrlID(); m_edit.DestroyWindow(); HWND hEdit = ::CreateWindowExW( exStyle, L"EDIT", L"", style, rc.left, rc.top, rc.Width(), rc.Height(), this->GetSafeHwnd(), (HMENU)(UINT_PTR)ctrlID, AfxGetInstanceHandle(), NULL); m_edit.Attach(hEdit); if (hFont) m_edit.SendMessage(WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0)); } void CActivityDialog::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); } // 快照模式:无子连接,OnReceiveComplete 空实现(纯虚函数必须覆盖) void CActivityDialog::OnReceiveComplete() { } void CActivityDialog::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]; } // 服务端是 MBCS 工程,编辑框走 A 接口会把 UTF-8 中文当 ANSI 处理导致乱码; // 与"活动窗口"列一致,用 W 接口显示:先把 UTF-8 转成宽字符,再走 WM_SETTEXTW 写入。 // (编辑框已在 OnInitDialog 中重建为 Unicode 窗口,SetWindowTextW 不会经过 CP_ACP 回转。) int wlen = MultiByteToWideChar(CP_UTF8, 0, norm.c_str(), (int)norm.size(), NULL, 0); if (wlen <= 0) return; std::wstring w(wlen, L'\0'); MultiByteToWideChar(CP_UTF8, 0, norm.c_str(), (int)norm.size(), &w[0], wlen); ::SetWindowTextW(m_editLog.GetSafeHwnd(), w.c_str()); }