首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

解決 RichEdit 控制項 DDX 數據交換超過 64KB 丟失問題 (MFC/VC++)

     編輯:VC 教學

問題現象

MFC 中用 DDX_Text 將 CRichEditCtrl 內容與 CString 交換時,若文字超過 64KB 會丟失。原因:DDX_Text 呼叫 GetWindowText → 發送 WM_GETTEXT,但 WM_GETTEXT 限制單次複製 64KB。

解決方案:自訂 DDX_RichText 使用 EM_STREAMOUT

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);
    }
}

使用方法

  1. 將上述兩個函數加入專案 (如 StdAfx.cpp 或單獨 .cpp)。
  2. 在對話框類別的 DoDataExchange 中替換:DDX_RichText(pDX, IDC_RICHEDIT, m_strContent);
  3. 重新編譯,即可正確交換任意大小的 RichEdit 內容。

此法同樣適用於 CRichEditCtrl::StreamIn/StreamOut 直接呼叫場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved