Отправляет email-рассылки с помощью сервиса Sendsay

Pascal с нуля by [CPM]

  Все выпуски  

Pascal с нуля by [CPM] Выпуск №17


Информационный Канал Subscribe.Ru

[Ø] Рассылка "Pascal с нуля" by [CPM]. Выпуск №17 [Ø]

::[Ø]BEGIN[Ø]::

Автор: FreeMan[CPM] mailto: vovanc@bigmir.net

Дизайн:Ustas [CPM]  mailto: ustas1715@yandex.ru

Помогает: MedL[CPM] mailto: medlmail@bigmir.net

Editorial

Доброе время суток, друзья.

Ко мне на мыло поступило довольно много писем. Основная масса - просьба выслать предыдущие выпуски либо показать, где они лежат. Я отослал практически всем, кто этого просил. Чтоб больше не возникало вопросов такого рода, я буду в конце каждой рассылки распологать ссылку на архив выпусков, а также форму быстрой подписки.
Последние 3 дня приходили письма с вопросами, которые относятся к материалу, изложенному в конце предыдущей рассылки. Основываясь на этом, можно сказать, что вы успели усвоить материал, а значит можно уже творить следующий выпуск(в смысле этот).

Intro

В этом выпуске мы рассмотрим создание так называемого "дружественного интерфейса". Простыми словами, мы будем делать меню. Ведь если вы присмотритесь к более-менее серьёзным прогам, то сможете увидеть там меню.
Я выбрал эту тему не из-за того, что больше нам нечего рассматривать, а просто для закрепления материала. Я уверен, что вы и сами в состоянии сделать меню.

1. Теория

Мы уже делали жалкое подобие меню в программе из прошлого выпуска. Но то была всего лишь импровизация. Чтоб охватить практически весь материал мы создадим меню, которое работает в графическом режиме, работает с файлами, построено на процедурах, одним пунктом которого будет работа с массивами. Итак, начнём... И начинать будем с самого начала. Определим примерный алгоритм работы меню.

1. Переход в графический режим
2. Показать меню
3. Организовать переход от одного пункта к другому.
4. Создать подпрограмму, которая будет работать, если мы активировали данный пункт меню.
5. После отработки подпрограммы мы должны отобразить меню снова.
6. Красиво, закрыв файлы, "закрыв" графический режим, выйти.

Переходить в графический режим, я думаю, вы научились. Если нет - читайте соответствующий выпуск.
А вот как будем показывать меню - это вопрос. Щас попытаюсь всё рассказать. Начнём с разъяснения базовых понятий (или понятия, смотря сколько смогу придумать)

Текущий элемент - тот пункт, который сейчас подготовлен к выполнению. Лучше поймёте, если откроете щас какую-нибудь оболочку (типа FAR или NC, DOS), там нажмите что нибудь типа Alt+F1, мышь не используйте. Теперь поклацайте стрелку вверх... Видите изменение... Тот элемент, который подсвечен, мы и назовём текущим.

Перемещение - изменение текущего элемента.
Запуск - нажатие клавиши Enter.
Исполнение - вызов подпрограммы, которая должна отработать при запуске.

Вот. Больше ничего не могу щас придумать. Придумаю - напишу во время рассмотрения.
Допустим, мы теперь имеем представление о работе меню... "Пришьём" теперь сюда работу с файлами. Будем читать названия (имена) пунктов с файла. Для того, чтоб было сложнее всё организовать, будем использовать текстовые файлы.
Формат файла будет такой:

kol-vo(n)
punkt 1
punkt2
...
punkt n

То есть, в проге мы читаем первую строку. Запоминаем число, которое там стоит - N. Потом в цикле читаем N строк и выводим их на экран.
Также нужно организовать смену текущего элемента при нажатии определённых клавиш.

2. Практика

Создадим файл CPMenu.txt следующего содержания:

5
Fill Array
Show Array
Sort Array
Show Picture
EXIT

Это будет файл, из которого мы будем читать названия элементов.

Теперь, я предпологаю, стоит поместить сюда весь исходный код нашей менюхи, а потом по кусочкам разобрать его алгоритм, потому что очень трудно рассказывать про написание исходного кода без самого кода.

Uses Graph,CRT;
Const
n=10;
Var
poz:Byte;
strs:String;
zf:Boolean;
s1:Byte;
a:Array [1..n] Of Integer;

Procedure fill_arr; Forward;
Procedure show_arr; Forward;

Procedure initgr;
Var
grDriver: Integer;
grMode: Integer;
ErrCode: Integer;
Begin
grDriver := Detect;
InitGraph(grDriver, grMode, '');
ErrCode := GraphResult;

If ErrCode <> grOk then
Begin
 Writeln('Graphics error:', GraphErrorMsg(ErrCode));
 Halt(1);
End;

End;

