I used to use below code to load plenty of text to VCL Memo.
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();
But in FMX Memo component, I can't use "LogMemo->SelText = AnsiString(strFromMemStream)" anymore. And I also can't use "GetTextLen" method to set selection start.
I tried to modify the code in below but it still didn't work. It always overwrite original content and can't append new text.
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();
Is there any one know how to do it in FMX Memo component or just to display plenty of text smoothly?
Thanks!
Solution 1 - Based to the second source code provided, here is a solution to append a text in the TMemo
object in FMX/FireMonkey Library.
Step 1 - Instead of trying to place the cursor and select the end of the text.
Before:
LogMemo->GoToTextEnd();
LogMemo->SelStart = LogMemo->Text.Length();
LogMemo->SelLength = 0;
Select all the text and store it in a temporary string.
After:
System::UnicodeString suTemp;
LogMemo->Lines->BeginUpdate();
LogMemo->GoToTextEnd();
LogMemo->SelStart = 0;
LogMemo->SelLength = LogMemo->Text.Length();
suTemp = LogMemo->SelText;
Step 2 - Then append the new text to the temporary string and update the Memo
suTemp += AnsiString((char *)LogMemoBufPtr->Memory, LogMemoBufPtr->Size);
LogMemo->Text = suTemp;
LogMemo->GoToTextEnd();
LogMemo->SelStart = LogMemo->Text.Length();
LogMemoBufPtr->Clear();
LogMemo->Lines->EndUpdate();
Solution 2 - Simple and faster solution when add the text at the end.
Store the current text into a temporary string and add the new text then update the memo.
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();
TMemo
in FireMonkey has a GoToTextEnd()
method:
Moves the cursor to the end of the text in the memo control.
You can't use AnsiString
in mobile platforms (without a compiler patch ), nor should you anyway since TMemo
holds Unicode text (same as VCL's TMemo
in Delphi 2009 and later). If your TMemoryStream
contains 8bit characters, you need to convert them to Unicode, such as with TEncoding
, before appending them to the TMemo
. The TEncoding::GetString()
methods take a TBytes
as input, so you could use TBytesStream
instead of TMemoryStream
. TBytesStream
wraps a TBytes
and has a public Bytes
property.
Try something like this:
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();
}
Update : I didn't realize that SelText
is read-only in FireMonkey, unlike in VCL. In that case, you have no choice but to append to the Text
property, which is not as efficient, especially for large 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();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.