| 導購 | 订阅 | 在线投稿
分享
 
 
 

關于RICHEDIT的兩個問題

來源:互聯網  2007-02-08 23:31:28  評論

問題1:

RichEditCtrl在用DDX進行數據交換的時候會發生數據丟失問題?爲什麽!

當我們在拖了一個控件到程序裏後,通常的做發是Ctrl+W,用類向導給控件關聯一個變量,然後依靠DDX/DDV進行數據交換,如果我們用同樣的方法來給RICHEDIT關聯一個CString類型的變量就會存在一個問題,就是如果我們的數據大于了64K,數據就會丟失。

通過查MSDN發現,WM_GETTEXT消息並沒有設計在RICHEDIT的數據大于64K的時候怎樣處理。而類向導生成的代碼是用DDX_Text來交換控件和CString變量的數據。恰好,DDX_Text函數是調用GetWindowText函數,而這個函數又會發出WM_GETTEXT消息到控件來返回控件裏的數據。WM_GETTEXT消息不能接受超過64K的數據,因此導致了RICHEDIT在數據交換的時候發生了丟失。

爲了解決這個問題,我們要用到DDX_RichText函數。添加下面兩個函數到工程

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文件,用文本方式打開.clw文件。參考裏面類的格式加下面兩行代碼:

ExtraDDXCount=1

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

如果沒有采用上面的步驟,我們就需要手動修改代碼,把所有的DDX_Text改爲DDX_RichText。同時要把他們移到類向導控制代碼的外面。也就是移出:

//{{AFX_DATA_INIT(...)

//}}AFX_DATA_INIT

//{{AFX_DATA_MAP(...)

//}}AFX_DATA_MAP

reference:

Q280447 BUG: Text from a Rich Edit Control Is Truncated During Dialog Data Exchange (DDX)

問題2:

當我們用類向導給richedit添加了EN_SETFOCUS, EN_KILLFOCUS的函數後卻不能響應,我發現這個響應函數根本就沒有被調用。即使是一個MessageBox()函數也不會調用。

原來是默認的消息映射添加錯誤了。

正確的消息影射和響應應該是:

ON_EN_SETFOCUS(IDC_RICHEDIT1,OnSetfocusRichedit1)

ON_EN_KILLFOCUS(IDC_RICHEDIT1,OnKillfocusRichedit1)

響應函數形式爲:

afx_msg void OnSetfocusRichedit1();

afx_msg void OnKillfocusRichedit1();

但是如果我們用類向導來直接添加,生成的代碼卻是:

ON_NOTIFY(EN_SETFOCUS, IDC_RICHEDIT1, OnSetfocusRichedit1)

ON_NOTIFY(EN_KILLFOCUS, IDC_RICHEDIT1, OnKillfocusRichedit1)

我們需要自己手動改爲上面的形式。

還有一個問題就是RichEditCtrl有時候不會出現在類向導的控件ID列表裏。這就需要我們自己添加DDX/DDV函數。自己動手啦!^_^

-- sampledlg.h --

class CSampleDlg : public CDialog

{

public:

CSampleDlg(CWnd* pParent = NULL);

// Dialog Data

//{{AFX_DATA(CSampleDlg)

enum { IDD = IDD_SAMPLE_DIALOG };

CString m_edit; // Added by ClassWizard for an edit control

//}}AFX_DATA

// Manually add member variables for the rich edit control

CRichEditCtrl m_richEditCtrl;

.......

sampledlg.cpp --

......

void CSampleDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CSampleDlg)

DDX_Text(pDX, IDC_EDIT, m_edit);

DDV_MaxChars(pDX, m_edit, 10);

//}}AFX_DATA_MAP

// Manually add DDX_Control, DDX_Text and DDV_MaxChars for the

// rich edit control

DDX_Control(pDX, IDC_RICHEDIT1, m_richEditCtrl);

DDX_Text(pDX, IDC_RICHEDIT1, m_richedit);

DDV_MaxChars(pDX, m_richedit, 10);

}

reference:

