Помощь - Поиск - Пользователи - Календарь
Полная версия: Строка для ввода и редактирования текста
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
kramolnic
Всем доброго времени суток.

Для своей задачи написал (почти написал) простенький модуль, который выводит на экран строку для ввода и редактирования текста (наподобие TEdit в Delphi, но под TPascal). Имеется возможность задания фильтра ввода (метод SetFilter) и собственно вызов окна на экран (Execute). Когда вызывается последний метод, на экране по-тупому "рисуется" строка ввода для текста и в неё перемещается курсор. После ввода (редактирования) текста по нажатию клавиши Enter метод Execute возвращает True. Соответственно, окошко прячется и можно продолжать работать с основной программой. Проблема состоит в том, что если до вызова Execute на экране уже что-то выведено (а у меня там в тектовом режиме псевдографикой нарисована таблица с числами), то надо как-то восстановить фон, который находился под строкой ввода до вызова Execute. И я не знаю, как лучше реализовать процедуру Hide моего объекта. Можно конечно производить перерисовку таблицы в основном окне после ввода текста, однако хотелось бы, чтобы моя панелька самостоятельно восстанавливала предыдущий фон. Поэтому вопрос: как лучше это сделать? можно ли как-то сохранить содержимое экрана в данной области и отрисовать его по вызову процедуры Hide или есть решения лучше?
P.S. сторонние модули не предлагать: преподаватель требует, чтобы программа была написана полностью самостоятельно, да и просто хочется все сделать своими силами.
Вот текст модуля. Если будут какие-либо критические замечания по реализации - буду признателен за помощь.
Код
Unit Edit;

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.
kramolnic
Цитата(volvo @ 7.12.2006 19:00) *

Так пойдет?


Конечно пойдет! Спасибо за готовый код... good.gif
volvo
Код не "готовый", а исправленный, заметь... Это - как говорится "две большие разницы".
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.