自动换行有很多种实现方法,但EDIT控件必须设置以下属性:
当然了,不管用什么方法,edit控件的属性一定需要设置:
edit控件Multiline属性一定要设置为True,否则文本将只有一行,当Multiline属性被置为Ture的时候,Auto Vscroll属性(设为(ture)便可用了(竖直方向超出范围自动滚屏,需要设为TRUE,Auto Hscroll(设为ture)水平自动换行,否则文本到最行一行的时候,不会再滚动了.
方法一:将EDIT映射到一CString
m_String = m_String + sNewString + "\r\n" //自动换行
UpdateData(false);
其中m_String是edit关联的一个CString变量。
这种方法的基本原理是获取原数据,添加新数据,然后再显示。当字符数量很多的时候,会出现闪屏,资源消耗过多的弊端,不建议使用。
方法二.将EDIT映射到一EDIT控件变量(类型为control, Cedit类型)
**m_Edit.SetSel(-1, -1); //自动滚屏
m_Edit.ReplaceSel(sNewString+”\r\n”); //自动换行**
其中m_Edit是edit关联的一个CEdit变量,这种方法利用控件自身的特性,不需要消耗过多的资源,也不会有闪屏的问题。推荐此方法。
方法三.将EDIT映射到一EDIT控件变量
DWORD dwLength = m_Edit.SendMessage(WM_GETTEXTLENGTH); //获取字符长度
m_Edit.SetSel(dwLength, dwLength); //设置光标位置到末尾
m_Edit.ReplaceSel(NewStr + “\r\n”); //末尾加文本
这种方法跟2的道理很相似,但是兼容性似乎不那么好,测试有的时候有效,有的时候却不好使。
追加内容:如果字符文本过多,我们怎么清理呢?
范例:到200行时将所有内容清空
代码:
int LineNum=m_Edit.GetLineCount(); //获取行号
if(LineNum<=200) //追加
{
m_Edit.SetSel(-1, -1);
m_Edit.ReplaceSel(str+"\r\n");
}
else //清理
{
m_Edit.SetSel(0, -1);
m_Edit.Clear();
}
消息类与edit控件的通讯
在很多情况下,为了管理我们输出的消息,我们需要定义一个消息类,所有的消息都由这个类来管理分发。那么这个时候就会遇到一个问题,消息管理类怎样与我们的控件edit通讯呢?
一个方案是将这个消息类定义为全局对象,这样我们可以实时的获取这个对象的数据,然后再将其显示。但是,如果对象是全局的,那么如果同时有多个数据到达的时候,数据就会出现混乱,因为显示线程只有一个。一个数据没有处理好,其他的数据就会被覆盖。
几经尝试,发现一个可行的方案:在消息类中使用sendMessage向edit控件所在的对话框发送自定义消息,sendMessage有4个参数,其中HWND可以在其主窗口初始化中得到,在初始化的过程中我们也可以同时获取控件的ID,这样在发送的时候,WPARAM可以携带控件ID,LPARAM可以携带消息指针,由于是同进程,对同一个指针访问没有问题。
关键代码如下:
发送端
::SendMessage(hWnd, WM_SHOWMSG, ctrId, (LPARAM)strLogMsg.GetBuffer(0));
接受端:
//自定义响应消息
LRESULT CPage1::OnShowMsg(WPARAM wParam, LPARAM lParam)
{
DWORD dwLineCount = m_strLogMsg.GetLineCount();
//行数超过200,就清理
if (dwLineCount >= 200)
{
m_strLogMsg.SetSel(0,-1);
m_strLogMsg.Clear();
}
m_strLogMsg.SetSel(-1);
m_strLogMsg.ReplaceSel((LPCSTR)lParam);
return 0;
}
在这个接受端,WPARAM本来是传递控件ID过来了,我们可以GetDlgItem获取其句柄,然后在调用其成员函数,也可以像上面一样,直接将控件绑定变量,然后再直接调用就好了。
在对话框的初始化代码中,Edit已经初始化好,直接给其发送消息,edit已经可以正常响应了。
上面的方法经过测试,的确有效可用,但是好像不太符合“高内聚,低耦合”封装特性,为了配消息类的工作,主窗口还要自己建立一个自定义消息响应函数,这个似乎不太合适。
于是我又发现了另外一个方法,这个方法更简洁高效。同样是SengMessge如下:
::SendMessage(GetDlgItem(EDT_MSG)->m_hWnd, EM_REPLACESEL, FALSE, (LPARAM)"消息到达 \r\n");
这种方法直接向空间发送替换字符消息,控件收到该消息的时候就会自动增加消息。当然了,该方法仍然需要获取主窗口的句柄,这个可以在初始化的时候获取,很明显,这种方法减少了很多工作量,耦合性也少很多。建议使用此方法。