Procedure show_menu(poz_:Byte;srt:String;Var s1_:Byte);
Var l,i:Byte;
str_s:String;
f:Text;
er:Integer;
Begin
Assign(f,srt);
 {$I-}
Reset(f);
 {$I+}

If IOResult<>0 Then Begin Writeln('Error: File Not Found');
 ReadKey; Halt(1);
End;

SetTextStyle(0,0,3);
SetColor(07);
OutTextXY(320-13*12,16,'OurFirstMenu');

SetTextStyle(0,0,2);
ReadLn(f,str_s);
Val(str_s,i,er);

If er<>0 Then Halt(1);

s1_:=i;

For l:=1 To i Do Begin

 If poz_=l Then SetColor(4)
 Else SetColor(White);

 ReadLn(f,str_s);
 OutTextXY(320-ord(str_s[0])*8,240-i*16+(l-1)*32,str_s);
End;

Close(f);
SetTextStyle(0,0,0);
End;

Procedure main(var poz__:Byte);
Begin

Case poz__ Of
 1:fill_arr;
 2:show_arr;
 3:zf:=FALSE;
 4:zf:=FALSE;
 5:zf:=FALSE;
Else Halt(1);
End;

End;

Procedure Yprav(max:Byte;Var poz_:Byte);
Var
c:Char;
Begin
c:=ReadKey;

Case c Of
 #80: Begin

 If poz_=max Then poz_:=1
 Else Inc(poz_);

 End;
 #72: Begin

 If poz_=1 then poz_:=max
 Else Dec(poz_);

 End;
 #77:poz_:=1;
 #13:Main(poz_);
End;

End;

Procedure fill_arr;
Var
i:Byte;
Begin

For i:=1 To n Do a[i]:=Random(1001)-500;

End;

Procedure show_arr;
Var
i:Byte;
s:String[4];
Begin
ClearDevice;
SetColor(White);

For i:=1 To n Do
Begin
 Str(a[i],s);
 OutText(s);
 OutText(' ');
End;

ReadLn;
End;

Begin
poz:=1;
strs:='CPMenu.txt';
zf:=true;
initgr;
Randomize;

Repeat
 ClearDevice;
 show_menu(poz,strs,s1);
 yprav(s1,poz);
Until NOT(zf);

End.
(*******************************
*  *
*(c) 2004-2005 Kiev, Ukraine [CPM] Group *
*  *
********************************)


3.Разбор полётов

Теперь разберём всю прогу по кусочкам.

Uses Graph,CRT;
Const
n=10;


Тут мы объявили модули и константу - количество элементов массива, с которым будем совершать действия.

Var
poz:Byte;
strs:String;
zf:Boolean;
s1:Byte;
a:Array [1..n] Of Integer;


Глобальные переменные.

poz - переменная, которая содержит номер текущего элемента.
zf - флаг выхода из проги.
s1 - тут содержится кол-во элементов меню, которое читается с первой строки нашего файла.
a - массив для манипуляций.

Procedure fill_arr; Forward;
Procedure show_arr; Forward;


Дело в том, что мы будем использовать это процедуры из другой процедуры. Поэтому надо ставить волшебное слово Forward. Если вы забыли, что это такое, то читайте 14-ый выпуск.

Procedure initgr;
Var
grDriver: Integer;
grMode: Integer;
ErrCode: Integer;
Begin
grDriver := Detect;
InitGraph(grDriver, grMode, '');
ErrCode := GraphResult;

if ErrCode <> grOk then
Begin
 Writeln('Graphics error:', GraphErrorMsg(ErrCode));
 Halt(1);
End;

End;


Процедура инициализации графики. Используется для перехода в графический видеорежим.

Procedure show_menu(poz_:Byte;srt:String;Var s1_:Byte);
Процедура., которая выводит меню на экран.
Первый параметр, который передаётся - номер текущего элемента (для того, чтоб его "подсветить")
Второй параметр - строка, содержащая имя файла (в нашем случае 'CPMenu.txt')
3-ий параметр передаётся по ссылке. Туда мы записываем кол-во элементов меню.

Var l,i:Byte;
str_s:String;
f:Text;
er:Integer;


Переменные:
l,i -под счётчики
str_s - сюда будем читать элементы меню
f - файловая переменная для связи с файлом
er - переменная под код ошибки (смотрите описание процедуры Val в хелпе)

Begin
Assign(f,srt);
{$I-}
Reset(f);
{$I+}
If IOResult<>0 Then Begin Writeln('Error: File Not Found');
ReadKey; Halt(1);End;


Связь с файлом. Не понимаете - читайте №16 рассылки.

SetTextStyle(0,0,3);
SetColor(7);
OutTextXY(320-13*12,16,'OurFirstMenu');


Выводим крупными серыми буквами "заголовок" меню.

SetTextStyle(0,0,2);

