gpt4 book ai didi

c++ - 无法在 RichEdit 中保留换行符

转载 作者:行者123 更新时间:2023-11-28 07:43:49 27 4
gpt4 key购买 nike

我在从字符串中的 RichEdit 控件中保留新闻行时遇到问题。我正在做的是:

  1. 从 RichEdit 控件获取文本
  2. 拆分由空格分隔的所有内容
  3. 添加一些 RTF 格式
  4. 将单词“融合”在一起
  5. 发送文本到控件

我不确定是什么部分导致的,所以这里是最相关的部分:

int RichEdit::GetTextLength() const
{
GETTEXTLENGTHEX len;
len.codepage = 1200;
len.flags = GTL_NUMBYTES;
return (int)SendMessage(this->handle, EM_GETTEXTLENGTHEX, (WPARAM)&len, 0) + 1;
}

tstring RichEdit::GetText() const
{
auto len = this->GetTextLength();
GETTEXTEX str;

TCHAR* tmp = new TCHAR[len];
str.cb = len;
str.flags = GT_USECRLF;
str.codepage = 1200;


str.lpDefaultChar = NULL;
str.lpUsedDefChar = NULL;

(void)SendMessage(this->handle, EM_GETTEXTEX, (WPARAM)&str, (LPARAM)tmp);

tstring ret(tmp);

delete[] tmp;
return ret;
}

void RichEdit::SetRtfText(const tstring& text, int flags)
{
DWORD WideLength = text.length();
DWORD Length = WideLength * 4;
PSTR Utf8 = (PSTR)malloc(Length);

int ReturnedLength = WideCharToMultiByte(CP_UTF8,
0,
text.c_str(),
WideLength-1,
Utf8,
Length-1,
NULL,
NULL);

if (ReturnedLength)
Utf8[ReturnedLength] = 0;

SETTEXTEX st = {0};
st.flags = flags;
st.codepage = CP_UTF8;
(void)SendMessage(this->handle, EM_SETTEXTEX, (WPARAM)&st, (LPARAM)Utf8 );

free(Utf8);
}

void split ( tstring input , tstring split_id, std::vector<std::pair<tstring,bool>>& res ) {
std::vector<std::pair<tstring,bool>> result;
int i = 0;
bool add;
tstring temp;
std::wstringstream ss;
size_t found;
tstring real;
int r = 0;
while ( i != input.length() )
{
add = false;
ss << input.at(i);
temp = ss.str();

found = temp.find(split_id);
if ( found != tstring::npos )
{
add = true;
real.append ( temp , 0 , found );
} else if ( r > 0 && ( i+1 ) == input.length() )
{
add = true;
real.append ( temp , 0 , found );
}
if ( add )
{
result.emplace_back(std::make_pair(real,false));
ss.str(tstring());
ss.clear();
temp.clear();
real.clear();
r = 0;
}
i++;
r++;
}
res = result;
}

ps: tstring 只是 std::wstring/std::string 的类型定义

如何保留换行符?

最佳答案

您的代码有很多问题。

您的代码是基于 TCHAR 的,但您实际上并没有正确地使用 TCHAR 检索/设置 RTF 数据。

检索文本时,您将换行符规范化为 CRLF,但检索文本长度时并未进行相同的规范化,因此它们将彼此不同步。

您正在使用 UTF-8 将数据写入 RichEdit,但 RTF 是一种基于 ASCII 的格式,它对 Unicode 数据使用转义序列。如果您打算以 Unicode 格式检索数据,您也可以使用 Unicode 编写它,并确保您一开始就正确地完成了所有这些工作。让 RichEdit 控件为您处理 Unicode。

您对 WideCharToMultiByte() 的使用是错误的。您根本不应该从字符串长度中减去 -1。您可能会尝试考虑空终止符,但长度值不包括开头的空终止符。如果您打算坚持使用 UTF-8,那么您应该使用 WideCharToMultiByte() 来计算正确的 UTF-8 长度,而不是对其进行硬编码。

int Length = WideCharToMultiByte(CP_UTF8, 0, text.c_str(), text.length(), NULL, 0, NULL, NULL);
char Utf8 = new char[Length+1];
WideCharToMultiByte(CP_UTF8, 0, text.c_str(), text.length(), Utf8, Length, NULL, NULL);
Utf8[Length] = 0;
...
delete[] Utf8;

