Fix: Decode host-management and clipboard text as GBK/UTF-8 on non-Chinese systems

The 主机管理 dialog wrote client data (process names, window titles, net
connection state, software entries, IE history, favorites, services,
scheduled tasks, hosts) through the ANSI InsertItem/SetItemText path, which
re-converts through CP_ACP and garbles Chinese when the operator machine
runs a non-Chinese ACP. Decode each client string with its real code page
and write it via LVM_SETITEMTEXTW, mirroring SystemDlg::SetClientTextItem.
Scheduled-task columns are split by encoding: name/path/exe come from the
client as UTF-8 (BSTRToUTF8) while the status literal stays GBK. Also detect
a UTF-8 BOM in the hosts file so a Notepad-saved hosts (EF BB BF) no longer
shows "锘?" on its first line.

In the keyboard dialog, the clipboard preview edit was an ANSI-class window
filled via utf8_to_ansi (CP_ACP) + SetWindowTextA, so Chinese was replaced
with '?' before it reached the control. Rebuild m_EditClipText as a
Unicode-class window and write the UTF-8 clipboard text via SetWindowTextW,
matching the m_edit record control.

Co-Authored-By: deepseek-v4-pro
This commit is contained in:
yuanyuanxianganddeepseek-v4-pro committed 2026-10-12 15:41:24 +02:00
1 parent ca6f76565c
commit d2149851b2
2 files changed
+88 -32

No files matched your search

+15 -2
View File
@@ -123,6 +123,9 @@ BOOL CKeyBoardDlg::OnInitDialog()
// 后,控件内部以 Unicode 存储,W 版消息直通,不再走 CP_ACP。
// -----------------------------------------------------------------
RebuildEdit(m_edit);
// 剪切板显示框同样重建为 Unicode 控件,ShowClipboardText 全程走 W 版消息,
// 否则 MBCS 下 SetWindowTextA 会在 A<->W 边界按 CP_ACP 转码,中文丢失。
RebuildEdit(m_EditClipText);
m_edit.SetLimitText(MAXDWORD); // 设置最大长度
auto rule = utf8_to_ansi((char*)m_TextRule.param);
@@ -171,9 +174,19 @@ void CKeyBoardDlg::OnReceiveComplete()
LRESULT CKeyBoardDlg::ShowClipboardText(WPARAM wParam, LPARAM lParam)
{
char* buf = (char*)wParam;
std::string text = utf8_to_ansi(buf);
// 剪切板文本是 UTF-8(client/my_clip.h 的 clip::get_text 从 CF_UNICODETEXT 转出)。
// 直接转宽字符串,用 W 版写入重建后的 Unicode 控件,绕开 utf8_to_ansi 的 CP_ACP
// 回转——非中文系统(德语/英语)上中文也能正常显示(与 m_edit 同法)。
std::wstring w;
if (buf && buf[0]) {
int wlen = MultiByteToWideChar(CP_UTF8, 0, buf, -1, NULL, 0);
if (wlen > 1) {
w.resize(wlen - 1);
MultiByteToWideChar(CP_UTF8, 0, buf, -1, &w[0], wlen);
}
}
SAFE_DELETE_ARRAY(buf);
m_EditClipText.SetWindowTextA(text.c_str());
::SetWindowTextW(m_EditClipText.GetSafeHwnd(), w.c_str());
return S_OK;
}