VC Edit控件自动换行显示方法

来源:互联网 发布:最讨厌的动漫人物知乎 编辑:程序博客网 时间:2024/05/18 06:56


方法一.将EDIT映射到一CString

m_String = m_String + sNewString + "\r\n"    //自动换行UpdateData(false);

其中m_String是edit关联的一个CString变量。

这种方法的基本原理是获取原数据,添加新数据,然后再显示。当字符数量很多的时候,会出现闪屏,资源消耗过多的弊端,不建议使用。

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控件Multiline属性一定要设置为True,否则文本将只有一行,当Multiline属性被置为Ture的时候,Auto Vscroll属性便可用了,需要设为TRUE,否则文本到最行一行的时候,不会再滚动了.


消息类与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");

这种方法直接向空间发送替换字符消息,控件收到该消息的时候就会自动增加消息。当然了,该方法仍然需要获取主窗口的句柄,这个可以在初始化的时候获取,很明显,这种方法减少了很多工作量,耦合性也少很多。建议使用此方法。
















原创粉丝点击