2013-03-07 135 views
0

我在保留來自RichEdit控件的字符串中的新聞行時遇到問題。 我在做什麼是:無法在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僅僅是性病:: wstring的/ STD一個typedef :: string的

我怎樣才能保持新行?

回答

1

你的代碼有很多問題。

您的代碼基於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()); 
} 

更新:如果你必須回到UTF-8的EM_SETTEXTEX消息,那麼試試這個:

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()); 
} 
+0

使用此方法我不能插入任何RTF文本,它會將其解釋爲純文本。任何想法爲什麼? – user1233963 2013-03-07 22:22:18

+0

你的文本是否實際上是RTF編碼的(它是否以'「{\ rtf」'或'「{urtf」')開頭? – 2013-03-07 23:12:18

+0

是的,使用我的舊setrfttext函數,它工作正常 – user1233963 2013-03-07 23:12:53