Для своей задачи написал (почти написал) простенький модуль, который выводит на экран строку для ввода и редактирования текста (наподобие TEdit в Delphi, но под TPascal). Имеется возможность задания фильтра ввода (метод SetFilter) и собственно вызов окна на экран (Execute). Когда вызывается последний метод, на экране по-тупому "рисуется" строка ввода для текста и в неё перемещается курсор. После ввода (редактирования) текста по нажатию клавиши Enter метод Execute возвращает True. Соответственно, окошко прячется и можно продолжать работать с основной программой. Проблема состоит в том, что если до вызова Execute на экране уже что-то выведено (а у меня там в тектовом режиме псевдографикой нарисована таблица с числами), то надо как-то восстановить фон, который находился под строкой ввода до вызова Execute. И я не знаю, как лучше реализовать процедуру Hide моего объекта. Можно конечно производить перерисовку таблицы в основном окне после ввода текста, однако хотелось бы, чтобы моя панелька самостоятельно восстанавливала предыдущий фон. Поэтому вопрос: как лучше это сделать? можно ли как-то сохранить содержимое экрана в данной области и отрисовать его по вызову процедуры Hide или есть решения лучше?
P.S. сторонние модули не предлагать: преподаватель требует, чтобы программа была написана полностью самостоятельно, да и просто хочется все сделать своими силами.
Вот текст модуля. Если будут какие-либо критические замечания по реализации - буду признателен за помощь.
Interface
Type
TEditBox = object
Caption: string;
Text: string;
BgColor: byte;
TxtColor: byte;
X, Y, PanelSize: byte;
function Execute: boolean;
function GetCurPos: byte;
procedure SetFilter(filt: byte);
private
CursorPos: byte;
filter: array[1..8] of boolean;
OldBgColor, OldTxtColor: byte;
procedure Show;
procedure Hide;
procedure PrintText;
end;
Implementation
uses Crt;
{Установка фильтра ввода}
procedure TEditBox.SetFilter(filt: byte);
begin
filter[1]:= (128 AND filt) <> {цифры}
filter[2]:= (64 AND filt) <> 0;{буквы a..z}
filter[3]:= (32 AND filt) <> 0;{буквы A..Z}
filter[4]:= (16 AND filt) <> 0;{допущена только одна точка (ввод десятичных чисел)}
filter[5]:= (8 AND filt) <> 0;{пробел}
filter[6]:= (4 AND filt) <> 0;{знаки препинания и др. символы}
filter[7]:= (2 AND filt) <> 0;{прячем текст за звездочками для ввода пароля}
filter[8]:= true;{флаг того, что фильтр был настроен пользователем}
end;
{рисует панель ввода и выводит текст, содержащийся в свойстве text}
procedure TEditBox.PrintText;
var i: byte;
begin
GotoXY(X,Y);
TextBackground(BgColor);
For i:= 1 to PanelSize do Write(' ');
GotoXY(X,Y);
TextColor(TxtColor);
if filter[7] then for i:= 1 to length(text) do write('*') else Write(Text);
GotoXY(X + CursorPos, Y);
end;
{выводит заголовок панели (Caption) и вызывает процедуру вывода текста}
procedure TEditBox.Show;
begin
if Caption<> '' then
begin
GotoXY(X, Y-1);
Write(Caption);
end;
CursorPos:= Length(text);
PrintText;
end;
{Метод для вызова окна: обрабатывает нажатия клавиш и возвращает True при нажатии Enter}
function TEditBox.Execute: boolean;
var
ch: char;
begin
if not filter[8] then
SetFilter(253);
Show;
Repeat
ch:= ReadKey;
case ch of
{‚«¥¢®}
#75: if CursorPos > 0 then dec(CursorPos);
{‚¯à ¢®}
#77: if (CursorPos < PanelSize) and (CursorPos < Length(text)) then
inc(CursorPos);
{‚¢®¤ æ¨äà}
#48..#57: if (Length(Text) < PanelSize) and filter[1] then
begin
Insert(ch, Text, CursorPos+1);
Inc(CursorPos);
end;
{‚¢®¤ áâà®çëå ¡ãª¢}
#97..#122: if (Length(Text) < PanelSize) and filter[2] then
begin
Insert(ch, Text, CursorPos+1);
Inc(CursorPos);
end;
{‚¢®¤ § £« ¢ëå ¡ãª¢}
#65..#90: if (Length(Text) < PanelSize) and filter[3] then
begin
Insert(ch, Text, CursorPos+1);
Inc(CursorPos);
end;
{‚¢®¤ â®çª¨. …᫨ â®çª 㦥 ãáâ ®¢«¥ , â® ¥ ¢¢®¤¨¬ ¨ç¥£®.}
#46: if (Length(Text) < PanelSize) and filter[4] and (pos('.',Text)=0) then
begin
Insert(ch, Text, CursorPos+1);
Inc(CursorPos);
end;
{‚¢®¤ ¯à®¡¥« .}
#32: if (Length(Text) < PanelSize) and filter[5] then
begin
Insert(ch, Text, CursorPos+1);
Inc(CursorPos);
end;
{‚¢®¤ § ª®¢ ¯à¥¯¨ ¨ï ¨ ¤à. ᯥæᨬ¢®«®¢.}
#33..#47, #58..#64, #91..#96, #123..#126:
if (Length(Text) < PanelSize) and filter[6] then
begin
Insert(ch, Text, CursorPos+1);
Inc(CursorPos);
end;
{“¤ «¥¨¥ ᨢ®« (Backspace)}
#8: If CursorPos > 0 then
begin
Delete(Text, CursorPos, 1);
dec(CursorPos);
end;
#27: begin
Execute:= false;
Exit;
end;
end;
PrintText;
until ch = #13;
Execute:= true;
end;
{Возвращает позицию курсора внутри поля ввода относительно начала строки}
function TEditBox.GetCurPos: byte;
begin
GetCurPos:= CursorPos;
end;
{Должна прятать окно ввода. Собственно, с этим и нужна помощь: как стереть строку для ввода и заголовок и восстановить прежний фон???}
procedure TEditBox.Hide;
begin
{С этим и требуется помощь. Как лучше всего стереть все, что было нарисовано при вызове Execute и восстановить фон в этом месте??}
end;
end.
А вот примерно так это применяется:
var
Edit1: TEditBox;
begin
{Настраиваем объект}
Edit1.caption:= 'Enter value: ';
Edit1.Text:= '0';
Edit1.txtcolor:= 15;
Edit1.PanelSize:= 10;
Edit1.X:=50;
Edit1.Y:= 10;
Edit1.SetFilter(144);
If Edit1.execute then
Writeln (Edit1.Text);
end.