Q181664

問題1: RichEditCtrl在用DDX進行數據交換的時候會發生數據丟失問題?爲什麽! 當我們在拖了一個控件到程序裏後,通常的做發是Ctrl+W,用類向導給控件關聯一個變量,然後依靠DDX/DDV進行數據交換,如果我們用同樣的方法來給RICHEDIT關聯一個CString類型的變量就會存在一個問題,就是如果我們的數據大于了64K,數據就會丟失。 通過查MSDN發現,WM_GETTEXT消息並沒有設計在RICHEDIT的數據大于64K的時候怎樣處理。而類向導生成的代碼是用DDX_Text來交換控件和CString變量的數據。恰好,DDX_Text函數是調用GetWindowText函數,而這個函數又會發出WM_GETTEXT消息到控件來返回控件裏的數據。WM_GETTEXT消息不能接受超過64K的數據,因此導致了RICHEDIT在數據交換的時候發生了丟失。 爲了解決這個問題,我們要用到DDX_RichText函數。添加下面兩個函數到工程 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文件,用文本方式打開.clw文件。參考裏面類的格式加下面兩行代碼: ExtraDDXCount=1 ExtraDDX1=7;;TextOver64KB;CString;;RichText;Retrieves text in excess of 64KB from RichEdit controls 如果沒有采用上面的步驟,我們就需要手動修改代碼,把所有的DDX_Text改爲DDX_RichText。同時要把他們移到類向導控制代碼的外面。也就是移出: //{{AFX_DATA_INIT(...) //}}AFX_DATA_INIT //{{AFX_DATA_MAP(...) //}}AFX_DATA_MAP reference: Q280447 BUG: Text from a Rich Edit Control Is Truncated During Dialog Data Exchange (DDX) 問題2: 當我們用類向導給richedit添加了EN_SETFOCUS, EN_KILLFOCUS的函數後卻不能響應,我發現這個響應函數根本就沒有被調用。即使是一個MessageBox()函數也不會調用。 原來是默認的消息映射添加錯誤了。 正確的消息影射和響應應該是: ON_EN_SETFOCUS(IDC_RICHEDIT1,OnSetfocusRichedit1) ON_EN_KILLFOCUS(IDC_RICHEDIT1,OnKillfocusRichedit1) 響應函數形式爲: afx_msg void OnSetfocusRichedit1(); afx_msg void OnKillfocusRichedit1(); 但是如果我們用類向導來直接添加,生成的代碼卻是: ON_NOTIFY(EN_SETFOCUS, IDC_RICHEDIT1, OnSetfocusRichedit1) ON_NOTIFY(EN_KILLFOCUS, IDC_RICHEDIT1, OnKillfocusRichedit1) 我們需要自己手動改爲上面的形式。 還有一個問題就是RichEditCtrl有時候不會出現在類向導的控件ID列表裏。這就需要我們自己添加DDX/DDV函數。自己動手啦!^_^ -- sampledlg.h -- class CSampleDlg : public CDialog { public: CSampleDlg(CWnd* pParent = NULL); // Dialog Data //{{AFX_DATA(CSampleDlg) enum { IDD = IDD_SAMPLE_DIALOG }; CString m_edit; // Added by ClassWizard for an edit control //}}AFX_DATA // Manually add member variables for the rich edit control CRichEditCtrl m_richEditCtrl; ....... sampledlg.cpp -- ...... void CSampleDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CSampleDlg) DDX_Text(pDX, IDC_EDIT, m_edit); DDV_MaxChars(pDX, m_edit, 10); //}}AFX_DATA_MAP // Manually add DDX_Control, DDX_Text and DDV_MaxChars for the // rich edit control DDX_Control(pDX, IDC_RICHEDIT1, m_richEditCtrl); DDX_Text(pDX, IDC_RICHEDIT1, m_richedit); DDV_MaxChars(pDX, m_richedit, 10); } reference: Q181664
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
王朝網路微信公眾號
微信掃碼關註本站公眾號 wangchaonetcn
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有