如何在C ++ Builder Berlin中从内存流加载到firemonkey(FMX)备忘录组件?

时间:2017-01-14 08:46:56

标签: c++ c++builder firemonkey

我曾经使用下面的代码将大量文本加载到VCL备忘录。

LogMemo->Lines->BeginUpdate();
LogMemo->SelStart = LogMemo->GetTextLen();
LogMemo->SelLength = 0;

LogMemo->SelText = AnsiString((char *)LogMemoBufPtr->Memory, LogMemoBufPtr->Size);
LogMemo->SelStart = LogMemo->GetTextLen();
LogMemo->Perform(EM_SCROLLCARET, 0, 0);
LogMemo->Lines->EndUpdate();

但在FMX Memo组件中,我无法使用" LogMemo-> SelText = AnsiString(strFromMemStream)"了。 我也无法使用" GetTextLen"设置选择开始的方法。

我尝试修改下面的代码,但它仍然没有用。它始终覆盖原始内容,无法附加新文本。

LogMemo->Lines->BeginUpdate();
LogMemo->GoToTextEnd();
LogMemo->SelStart = LogMemo->Text.Length();
LogMemo->SelLength = 0;

LogMemo->Text = AnsiString((char *)LogMemoBufPtr->Memory, LogMemoBufPtr->Size);
LogMemo->GoToTextEnd();
LogMemo->SelStart = LogMemo->Text.Length();
LogMemoBufPtr->Clear();
LogMemo->Lines->EndUpdate();

有没有人知道如何在FMX Memo组件中执行此操作或只是为了顺利显示大量文本?

谢谢!

3 个答案:

答案 0 :(得分:0)

使用SetText功能或Lines属性。

在这两种情况下,我认为您必须先将ASCII文本转换为Unicode。

答案 1 :(得分:0)

解决方案1 ​​ - 根据提供的第二个源代码,这是一个在FMX / FireMonkey库中的TMemo对象中附加文本的解决方案。

第1步 - 而不是尝试放置光标并选择文本的结尾。

  

在:

LogMemo->GoToTextEnd();
LogMemo->SelStart = LogMemo->Text.Length();
LogMemo->SelLength = 0;

选择所有文本并将其存储在临时字符串中。

  

后:

System::UnicodeString suTemp;

LogMemo->Lines->BeginUpdate();
LogMemo->GoToTextEnd();
LogMemo->SelStart = 0;
LogMemo->SelLength = LogMemo->Text.Length();
suTemp = LogMemo->SelText;

第2步 - 然后将新文本追加到临时字符串并更新备忘录

suTemp += AnsiString((char *)LogMemoBufPtr->Memory, LogMemoBufPtr->Size);
LogMemo->Text = suTemp;
LogMemo->GoToTextEnd();
LogMemo->SelStart = LogMemo->Text.Length();
LogMemoBufPtr->Clear();
LogMemo->Lines->EndUpdate();

解决方案2 - 在最后添加文本时简单快捷的解决方案。

  

将当前文本存储到临时字符串中并添加新文本   然后更新备忘录。

System::UnicodeString suTemp;

LogMemo->Lines->BeginUpdate();
suTemp = LogMemo->Text;

suTemp += AnsiString((char *)LogMemoBufPtr->Memory, LogMemoBufPtr->Size);
LogMemo->Text = suTemp;
LogMemo->GoToTextEnd();
LogMemoBufPtr->Clear();
LogMemo->Lines->EndUpdate();

答案 2 :(得分:0)

FireMonkey中的

TMemo有一个GoToTextEnd()方法:

  

将光标移动到备忘录控件中文本的末尾。

您无法在移动平台中使用AnsiString(没有compiler patch),也不应该因为TMemo包含Unicode文本(与Delphi中的VCL TMemo相同) 2009年及以后)。如果您的TMemoryStream包含8位字符,则需要先将其转换为Unicode,例如TEncoding,然后再将其附加到TMemoTEncoding::GetString()方法使用TBytes作为输入,因此您可以使用TBytesStream代替TMemoryStreamTBytesStream包裹TBytes并拥有公共Bytes属性。

尝试这样的事情:

LogMemo->Lines->BeginUpdate();
try
{
    LogMemo->GoToTextEnd();
    LogMemo->SelLength = 0;
    LogMemo->SelText = TEncoding::Default->GetString(LogMemoBufPtr->Bytes, 0, LogMemoBufPtr->Size);
    /* or:
    TEncoding *enc = TEncoding::GetEncoding(L"desired charset here");
    try {
        LogMemo->SelText = enc->GetString(LogMemoBufPtr->Bytes, 0, LogMemoBufPtr->Size);
    }
    __finally {
        delete enc;
    }
    */
    LogMemo->GoToTextEnd();
    LogMemo->SelLength = 0;
    // not sure if this is the best replacement for EM_SCROLLCARET...
    LogMemo->VScrollBar->Value = LogMemo->VScrollBar->Max;
}
__finally {
    LogMemo->Lines->EndUpdate();
}

更新:与VCL不同,我没有意识到FireMonkey中的SelText 只读。在这种情况下,您别无选择,只能附加到Text属性,这不是那么有效,特别是对于大文本。

LogMemo->Lines->BeginUpdate();
try
{
    LogMemo->Text = LogMemo->Text + TEncoding::Default->GetString(LogMemoBufPtr->Bytes, 0, LogMemoBufPtr->Size);
    /* or:
    TEncoding *enc = TEncoding::GetEncoding(L"desired charset here");
    try {
        LogMemo->Text = LogMemo->Text + enc->GetString(LogMemoBufPtr->Bytes, 0, LogMemoBufPtr->Size);
    }
    __finally {
        delete enc;
    }
    */
    LogMemo->GoToTextEnd();
    LogMemo->SelLength = 0;
    // not sure if this is the best replacement for EM_SCROLLCARET...
    LogMemo->VScrollBar->Value = LogMemo->VScrollBar->Max;
}
__finally {
    LogMemo->Lines->EndUpdate();
}