【问题标题】:Adding Characters one by one to TMemo将字符一一添加到 TMemo
【发布时间】:2011-04-16 17:18:05
【问题描述】:

谁能告诉我如何将文本文件中的字符一一添加到备忘录中? 文本文件包含不同的文本段落。我想将每个段落的字符一个一个添加到段落末尾。然后延迟 10 秒后在备忘录中显示下一段。

谢谢, 塞

【问题讨论】:

    标签: delphi delphi-xe


    【解决方案1】:

    您可能会使用TTimer。在您的表单上添加 TTimerTMemoTButton。然后做

    var
      lines: TStringList;
      pos: TPoint;
    
    const
      CHAR_INTERVAL = 75;
      PARAGRAPH_INTERVAL = 1000;
    
    procedure TForm6.Button1Click(Sender: TObject);
    const
      S_EMPTY_FILE = 'You are trying to display an empty file!';
    begin
      Memo1.ReadOnly := true;
      Memo1.Clear;
      Memo1.Lines.Add('');
      pos := Point(0, 0);
      if lines.Count = 0 then
        raise Exception.Create(S_EMPTY_FILE);
      while (pos.Y < lines.Count) and (length(lines[pos.Y]) = 0) do inc(pos.Y);
      if pos.Y = lines.Count then
        raise Exception.Create(S_EMPTY_FILE);
      NextCharTimer.Enabled := true;
    end;
    
    procedure TForm6.FormCreate(Sender: TObject);
    begin
      lines := TStringList.Create;
      lines.LoadFromFile('C:\Users\Andreas Rejbrand\Desktop\Test.txt');
    end;
    
    procedure TForm6.NextCharTimerTimer(Sender: TObject);
    begin
      NextCharTimer.Interval := CHAR_INTERVAL;
    
      Memo1.Lines[Memo1.Lines.Count - 1] := Memo1.Lines[Memo1.Lines.Count - 1] + lines[pos.Y][pos.X + 1];
      inc(pos.X);
    
      if pos.X = length(lines[pos.Y]) then
      begin
        NextCharTimer.Interval := PARAGRAPH_INTERVAL;
        pos.X := 0;
        repeat
          inc(pos.Y);
          Memo1.Lines.Add('');
        until (pos.Y = lines.Count) or (length(lines[pos.Y]) > 0);
      end;
    
      if pos.Y = lines.Count then
        NextCharTimer.Enabled := false;
    end;
    

    【讨论】:

    • 非常感谢大卫,我尝试了你的代码,它完美运行,也非常感谢其他回复。塞
    • @user711361:你是在和我说话还是在和大卫说话? :)
    • @user711361:请点击答案左侧的复选标记,接受您最喜欢的答案。
    • 是的,感谢您嵌入了信息丰富且紧凑的光栅图像,而不是使用过时且不方便的超链接。
    【解决方案2】:

    一个替代计时器的线程。在文件中为段落测试“回车”:

    const
      UM_MEMOCHAR = WM_USER + 22;
    
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        procedure UMMemoChar(var Msg: TMessage); message UM_MEMOCHAR;
      public
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    type
      TCharSender = class(TThread)
      private
        FCharWait, FParWait: Integer;
        FFormHandle: HWND;
        FFS: TFileStream;
      protected
        procedure Execute; override;
      public
        constructor Create(FileName: string; CharWait, ParagraphWait: Integer;
            FormHandle: HWND);
        destructor Destroy; override;
      end;
    
    constructor TCharSender.Create(FileName: string; CharWait, ParagraphWait: Integer;
        FormHandle: HWND);
    begin
      FCharWait := CharWait;
      FParWait := ParagraphWait;
      FFormHandle := FormHandle;
      FFS := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
      FreeOnTerminate := True;
      inherited Create(False);
    end;
    
    destructor TCharSender.Destroy;
    begin
      FFS.Free;
      inherited;
    end;
    
    procedure TCharSender.Execute;
    var
      C: Char;
    begin
      while (FFS.Position < FFS.Size) and not Terminated do begin
        FFS.Read(C, SizeOf(C));
        if (C <> #10) then
          PostMessage(FFormHandle, UM_MEMOCHAR, Ord(C), 0);
    
        if C = #13 then
          Sleep(FParWait)
        else
          Sleep(FCharWait);
      end;
    end;
    
    {TForm1}
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Memo1.Clear;
      TCharSender.Create(
          ExtractFilePath(Application.ExeName) + 'text.txt', 20, 1000, Handle);
    end;
    
    procedure TForm1.UMMemoChar(var Msg: TMessage);
    begin
      Memo1.SelStart := Memo1.Perform(WM_GETTEXTLENGTH, 0, 0);
      Memo1.Perform(WM_CHAR, Msg.WParam, 0);
    end;
    

    【讨论】:

    • +1。我实际上考虑过使用线程(和消息)而不是计时器,但认为这太过分了!
    【解决方案3】:

    有很多方法可以做到这一点,我不确定您打算如何处理换行符。但是,所有路由都指向 TMemo.Lines,这是一个 TStrings 实例,它封装了与底层 Windows 编辑控件交互所需的 Windows 消息。

    例如,这些例程应该可以帮助您入门。

    procedure AddNewLine(Memo: TMemo);
    begin
      Memo.Lines.Add('');
    end;
    
    procedure AddCharacter(Memo: TMemo; const C: Char);
    var
      Lines: TStrings;
    begin
      Lines := Memo.Lines;
      if Lines.Count=0 then
        AddNewLine(Memo);
      Lines[Lines.Count-1] := Lines[Lines.Count-1]+C;
    end;
    

    【讨论】:

      猜你喜欢
      • 2013-05-11
      • 1970-01-01
      • 2020-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-17
      • 2014-07-17
      相关资源
      最近更新 更多