1. gzyueqian
      18529173453
      首頁 > 新聞中心 > > 正文

      高手解答:關于RICHEDIT的兩個問題

      更新時間: 2007-05-11 14:14:46來源: 粵嵌教育瀏覽量:1126


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

      免費預約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 色在线中文字幕大 | 亚洲中文字幕每日更新 | 亚洲日韩a∨电影天堂 | 一本久中文视频播放 | 亚洲午夜在线观看专区 | 在线欧美精品一区二区三区 |