MFC 中用 DDX_Text 將 CRichEditCtrl 內容與 CString 交換時,若文字超過 64KB 會丟失。原因:DDX_Text 呼叫 GetWindowText → 發送 WM_GETTEXT,但 WM_GETTEXT 限制單次複製 64KB。
RichEdit 支援流式讀取 EM_STREAMOUT (配合 EDITSTREAM 回呼),無大小限制。
// 回呼函數:將流資料追加到 CString 緩衝區
DWORD CALLBACK ES2MemCallBack(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
LPTSTR& lpszStrFill = *(LPTSTR*)dwCookie;
memcpy(lpszStrFill, pbBuff, *pcb = cb);
lpszStrFill += cb;
*lpszStrFill = _T('\0');
return 0;
}
// 自訂 DDX 函數
void AFXAPI DDX_RichText(CDataExchange* pDX, int nIDC, CString& value)
{
extern void AFXAPI AfxSetWindowText(HWND hWndCtrl, LPCTSTR lpszNew);
HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
if (pDX->m_bSaveAndValidate) { // 從控制項取值
int nLen = ::GetWindowTextLength(hWndCtrl);
LPTSTR lpszStrFill = value.GetBufferSetLength(nLen);
EDITSTREAM es = { (DWORD_PTR)&lpszStrFill, 0, ES2MemCallBack };
::SendMessage(hWndCtrl, EM_STREAMOUT, SF_TEXT, (LPARAM)&es);
value.ReleaseBuffer();
} else { // 設值到控制項
AfxSetWindowText(hWndCtrl, value);
}
}
StdAfx.cpp 或單獨 .cpp)。DoDataExchange 中替換:DDX_RichText(pDX, IDC_RICHEDIT, m_strContent);此法同樣適用於 CRichEditCtrl::StreamIn/StreamOut 直接呼叫場景。