2011-04-16 41 views
6

任何人都可以告訴我如何從文本文件中將字符逐個添加到備忘錄? 該文本文件包含不同的文本段落。我想逐個添加每個段落的字符,直到段落結束。然後延遲10秒後,下一段落將顯示在備忘錄中。將字符逐個添加到TMemo

感謝, SEI

回答

11

您可能會使用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; 

Animated sample image http://privat.rejbrand.se/autotype.gif

+0

+1看起來像你有樂趣 – 2011-04-16 19:55:44

+0

+1,Andreas。現在動畫? :) 下一步是什麼? – 2011-04-16 21:55:38

+0

+1 Andreas,你用什麼工具來生成該gif? – jachguate 2011-04-17 09:13:30

1

有很多方法可以做到這一點,我不知道你打算如何處理換行符。但是,所有路由都會導致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; 
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; 
+0

+1。我實際上考慮使用線程(和消息),而不是一個計時器,但決定它是矯枉過正! – 2011-04-17 11:28:53