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

RichEdit 控制項兩大常見問題解決:DDX 資料截斷與訊息映射錯誤

     編輯:關於C++

問題一:DDX_Text 處理超過 64KB 文字資料截斷

現象:使用 ClassWizard 將 RichEdit 控制項關聯 CString 變數,透過 DDX_Text 交換資料時,超過 64KB 的文字會遺失。

原因:DDX_Text 內部呼叫 GetWindowText,發送 WM_GETTEXT 訊息,但該訊息無法處理超過 64KB 的資料。

解決方案:自訂 DDX_RichText 函數,使用 EM_STREAMOUT 訊息串流讀取:

DWORD CALLBACK ES2MemCallBack(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
    LPTSTR& lpszStrFill = *(LPTSTR*)dwCookie;
    memcpy(lpszStrFill, pbBuff, *pcb = cb);
    lpszStrFill += cb;
    *lpszStrFill = TCHAR('\0');
    return 0;
}

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

並修改專案 .clw 檔案註冊新 DDX 函數:

ExtraDDXCount=1
ExtraDDX1=7;;TextOver64KB;CString;;RichText;Retrieves text in excess of 64KB from RichEdit controls

或手動將程式碼中 DDX_Text 改為 DDX_RichText 並移出 ClassWizard 管理區塊。

問題二:EN_SETFOCUS / EN_KILLFOCUS 訊息無法響應

現象:ClassWizard 加入 EN_SETFOCUS、EN_KILLFOCUS 處理函數,但完全不被呼叫。

原因:ClassWizard 錯誤生成 ON_NOTIFY 宏,正確應為 ON_EN_SETFOCUS/ON_EN_KILLFOCUS(命令訊息而非通知訊息)。

正確訊息映射:

ON_EN_SETFOCUS(IDC_RICHEDIT1, OnSetfocusRichedit1)
ON_EN_KILLFOCUS(IDC_RICHEDIT1, OnKillfocusRichedit1)

響應函數宣告:

afx_msg void OnSetfocusRichedit1();
afx_msg void OnKillfocusRichedit1();

需手動修正訊息映射巨集與函數簽章。

補充:RichEdit 不顯示在 ClassWizard 控制項清單

若 RichEdit 控制項 ID 未出現在 ClassWizard,需手動在 DoDataExchange 中加入:

DDX_Control(pDX, IDC_RICHEDIT1, m_richEditCtrl);
DDX_Text(pDX, IDC_RICHEDIT1, m_richedit);
DDV_MaxChars(pDX, m_richedit, 10);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved