RichEdit一边输入一边修改

qq_35027284 2018-01-08 06:27:35
如题,想实现一边输入一边修改,输入由线程完成,总是追加在最后,尔后人工对当中的部分进行修改。
想法是修改前记录显示的第一行行号,当前选择的开始和结束位置,然后将内容将光标移动到最后面,追加,再设置选择的内容和滚动的行,但效果不理想。出现1、选择文本的时候可能被中断了,即我想选择5-15直接的字符,但有可能我选择到10的时候,光标就被切走了,接着切回来,但选择的是10-15;2、但文本较大的时候,会出现闪烁,可以看到滑块移动到最底部后又移回来。3、切换到其他程序再切回来,会自动选择所有文本,应该是焦点问题,已经将RichEdit的“No Hide Selection”设置为TRUE了。
在网上没有找到相关的资料,不知道怎么修改了,大家给点意见,或者提供个好的想法,谢谢。
...全文
519 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_35027284 2018-01-15
  • 打赏
  • 举报
回复
基本可以了,在这里总结一下,这是代码 MyRichEdit.h

#pragma once

class CMyRichEditCtrl : public CRichEditCtrl
{
public:
	CMyRichEditCtrl();
	~CMyRichEditCtrl();

	DECLARE_DYNAMIC(CMyRichEditCtrl)  
	DECLARE_MESSAGE_MAP()
public:
	void AppendText(CString strText);  // 追加文本
protected:
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	void _AppendText(CString strText);

private:
	CString m_strTextForAppend;  // 要追加的文本
	BOOL m_bLButtonDown;  // 鼠标左键被按下
};

MyRichEdit.cpp

#include "stdafx.h"
#include "MyRichEdit.h"



IMPLEMENT_DYNAMIC(CMyRichEditCtrl, CRichEditCtrl)  
CMyRichEditCtrl::CMyRichEditCtrl()
{
	m_strTextForAppend = "";
	m_bLButtonDown = FALSE;
}
CMyRichEditCtrl::~CMyRichEditCtrl()
{

}



BEGIN_MESSAGE_MAP(CMyRichEditCtrl, CRichEditCtrl)  
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
END_MESSAGE_MAP()  


void CMyRichEditCtrl::AppendText(CString strText)
{
	if (m_bLButtonDown)
	{
		// 迂回策略,在选择时不再追加
		m_strTextForAppend += strText;
	}
	else
	{
		_AppendText(strText);
	}
}
void CMyRichEditCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
	m_bLButtonDown = TRUE;

	CRichEditCtrl::OnLButtonDown(nFlags, point);
}
void CMyRichEditCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
	m_bLButtonDown = FALSE;
	_AppendText(m_strTextForAppend);  // 追加
	m_strTextForAppend.Empty();

	CRichEditCtrl::OnLButtonUp(nFlags, point);
}

void CMyRichEditCtrl::_AppendText(CString strText)
{
	long lBegin = -1;
	long lEnd = -1;

	this->SetRedraw(FALSE);  // 设置不更新
	this->HideSelection(FALSE, TRUE);
	this->GetSel(lBegin, lEnd);
	int iLine = this->GetFirstVisibleLine();

	this->SetSel(-1, -1);
	this->ReplaceSel(strText);

	int iLineCount = this->GetLineCount();
	this->LineScroll(-iLineCount);  // 滚动到最顶部
	this->LineScroll(iLine);  // 滚回之前显示的行
	this->SetSel(lBegin, lEnd);
	this->HideSelection(TRUE, TRUE);
	this->SetRedraw(TRUE);  // 设置更新
	this->Invalidate(FALSE);  // 刷新
}

首先,追加的时候设置不更新,但要注意的是,SetRedraw(FALSE)后,被控件挡住的其他控件可能会被刷出来,所以要注意把被挡住的控件隐藏或移走。追加完了,在设置更新,并调用刷新,其不会自动更新。 其次,选择文本的时候,会被追加的操作中断,参考幻梦的意见,选择文本的时候不追加,选择完再追加,没有去找更好的方法。 再次,RichEdit用的是1.0,不能用2.0版本,否则在输入时,输入法的输入框会被追加的操作打断。 感谢赵老师,虽然没有用自绘的方法,但自绘效果应该会更好。其次感谢zgl7903,虽然他的方法没有直接解决我的问题,但也间接的让我找到解决的思路,最后是幻夢之葉,提供了一个很好的方法。 现在ok了,可能还有小问题,但影响不大,容易解决。留下解决的方法,让其他人可以借鉴。
幻夢之葉 2018-01-12
  • 打赏
  • 举报
回复
引用 11 楼 qq_35027284 的回复:
[quote=引用 10 楼 jianwen0529 的回复:] 看看能不能响应鼠标的按下弹起移动的消息,然后在里面放一个状态,然后正在选择就阻止RichEdit的更新,否则才进行更新
你这样阻止更新,选择的文本和追加的文本不就不会显示了[/quote] 我的意思是,你监测选择文本的状态。当选择完毕再进行追加文本。
qq_35027284 2018-01-12
  • 打赏
  • 举报
回复
引用 10 楼 jianwen0529 的回复:
看看能不能响应鼠标的按下弹起移动的消息,然后在里面放一个状态,然后正在选择就阻止RichEdit的更新,否则才进行更新
你这样阻止更新,选择的文本和追加的文本不就不会显示了
qq_35027284 2018-01-12
  • 打赏
  • 举报
回复
引用 12 楼 jianwen0529 的回复:
我的意思是,你监测选择文本的状态。当选择完毕再进行追加文本。
可以,这种效果也不错,暂时只能用这个了,不过还有一个,在输入时,这时候追加文本,输入法的文字框会打断(消失)。
qq_35027284 2018-01-11
  • 打赏
  • 举报
回复
引用 6 楼 zgl7903 的回复:
追加

richEditCtrl->SetFocus();
  richEditCtrl->SetSel(-1, -1);
  richEditCtrl->HideSelection(FALSE, TRUE);
  richEditCtrl->ReplaceSel(szlog);
  richEditCtrl->HideSelection(TRUE, TRUE);
上面已经设置了SetSel(-1, -1)了,这时候HideSelection不就没有作用了?
幻夢之葉 2018-01-11
  • 打赏
  • 举报
回复
看看能不能响应鼠标的按下弹起移动的消息,然后在里面放一个状态,然后正在选择就阻止RichEdit的更新,否则才进行更新
qq_35027284 2018-01-11
  • 打赏
  • 举报
回复
在追加之前用SetRedraw(FALSE)不让RichEdit更新,都弄完后才用SetRedraw(TRUE)和Invalidate(FALSE)更新。这样不会出现闪烁和滚动条上下快速切换的现象。 但仍然还有问题:1、按住鼠标左键选择文本,选择过程中被中断了。2、输入时,输入法的输入框就不见了,要重新输入。 第一点还好,重载OnLButtonDown和OnLButtonUp应该就可以了,第二点不知道是怎么回事。
qq_35027284 2018-01-10
  • 打赏
  • 举报
回复
引用 6 楼 zgl7903 的回复:
追加

richEditCtrl->SetFocus();
  richEditCtrl->SetSel(-1, -1);
  richEditCtrl->HideSelection(FALSE, TRUE);
  richEditCtrl->ReplaceSel(szlog);
  richEditCtrl->HideSelection(TRUE, TRUE);
还是一样,我光标在选择文本,还在选择时,来一个replaceSel就被断开了,滚动条在上下切换。
zgl7903 2018-01-10
  • 打赏
  • 举报
回复
追加

richEditCtrl->SetFocus();
  richEditCtrl->SetSel(-1, -1);
  richEditCtrl->HideSelection(FALSE, TRUE);
  richEditCtrl->ReplaceSel(szlog);
  richEditCtrl->HideSelection(TRUE, TRUE);
qq_35027284 2018-01-10
  • 打赏
  • 举报
回复
想问一下有没有不通过SetSel和ReplaceSel的方法在最后面追加文本的的方法
qq_35027284 2018-01-09
  • 打赏
  • 举报
回复
那么就是说现在RichEdit实现不了我想要的,只能从自绘入手,只是怕时间长了赶不上进度。
赵4老师 2018-01-09
  • 打赏
  • 举报
回复
自绘是早晚要学会的一种技能。
qq_35027284 2018-01-09
  • 打赏
  • 举报
回复
也不是终端,只是一个平台中的一个小模块,MFC不熟,到这里就不知道怎样继续了
躺着睡的蜗牛 2018-01-08
  • 打赏
  • 举报
回复
感觉像是在实现终端似的 用单文档或者自绘控件实现可能会更好一些

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