在 `content += str;` 賦值時,觸發了編輯控件的 `EN_CHANGE` 通知消息,進而調用 `OnEnChange()` 處理函數,該函數內部調用了 `writein()` 寫入操作,**導致讀取過程中被寫入操作打斷/干擾**,造成數據異常。
void EditView::ReadTitle(CString strName) {
CString content = "";
CStdioFile file;
CString fileName = strName;
if (file.Open(fileName, CFile::modeRead | CFile::typeText)) {
file.SeekToBegin();
CString str;
int len = 512 - 2;
file.ReadString(str); // 讀取一行
if ("" != str)
content += str; // 💥 此處觸發 OnEnChange -> writein()
file.Close();
} else {
AfxMessageBox("讀取失敗!");
}
this->SetWindowText(content); // 設置窗口文本
}
void EditView::ReadTitle(CString strName) {
CString content = "";
CStdioFile file;
if (file.Open(strName, CFile::modeRead | CFile::typeText)) {
// 1. 斷開 EN_CHANGE 消息映射(或設置標志位)
// 方法 A:修改消息映射表(需重新編譯)
// 方法 B:使用標志位(運行時動態控制)
m_bReadingFile = true; // 類成員變量 BOOL m_bReadingFile = FALSE;
file.SeekToBegin();
CString str;
while (file.ReadString(str)) { // 循環讀取所有行
if (!str.IsEmpty()) {
content += str;
content += _T("\r\n"); // 保留換行
}
}
file.Close();
m_bReadingFile = false; // 恢復
// 2. 統一設置文本(單次觸發 EN_CHANGE)
SetWindowText(content);
} else {
AfxMessageBox(_T("讀取失敗!"));
}
}
// OnEnChange 中判斷標志位
void EditView::OnEnChange() {
if (m_bReadingFile) return; // 讀取文件期間忽略變更通知
// 正常業務邏輯
writein();
}
void EditView::ReadTitle(CString strName) {
CString content;
CStdioFile file;
if (file.Open(strName, CFile::modeRead | CFile::typeText)) {
CString str, line;
while (file.ReadString(line)) {
str += line;
str += _T("\r\n");
}
file.Close();
content = str; // 先組裝完整內容
}
// 單次設置,避免多次觸發
SetWindowText(content);
}
CFile file;
if (file.Open(strName, CFile::modeRead | CFile::typeText)) {
ULONGLONG len = file.GetLength();
CString content;
content.GetBufferSetLength(len + 1);
file.Read(content.GetBuffer(len), len);
content.ReleaseBuffer();
file.Close();
SetWindowText(content);
}
// 在 OnEnChange 開頭添加調試輸出
void EditView::OnEnChange() {
TRACE(_T("OnEnChange called, m_bReadingFile=%d\n"), m_bReadingFile);
if (m_bReadingFile) return;
// ...
}
通過 Output 窗口觀察調用堆棧,快速定位遞歸調用源頭。