`
lovnet
  • 浏览: 6706620 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

关于RICHEDIT的两个问题

阅读更多

问题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; //类向导为EDIT空间生成的变量
//}}AFX_DATA

//俺们自己给RICHEDIT加个
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
// 再手动为RICHEDIT添加函数DDX_Control, DDX_Text and DDV_MaxChars
DDX_Control(pDX, IDC_RICHEDIT1, m_richEditCtrl);
DDX_Text(pDX, IDC_RICHEDIT1, m_richedit);
DDV_MaxChars(pDX, m_richedit, 10);
}

reference:
Q181664

分享到:
评论

相关推荐

    RichEdit做的日历

    使用RichEdit作为显示控件,显示时控制上下两行显示不同大小、颜色的字体。使用公历转农历的类。是一个显示界面不错的日历

    VC++在RichEdit中添加表情图象类及示例

    内容索引:VC/C++源码,图形处理,QQ表情 VC++在RichEdit中使用诸如表情一类的图象类,VC6和VC7两个版本的都有,示例程序同样支持两种环境,编译无错,请将编译后的EXE文件拷贝至项目根目录下运行,以便于程序能调用...

    没有用EDIT/RICHEDIT 控件写的记事本

    使用等宽字体,一个汉字的宽度等于两个字母的宽度,没有鼠标以及其他的功能。。

    类似MSN信息发送框的制作(上).rar_QQ 聊_qq 聊天 _richedit_输入框

    用 MSN 和 QQ 等聊天的时候,当用户输入特定意义的字符串时,系统回自动用一张小图片替代.比如输入" : ) "系统 会用一个小笑脸代替。...这个信息输入框由两部分组成:图案选择器和多功能文本框。本篇介绍多功能文本框。

    用VC++制作一个可折叠展开的对话框

    内容索引:VC/C++源码,界面编程,对话框,RichEdit 用VC++实现在一个窗体中使用多个RichEdit控件,在窗初始化的时候可能是只看到一个或两个,根据要求人为可以动态重复增加RichEdit,后来经过思考找到一个解决办法就是...

    MFC-二进制文件对比程序

    使用了RichEdit编辑框,点击按钮后可实现将不同的地方标红,且可实现两个编辑框通过鼠标单击或鼠标滚轮来同时滚动

    复读机

    虽然代码有点乱,但我觉得还是有可供参考的地方 如: 缩到右下角的托盘,同时只能运行一次 对RichEdit的操作,对消息的处理 我只想共享出来和爱好编程的交流,同时也希望大家改进这个程序 改进了别忘了给我一份 ...

    C++ Builder实现网络连接检测程序

    Ping的实现过程很简单,该命令将引发IP层发送一个简单的IP包...  两个RichEdit控件:一个用于给远程主机发送信息,一个用于接收来自远程主机的信息。  两个CheckBox控件:用于用户是否自己设定端口号。  一个Butt

    aspnet-office-solutions:一组用于构建可扩展Web应用程序的解决方案,其中包含DevExpress ASP.NET Spreadsheet和Rich Text Editor控件

    这样可以避免出现以下问题: RichEdit将每个请求的文档模型导入并导出到状态提供者(例如,更改文档内容或打开对话框)。 这会消耗额外的CPU资源。 服务器的内存存储文档模型,因为每次模型更改(例如,文本输入或...

    VC++2010权威开发指南+源代码

    资源比较大,分成两部分上传。 第一部分 Visual C++ 2010开发与新特性  第1章 Visual C++ 2010开发环境简介 1  1.1 Visual C++ 2010简介 1  1.2 Visual C++ 2010下载安装指南 1  1.3 Visual C++ 2010主要特点与 ...

    Windows环境下32位汇编语言程序设计(chm 罗云彬)

    9.4 使用Richedit控件(2) 9.4 使用Richedit控件(3) 9.4 使用Richedit控件(4) 9.4 使用Richedit控件(5) 9.4 使用Richedit控件(6) 9.4 使用Richedit控件(7) 9.4 使用Richedit控件(8) 9.4 使用Richedit控件(9) ...

    Windows环境下32位汇编语言程序设计.rar

    9.3 使用工具栏(6) 9.4 使用Richedit控件(1) 9.4 使用Richedit控件(2) 9.4 使用Richedit控件(3) 9.4 使用Richedit控件(4) 9.4 使用Richedit控件(5) 9.4 使用Richedit控件(6) 9.4 使用Richedit控件(7) 9.4 使用Rich...

    SkinMagic界面换皮肤开发库

    13,增加两个函数支持非标准的窗口的滚动条的换皮肤。 14,增加几个新的皮肤文件 15,增加SDK和WTL的例子程序,增加一个控件换皮肤的例子程序。 16,增加一个对话框窗口显示菜单的例子程序。 17,增加一个用于...

    皮肤控件研究文档,破解后的库文件,皮肤设计工具使用教程

    这个问题涉及到两个方面:  是否容易整合到现有应用程序中?  是否容易在新的应用程序项目中应用? 易用性: 界面控件类产品对应用程序的影响应该越小越好,要易于在现有应用程序中整合。这要求API简洁,同时...

    Windows环境下32位汇编语言程序设计 第2版(罗文斌) 完整光盘

    在两个窗口的 DC 间互相拷贝屏幕 Chapter07\Clock ;模拟时钟程序 Chapter07\BmpClock ;用 Bitmap 图片做背景的模拟时钟程序 Chapter07\TestObject ;一些常见的绘图操作 Chapter08\CommDlg ;使用通用对话框 Chapter...

    Windows环境下32位汇编语言程序设计(最新琢石成器版)附属光盘

    在两个窗口的 DC 间互相拷贝屏幕 Chapter07\Clock ;模拟时钟程序 Chapter07\BmpClock ;用 Bitmap 图片做背景的模拟时钟程序 Chapter07\TestObject ;一些常见的绘图操作 Chapter08\CommDlg ;使用通用对话框 ...

    Windows环境下32位汇编语言程序设计_随书光盘

    在两个窗口的 DC 间互相拷贝屏幕 Chapter07\Clock ;模拟时钟程序 Chapter07\BmpClock ;用 Bitmap 图片做背景的模拟时钟程序 Chapter07\TestObject ;一些常见的绘图操作 Chapter08\CommDlg ;使用通用对话框 Chapter...

    C++MFC教程

    例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时消息就会通过窗口一的句柄被发送到窗口一而不是窗口二。 5、示例:下面有一段伪代码演示如何在窗口过程中处理消息 LONG yourWndProc(HWND hWnd,UINT ...

Global site tag (gtag.js) - Google Analytics