首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获得TRichEdit的进度?

如何获得TRichEdit的进度?
EN

Stack Overflow用户
提问于 2020-02-05 08:40:11
回答 2查看 104关注 0票数 0

我有一个简单的“畜生”大文本文件(20 big )。我想在TRichEdit上展示一下。问题是它需要6秒才能显示出来。为了避免这个糟糕的UX设计,我想在应用程序的底部放一个程序栏。

我的问题是如何获得TRichEdit展示的进展?使用TRichEdit::LoadFromStream方法,它的速度从0到100% (小于1秒),但是在应用程序等待6秒钟之后,在第一次显示中。

我用FileStreamProgress继承TFileStream创建了这个类。我覆盖了TFileStream::Read()

代码语言:javascript
复制
    int __fastcall FileStreamProgress::Read(void *Buffer, int Count)
    {
        __int64 previousPosition = this->Position;
        int ret = TFileStream::Read(Buffer, Count);
        if (this->Position == 0 || this->Position == this->Size || (previousPosition/128000) != (this->Position/128000)) {
            ProgressCallBack(ProgressCallBackParam1, this->Position, this->Size);
        }
        return ret;
    }
    static void FileStreamProgress::ProgressCallBack(void*thiz, int i, int max)
    {
        TProgressBar* ProgressBar = (TProgressBar*)thiz;
        if (ProgressBar)
        {
            if (max > 0)
            {
                ProgressBar->Position = int(i * 100 / max);
            }

            if (Application)
            {
                Sleep(1);
                Application->ProcessMessages();
            }
        }
    }        

我就是这样测试的:

代码语言:javascript
复制
void MyApp::CreatePage(AnsiString filename)
{
    ProgressBar->Visible = true;
    FileStreamProgress::ProgressCallBackParam1 = (void*)this->ProgressBar;
    TFileStream * stream = new FileStreamProgress(filename.c_str(), fmOpenRead);
    TPageMemo* Page = new TPageMemo(this);

    Page->Parent = PControl;
    Page->PageControl = PControl;

    MessageDlg("111",mtError,TMsgDlgButtons()<<mbOK,0);
    Page->Texte->Lines->LoadFromStream(stream);
    MessageDlg("222",mtError,TMsgDlgButtons()<<mbOK,0);

    PControl->ActivePage = Page;
}

在两个消息对话框"111“和"222”之间有7个附庸。我的进度条等待6秒100% (在展示期间)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-06 07:51:14

我试图深入研究win32 API的SendMessage,并在没有预期结果的情况下进行处理。

最后,我昨天使用了一个TMemo,因为它是一个粗俗的文本。它非常快(即时打开),但是缺少一些函数,比如FindTextW()。我重写了它。谢谢

http://docwiki.embarcadero.com/RADStudio/Rio/en/Memo_and_Rich_Edit_Controls

票数 0
EN

Stack Overflow用户

发布于 2020-02-06 15:42:43

出于好奇,我对TRichEdit进行了测试,并想出了如下结论:

代码语言:javascript
复制
//---------------------------------------------------------------------------
void load_text(TRichEdit *re,AnsiString filename,TProgressBar *pb)
    {
    // variables
    int hnd,adr,siz,len,i;
    const int _buf=128*1024;                    // buffer size
    AnsiString s,s0;
    char buf[_buf+1];
    // open file and detect size
    hnd=FileOpen(filename,fmOpenRead); if (hnd<0) return;
    siz=FileSeek(hnd,0,2);
        FileSeek(hnd,0,0);
    // prepare progress bar
    pb->Position=0;
    pb->Max=siz;
    pb->Visible=true;
    // process txt file by chunks
    for (s0="",adr=0;adr<siz;)
        {
        // update progress bar and GUI
        pb->Position=adr;
        Application->ProcessMessages();
        // load chunk
        len=FileRead(hnd,buf,_buf);
        adr+=len; buf[len]=0;
        // handle cutted lines by chunk size
        s=s0; s0="";
        // ignore last 2 lines for chunks (except last chunk)
        if (len==_buf)
            {
            // skip last line
            for (i=len-1;i>=0;i--)
             if ((buf[i]==13)||(buf[i]==10))
                {
                i--;
                if (i>=0)
                 if (buf[i]!=buf[i+1])              // different eol code to ignore empty line
                  if ((buf[i]==13)||(buf[i]==10))   // eol code
                   i--;
                break;
                }
            // skip another line to avoid inserting empty line if eol is cutted
            for (;i>=0;i--)
             if ((buf[i]==13)||(buf[i]==10))
                {
                s0+=buf+i+1;                        // copy last 2 lines into s0
                i--;
                if (i>=0)
                 if (buf[i]!=buf[i+1])              // different eol code to ignore empty line
                  if ((buf[i]==13)||(buf[i]==10))   // eol code
                   i--;
                i++; if (i<0) i=0; buf[i]=0;        // end of string
                break;
                }
            }
        // last chunk ignore last eol
        else{
            // skip last line
            i=len-1;
            if ((buf[i]==13)||(buf[i]==10))         // eol code
                {
                i--;
                if (buf[i]!=buf[i+1])               // different eol code to ignore empty line
                 if ((buf[i]==13)||(buf[i]==10))    // eol code
                  i--;
                i++; if (i<0) i=0; buf[i]=0;        // end of string
                }
            }
        // add actual chunk
        s+=buf;
        re->Lines->Add(s);
        }
    // tidy up
    pb->Visible=false;
    FileClose(hnd); hnd=-1;
    }
//---------------------------------------------------------------------------

看起来,它不需要您描述的结束暂停,但是,这可能与我正在使用的、BDS2006、Turbo、C++、的版本有关。当在~23 MByte STL文件上进行测试时,加载时间为~10秒(TMemo花费了上帝的两倍,知道为什么).

保存的文件(而PlainText=true)与加载的文件相同,因此代码应该是正确的。

这里是预览的动画GIF:

当像这样使用时:

代码语言:javascript
复制
void __fastcall TForm1::FormActivate(TObject *Sender)
    {
    //tbeg();
    load_text(re_txt,"in.txt",pb_progress);
    //tend();
    //Caption=tstr();
    re_txt->Lines->SaveToFile("out.txt");
    }

其中pb_progressTProgressBarre_txtTRichEdit

你可以看到不需要回调..。

PS.如果您想像我一样度量时间(注释行),tbeg/tend/tstr函数的实现如下:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60071903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档