Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在C+中从内存流加载到firemonkey(FMX)memo组件+;建筑商柏林?_C++_C++builder_Firemonkey - Fatal编程技术网

C++ 如何在C+中从内存流加载到firemonkey(FMX)memo组件+;建筑商柏林?

C++ 如何在C+中从内存流加载到firemonkey(FMX)memo组件+;建筑商柏林?,c++,c++builder,firemonkey,C++,C++builder,Firemonkey,我曾经使用下面的代码将大量文本加载到VCL备忘录中 LogMemo->Lines->BeginUpdate(); LogMemo->SelStart = LogMemo->GetTextLen(); LogMemo->SelLength = 0; LogMemo->SelText = AnsiString((char *)LogMemoBufPtr->Memory, LogMemoBufPtr->Size); LogMemo->SelSta

我曾经使用下面的代码将大量文本加载到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备忘录组件中,我不能再使用“LogMemo->SelText=AnsiString(strfrommstream)”。 我也不能使用“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备忘录组件中实现这一点,或者只是为了平滑地显示大量文本

谢谢

使用函数或属性


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

解决方案1-基于提供的第二个源代码,下面是一个在FMX/FireMonkey库中的
TMemo
对象中追加文本的解决方案

步骤1-不要试图放置光标并选择文本的结尾

之前:

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

之后:

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

suTemp += AnsiString((char *)LogMemoBufPtr->Memory, LogMemoBufPtr->Size);
LogMemo->Text = suTemp;
LogMemo->GoToTextEnd();
LogMemo->SelStart = LogMemo->Text.Length();
LogMemoBufPtr->Clear();
LogMemo->Lines->EndUpdate();
解决方案2-在末尾添加文本时,该解决方案简单快捷

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


FireMonkey中的
TMemo
有一个方法:

将光标移动到备注控件中文本的末尾

您不能在移动平台中使用
AnsiString
(没有),也不应该使用,因为
TMemo
保存Unicode文本(与Delphi 2009及更高版本中的VCL
TMemo
相同)。如果
TMemoryStream
包含8位字符,则在将它们附加到
TMemo
之前,需要将它们转换为Unicode,例如with。这些方法将
TBytes
作为输入,因此您可以使用而不是
TMemoryStream
tbytestream
包装
TBytes
并具有公共属性

试着这样做:

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

更新:我没有意识到FireMonkey中的
SelText
只读的,与VCL不同。在这种情况下,您别无选择,只能附加到
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();
}

谢谢你的评论。我曾尝试使用“Lines->LoadFromStream”,但它不起作用。您能定义什么是
LogMemoBufPtr
?在第一个示例中,
LogMemo->SelText=Anistring(…)
将在
LogMemo->text
的末尾添加新文本,在第二个示例中,
LogMemo->text=Anistring(…)
将覆盖现有文本。那么,您需要什么特性呢?LogMemoBufPtr是一个“TMemoryStream”指针,用于存储文本。我知道“日志备忘录->文本”将覆盖所有现有文本。但在FMX备忘录组件中,我不能使用“SelText=AnsiString(…)”。这就是为什么我试图找到另一种方式把文本转换成文本。我所期望的只是在备忘录中快速添加更多的文本。第一个例子是我用于VCL组件。但我不能在FMX组件中使用相同的代码。我需要编写跨平台的应用程序。因此,我必须使用FMX组件。您的解决方案可以正确显示备忘录,但性能/更新速度仍然很慢。每次它都重复显示所有文本,包括现有文本,这导致备忘录中的更新缓慢。我尝试使用“Append”,但它的性能仍然相同(很慢)。您的
LogMemoBufPtr
缓冲区的典型大小是多少?当添加超过25000个字符的字符串时,我看不到VCL和FMX软件之间的性能差异。这取决于。有时大约有10000个,有时大约有2000个。如果最终数据大小约为50K字节,我确实看到了差异。解决方案1的步骤1只需保存
Text
属性的值,就可以更好地处理,无需先选择文本:
System::UnicodeString suTemp=LogMemo->Text步骤2通过使用temp
UnicodeString
Length
来简化,而不是再次读取
Text
LogMemo->SelLength=suTemp.Length()嗨,谢谢你的Unicode概念。我将研究并更改代码以支持它。但我仍然有问题,只是写新的文本到FMX备忘录组件更好的性能。在FMX中无法访问“Tcustomemo::SelText”。所以,我需要找到另一种方法,只将新文本写入备忘录。
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();
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();
}
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();
}