Слегка уменьшаем шрифт

ReadLn(f,str_s);
Val(str_s,i,er);


Читаем первую строку файла (там число, кол-во элементов). Потом переводим строку в число

If er<>0 Then Halt(1);

Переменной er, которую мы передаём 3-им параметром в процедуру Val будет присвоено значение, отличное от нуля, если произошла ошибка (в первой строке не число). В таком случае мы просто выходим.

s1_:=i;

Иначе запоминаем количество элементов.

For l:=1 To i Do Begin
 If poz_=l Then SetColor(4)
 Else SetColor(White);
 ReadLn(f,str_s);
 OutTextXY(320-ord(str_s[0])*8,240-i*16+(l-1)*32,str_s);
End;
Close(f);

SetTextStyle(0,0,0);
End;


В цикле поочерёдно читаем элементы и выводим их по центру экрана, при чем, если номер элемента совпадает с номером текущего элемента, мы изменяем его цвет. После чего закрываем файл и восстанавливаем стандартный размер шрифта.

Procedure main(var poz__:Byte);

Процедура получает управление при запуске элемента. При чём в неё передаётся номер элемента, который запустили.

Begin
Case poz__ Of
 1:fill_arr;


Если запустили первый элемент (Fill Array), то мы вызываем процедуру заполнения массива. Процедура вызывается из процедуры, поэтому нам было нужно поставить Forward.

2:show_arr;

Аналогично.

3:zf:=FALSE;
4:zf:=FALSE;


Написание процедур обработки этих двух элементов я поручаю вам.

5:zf:=FALSE;

Если флажок установлен в положение FALSE, то мы выходим из проги. Как вы заметили, аналогичные операции совершаются при запуске 3-его и 4-го пунктов меню... Но это легко исправимо - нужно написать процедуру, обрабатывающую это событие и поставить её вызов, как это сделано в первом и втором вызовах.

Else Halt(1);
End;
End;
Procedure Yprav(max:Byte;Var poz_:Byte);


Объявление процедуры, которая будет обрабатывать нажатия на клавиши.
1-ый параметр - кол-во элементов, а второй - текущая позиция, которая будет изменятся при нажатиии на управляющие клавиши.

Var c:Char;

Переменная, в которую будет занесен код нажатой клавиши

Begin
c:=ReadKey;


Ждём нажатия, а когда оно происходит - заносим код клавиши, на которую нажали в соответствующую переменную

Case c Of
#80: Begin
If poz_=max Then poz_:=1
Else Inc(poz_);
End;


Если нажали клавишу "стрелка_вниз", код которой #80, то делаем текущим следующий элемент.

#72: Begin
If poz_=1 then poz_:=max
Else Dec(poz_);
End;


Тоже самое, только "стрелка_вверх".

#77:poz_:=1;
#13:Main(poz_);
End;
End;


Если нажата клавиша ВВОД, то передаём в Main номер текущего элемента, который она обработает.

Procedure fill_arr;
Var
i:Byte;
Begin
For i:=1 To n Do a[i]:=Random(1001)-500;
End;


Процедура заполнения массива случайными элементами.

Procedure show_arr;
Var
i:Byte;
s:String[4];
Begin
ClearDevice;
SetColor(White);
For i:=1 To n Do
Begin
Str(a[i],s);
OutText(s);
OutText(' ');
End;
ReadLn;
End;


Процедура Вывода содержимого массива на экран.

Begin
poz:=1;
strs:='CPMenu.txt';
zf:=true;
initgr;


Присваиваем начальные значения переменным и инициализируем графику.

Randomize;

"Включаем" случайные числа.

Repeat
ClearDevice;
show_menu(poz,strs,s1);
yprav(s1,poz);
Until NOT(zf);


В цикле показываем меню, читаем клавиши.... Пока флаг не примет значение FALSE

End.

Конец проги.

(*******************************
*                                   *
*(c) 2004-2005 Kiev, Ukraine [CPM] Group *
*                                   *
********************************)

Фишка, которая возникла при отработки проги из предыдущего выпуска.

4.Заключение

Теперь вы можете вставить во все свои проги меню (или в меню все свои проги). Если у вас возникли вопросы, то пишите, наши адреса внизу.

Обещанная ссылка на архив выпусков: http://subscribe.ru/catalog/comp.soft.prog.pascalcpm
Обещанная форма быстрой подписки на рассылку:

Рассылки Subscribe.Ru
Pascal с нуля by [CPM]

Наша команда [CPM]:

Дизайн, верстка и корректировка >>> Ustas[CPM]

Пишет >>> FreeMan[CPM]
ICQ:88880172

  Помогает >>> FreeMan[CPM]
ICQ:88880172

::[Ø]END.[Ø]::

© 2004 Kiev Ukraine [CPM] Group 

http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.pascalcpm
Отписаться

В избранное