Текстовый редактор, как сделать редактируемые строки? - Free Pascal
Формулировка задачи:
Доброго времени суток всем!
Вопрос таков: начал делать текстовый редактор и не могу сделать редактируемые строки. Написанное можно только стереть, нельзя передвинуться, скажем, на 2 символа влево или вправо с помощью стрелок на клавиатуре. Также нельзя стирать символы из предыдущей строки (той, которая писалась до нажатия Enter).
Вот что я там понаписал:
Просмотрите пожалуйста кодик и скажите что можно сделать.
{Teddy - The simple text editor v0.1 Teddy is a very simple text editor for DOS/Windows and Linux} program Teddy; uses crt,dos; var s,s1,s2,s3:string; f,f1,f2:text; label main_menu; {----------main menu----------} begin main_menu: clrscr; writeln(' Teddy - the simple text editor v0.1'); writeln(' Made in Free Pascal 2.2.2'); writeln(''); writeln(''); writeln(' "!open" - open file'); writeln(' "!new" - create new file'); writeln(' "!save" - save file'); writeln(' "!exit" - exit Teddy'); write('>>> '); readln(s); {----------exit function----------} if s='!exit' then exit {----------new file function----------} else if s='!new' then begin writeln('Enter the path of file: '); readln(s1); assign(f,s1); rewrite(f); clrscr; repeat write('>>> '); readln(s3); writeln(f,s3); until s3='!save'; close(f); goto main_menu; end {----------open file function----------} else if s='!open' then begin writeln('Enter the path of file: '); readln(s1); assign(f1,s1); reset(f1); while not eof (f1) do begin readln(f1,s3); writeln(s3); end; close(f1); goto main_menu; end; end.
Решение задачи: «Текстовый редактор, как сделать редактируемые строки?»
textual
Листинг программы
uses APP,OBJECTS,MENUS,DRIVERS,VIEWS,DIALOGS ; type TMyApp = object(TApplication) procedure InitStatusLine; virtual; procedure InitMenuBar; virtual; procedure NewWindow; virtual; procedure NewDialog; virtual; procedure HandleEvent(var Event: TEvent); virtual; end; var MyApp: TMyApp; { ::::::::::::::::?*ЁжЁ*«Ё§*жЁп StatusBar'л::::::::::::::::::::::: } procedure TMyApp.InitStatusLine; var R: TRect; { еа**Ёв Ја**Ёжл бва®ЄЁ бв*вгб* } begin GetExtent(R); { гбв***ў«Ёў*Ґв R ў Є®®а¤Ё**вл ўбҐЈ®} { нЄа*** } R.A.Y := R.B.Y - 1; { ЇҐаҐ¤ўЁЈ*Ґв ўҐаиЁ*г ** 1 бва®Єг } { ўлиҐ *Ё¦*Ґ© } StatusLine := New(PStatusLine, Init(R, { ᮧ¤*Ґв бва®Єг } { бв*вгб* } NewStatusDef(0, $FFFF, { гбв***ў«Ёў*Ґв ¤Ё*Ї*§®* Є®*⥪бв*®Ј® } { Help } NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit, { ®ЇаҐ¤Ґ«пҐв н«Ґ¬Ґ*в } NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose, { ¤агЈ®© } nil)), { Ў®«миҐ *Ґв Є«*ўЁи } nil) { Ў®«миҐ *Ґв ®ЇаҐ¤Ґ«Ґ*Ё© } )); end; { ::::::::::::::::?*ЁжЁ*«Ё§*жЁп MenuBar'л::::::::::::::::::::::: } const cmFileNew = 200; { ®ЇаҐ¤Ґ«Ґ*ЁҐ *®ў®© Є®¬**¤л } cmNewDialog = 201; procedure TMyApp.InitMenuBar; var R: TRect; begin GetExtent(R); R.B.Y := R.A.Y + 1; MenuBar := New(PMenuBar, Init(R, NewMenu( { ᮧ¤*вм Ї®«®бг б ¬Ґ*о } NewSubMenu('~F~ile', hcNoContext, NewMenu( { ®ЇаҐ¤Ґ«Ёвм ¬Ґ*о } NewItem(' ~N~ew', 'F3', kbF3, cmFileNew, hcNoContext, { н«Ґ¬Ґ*в } NewLine( { а*§¤Ґ«ЁвҐ«м } NewItem('>< E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext, nil)))), { Ў®«миҐ *Ґв н«Ґ¬Ґ*в®ў } NewSubMenu('~O~ptions', hcNoContext, NewMenu( { ®ЇаҐ¤Ґ«Ёвм ¬Ґ*о } NewItem(' ~D~ialog...', 'F8', kbF8, cmNewDialog, hcNoContext, { н«Ґ¬Ґ*в } nil)), { Ў®«миҐ *Ґв н«Ґ¬Ґ*в®ў } nil)) { Ў®«миҐ *Ґв Ї®¤¬Ґ*о } ))); { Є®*Ґж Ї®«®бл } end; { ::::::::::::::::?*ЁжЁ*«Ё§*жЁп ЋЄ**::::::::::::::::::::::: } const WinCount: Integer = 0; { Ё*ЁжЁ*«Ё§*жЁп бзҐвзЁЄ* ®Є®* } type PDemoWindow = ^TDemoWindow; { §*¬ҐвЁ¬, зв® ‚л ўбҐЈ¤* ®Ўкпў«пҐвҐ вЁЇ гЄ*§*вҐ«п ¤«п Є*¦¤®Ј® *®ў®Ј® ®ЎкҐЄв*®Ј® вЁЇ* } TDemoWindow = object(TWindow) { ®ЇаҐ¤Ґ«Ґ*ЁҐ *®ў®Ј® вЁЇ* ®Є** } constructor Init(Bounds: TRect; WinTitle: String; WindowNo: Integer); procedure MakeInterior(Bounds: TRect; Left: Boolean); end; constructor TDemoWindow.Init(Bounds: TRect; WinTitle: String; WindowNo: Integer); var S: string[3]; R: TRect; begin Str(WindowNo, S); TWindow.Init(Bounds, WinTitle + ' ' + S, wnNoNumber); GetExtent(Bounds); Bounds.Grow(-1,-1); { Ё*вҐамҐа Ї®¬Ґй*Ґвбп ў*гваЁ а*¬ЄЁ ®Є** } R.Assign(Bounds.A.X, Bounds.A.Y, Bounds.B.X div 2 + 1, Bounds.B.Y); MakeInterior(R, True); Bounds.Grow(-1,-1); { Ё*вҐамҐа Ї®¬Ґй*Ґвбп ў*гваЁ а*¬ЄЁ ®Є** } R.Assign(Bounds.B.X div 2, Bounds.A.Y, Bounds.B.X, Bounds.B.Y); MakeInterior(R,False); end; procedure TMyApp.NewWindow; var Window: PDemoWindow; R: TRect; begin Inc(WinCount); R.Assign(0, 0, 26, 7); { гбв**®ўЄ* **з*«м*®Ј® а*§¬Ґа* Ё Ї®§ЁжЁЁ } R.Move(Random(58), Random(16)); { б«гз*©*®Ґ ЇҐаҐ¬ҐйҐ*ЁҐ Ї® нЄа**г } Window := New(PDemoWindow, Init(R, 'Demo Window', WinCount)); DeskTop^.Insert(Window); { ўлўҐбвЁ ®Є*® ** Ї**Ґ«м нЄа*** } end; { ::::::::::::::::?*ЁжЁ*«Ё§*жЁп „Ё*«®Ј®ў®Ј® ЋЄ**::::::::::::::::::::::: } type DialogData = record CheckBoxData: Word; RadioButtonData: Word; InputLineData: string[128]; end; var DemoDialogData: DialogData; procedure TMyApp.NewDialog; var Dialog: PDialog; R: TRect; Control: Word; B: PView; begin R.Assign(20, 6, 60, 19); Dialog := New(PDialog, Init(R, 'Demo Dialog')); with Dialog^ do begin R.Assign(3, 3, 17, 6); { <-- ChekBox'л } B := New(PCheckBoxes, Init(R, NewSItem('~H~varti', NewSItem('~T~ilset', NewSItem('~J~arsberg', nil))) )); { B^.Options := B^.Options and not ofPostProcess; }{ <-- <H>,<T>,<J> а*Ў®в*ов в®«мЄ® Ґб«Ё Checkboxes *ЄвЁўҐ*!!! } Insert(B); R.Assign(2, 2, 13, 3); { <-- Label for ^^ } Insert(New(PLabel, Init(R, '~C~heckboxes', B))); R.Assign(20, 3, 34, 6); { <-- OptionBox'л } B := New(PRadioButtons, Init(R, NewSItem('~S~olid', NewSItem('~R~unny', NewSItem('~M~elted', nil))) )); Insert(B); R.Assign(20, 2, 28, 3); Insert(New(PLabel, Init(R, 'O~p~tions', B))); R.Assign(3, 8, 37, 9); { <-- InputLine } B := New(PInputLine, Init(R, 128)); Insert(B); R.Assign(2, 7, 24, 8); Insert(New(PLabel, Init(R, '~I~nputLine', B))); R.Assign(7, 10, 19, 12); Insert(New(PButton, Init(R, '~O~K', cmOK, bfDefault))); R.Assign(20, 10, 32, 12); Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal))); end; Dialog^.SetData(DemoDialogData); Control := DeskTop^.ExecView(Dialog); if Control <> cmCancel then Dialog^.GetData(DemoDialogData); end; procedure TMyApp.HandleEvent(var Event: TEvent); begin TApplication.HandleEvent(Event); if Event.What = evCommand then begin case Event.Command of {cmNewWin}cmFileNew: NewWindow; cmNewDialog: NewDialog; else Exit; end; ClearEvent(Event); end; end; { ::::::::::::::::?*ЁжЁ*«Ё§*жЁп ?*вҐамҐа* ЋЄ**::::::::::::::::::::::: } const MaxLines = 100; { нв® Їа®Ё§ў®«м*®Ґ зЁб«® бва®Є } MaxViewWidth = 132; var LineCount: Integer; Lines: array[0..MaxLines - 1] of PString; type TDrawBuffer = array[0..MaxViewWidth-1] of Word; {end;} type PInterior = ^TInterior; { ‡*¬ҐвЁ¬, зв® ‚л Ё§¬Ґ*пҐвҐ ЇаҐ¤Є* г TInterior } TInterior = object(TScroller) constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar); procedure Draw; virtual; end; constructor TInterior.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar); begin TScroller.Init(Bounds, AHScrollBar, AVScrollBar); GrowMode := gfGrowHiX + gfGrowHiY; SetLimit(128, LineCount); { Ј®аЁ§®*в*«м**п Ё ўҐавЁЄ*«м**п Ја**Ёжл бЄа®««Ё*Ј* } end; procedure TInterior.Draw; var Color: Byte; I, Y: Integer; B: TDrawBuffer; begin Color := GetColor(1); for Y := 0 to Size.Y - 1 do begin MoveChar(B, ' ', Color, Size.X); i := Delta.Y + Y; { Delta - ᬥйҐ*ЁҐ бЄа®««Ё*Ј* } if (I < LineCount) and (Lines[I] <> nil) then MoveStr(B, Copy(Lines[I]^, Delta.X + 1, Size.X), Color); WriteLine(0, Y, Size.X, 1, B); end; end; procedure TDemoWindow.MakeInterior(Bounds: TRect; Left: Boolean); var Interior: PInterior; R: TRect; begin Interior := New(PInterior, Init(Bounds, StandardScrollBar(sbHorizontal), StandardScrollBar(sbVertical))); if Left then Interior^.GrowMode := gfGrowHiY else Interior^.GrowMode := gfGrowHiX + gfGrowHiY; Insert(Interior); end; procedure ReadFile; var F: Text; S: String; begin LineCount := 0; Assign(F, 'C:\321\123.txt'); Reset(F); while not Eof(F) and (LineCount < MaxLines) do begin Readln(F, S); Lines[LineCount] := NewStr(S); Inc(LineCount); end; Close(F); end; procedure DoneFile; var I: Integer; begin for I := 0 to LineCount - 1 do if Lines[I] <> nil then DisposeStr(Lines[i]); end; { ::::::::::::::::‘®Ўб⢥**® Їа®Ја*¬¬*::::::::::::::::::::::: } begin MyApp.Init; { **з*«м**п гбв**®ўЄ* } with DemoDialogData do begin CheckboxData := 1; RadioButtonData := 2; { 0 = 1-л©, 1 = 2-®©, 2 = 3-Ё© } InputLineData := 'Copyright (C) 2004 Vovan-VE'; end; MyApp.Run; { ўлЇ®«*Ґ*ЁҐ } MyApp.Done; { §*ЄалвЁҐ } end.