话虽如此,如果您要坚持使用 TCHAR,那么试试这个:

#ifdef UNICODE
#define RTFCodePage 1200
#else
#define RTFCodePage CP_ACP
#endif

int RichEdit::GetTextLength() const
{
GETTEXTLENGTHEX len = {0};
len.codepage = RTFCodePage;
len.flags = GTL_NUMCHARS | GTL_USECRLF;
return SendMessage(this->handle, EM_GETTEXTLENGTHEX, (WPARAM)&len, 0);
}

tstring RichEdit::GetText() const
{
int len = this->GetTextLength() + 1;

GETTEXTEX str = {0};
str.cb = len * sizeof(TCHAR);
str.flags = GT_USECRLF;
str.codepage = RTFCodePage;

vector<TCHAR> tmp(len);
len = SendMessage(this->handle, EM_GETTEXTEX, (WPARAM)&str, (LPARAM)&tmp[0]);

return tstring(&tmp[0], len-1);
}

void RichEdit::SetRtfText(const tstring& text, int flags)
{
SETTEXTEX st = {0};
st.flags = flags;
st.codepage = RTFCodePage;

#ifdef UNICODE
st.flags |= ST_UNICODE;
#endif

SendMessage(this->handle, EM_SETTEXTEX, (WPARAM)&st, (LPARAM)text.c_str());
}

最好放弃 TCHAR 并只对所有内容使用 Unicode:

int RichEdit::GetTextLength() const
{
GETTEXTLENGTHEX len = {0};
len.codepage = 1200;
len.flags = GTL_NUMCHARS | GTL_USECRLF;
return SendMessage(this->handle, EM_GETTEXTLENGTHEX, (WPARAM)&len, 0);
}

wstring RichEdit::GetText() const
{
int len = this->GetTextLength() + 1;

GETTEXTEX str = {0};
str.cb = len * sizeof(WCHAR);
str.flags = GT_USECRLF;
str.codepage = 1200;

vector<WCHAR> tmp(len);
len = SendMessage(this->handle, EM_GETTEXTEX, (WPARAM)&str, (LPARAM)&tmp[0]);

return wstring(tmp, len-1);
}

void RichEdit::SetRtfText(const wstring& text, int flags)
{
SETTEXTEX st = {0};
st.flags = flags | ST_UNICODE;
st.codepage = 1200;

SendMessage(this->handle, EM_SETTEXTEX, (WPARAM)&st, (LPARAM)text.c_str());
}

更新:如果您必须为 EM_SETTEXTEX 消息返回 UTF-8,请尝试以下操作:

void RichEdit::SetRtfText(const tstring& text, int flags)
{
string Utf8;
int Length;

#ifdef UNICODE

Length = WideCharToMultiByte(CP_UTF8, 0, text.c_str(), text.length(), NULL, 0, NULL, NULL);
if (Length > 0)
{
Utf8.resize(Length);
WideCharToMultiByte(CP_UTF8, 0, text.c_str(), text.length(), &Utf8[0], Length, NULL, NULL);
}

#else

Length = MultiByteToWideChar(CP_ACP, 0, text.c_str(), text.length(), NULL, 0);
if (Length > 0)
{
vector<WCHAR> tmp(Length);
MultiByteToWideChar(CP_ACP, 0, text.c_str(), text.length(), &tmp[0], Length);

Length = WideCharToMultiByte(CP_UTF8, 0, tmp.c_str(), tmp.length(), NULL, 0, NULL, NULL);
if (Length > 0)
{
Utf8.resize(Length);
WideCharToMultiByte(CP_UTF8, 0, tmp.c_str(), tmp.length(), &Utf8[0], Length, NULL, NULL);
}
}

#endif

SETTEXTEX st = {0};
st.flags = flags & ~ST_UNICODE;
st.codepage = CP_UTF8;
SendMessage(this->handle, EM_SETTEXTEX, (WPARAM)&st, (LPARAM)Utf8.c_str());
}

关于c++ - 无法在 RichEdit 中保留换行符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15263528/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com