Так вот дело понятное, сейчас работая с такими довольно массивными проектами написанными на Дельфи, иногда мне встречаются модули в которых используются эти самые операторы. Блин, я больше всего не люблю изменять такие модули(хорошо что их всего парочка), потому что как правило в них исправляя одну проблему появляется новых две, ведь кода в них не мало, писался этот код несколькими программистами до меня, и чтобы понять всю логику таких модулей приходится тратить не один час, а иногда не один день, и уж поверьте это удручает, поэтому начинающим программистам чисто так по человечески скажу - не привыкайте использовать этот оператор с "малых лет".
Теперь немного ближе к теме. Прошли мы значит в колледже этот оператор, учитель сказал нам что это "кака", но вот проходит пара лекций и вдруг нам дается официальное разрешение использовать данный оператор для создания цветового меню. Как же я тогда в душе злился. Я помню тогда подошел к преподавателю и показал ей свой вариант решения задачи, где не нужно было использовать никакого оператора Goto, и при этом все прекрасно работало, но в ответ получил примерно следующую фразу "Молодец, ты можешь так придумать, а другие не могут, поэтому пусть делают как умеют". Я помню пытался одногруппникам донести свой вариант, и объяснить почему так лучше, но понимание нашел лишь у пары человек. Остальным было пофиг.
Обычная реализация данного меню состояла в том что при нажатии определенных клавиш оператор Goto переносил курсор в нужный кусок кода который в свою очередь делал какие-то перерисовки и выполнял определенные действия и ждал следующего нажатия при надобности чтобы в очередной раз перейти в другой кусок кода. Когда одногрупники стали использовать такой вариант в своих более менее весомых(больших) программах, разобраться в их коде было сложно, и когда меня просили помочь с чем-то, я первые раза три отправлял таких лесом и рекомендовал привести код в порядок ибо было мне в лом разбираться в "стоге сена".
А теперь демонстрирую свой вариант реализации цветого меню в Паскале, с возможностью строить многоуровневые меню. Кстати в данном варианте все ещё есть недостатки, то есть, имеются "штуки" которые можно сделать ещё лучше, но это вы уж сами :)
Код моего варианта, с примером использования:
Uses crt;
var str,str2,STR3:array[1..20]of string;
I:integer;
k:char;
X11,X22:integer;
{Универсальная процедура для вывода вертикального меню, параметры описаны ниже}
Procedure menu(kl,XX,YY:integer; pun:array of string;
fon,txt,fon1,txt1:integer;var key:char; X1:integer);
{колич.пунк.}{место по Х}{место поУ}{имена пунк.}{нор.фон}
{нор.текст}{выд.фон}{выд.текст}{код клавиши}{положение курсора}
begin
textbackground(fon);
textcolor(txt);
{ ClrScr;}
{ GotoXY(XX,YY); Кому надо можно использовать рамку, но для вложенных менюх такой вариант не пойдет.
write('г============МЕНЮ============¬');
For I:=1 to kl+1 do begin
GotoXY(XX,YY+i);
write('¦ ¦');
end;
GotoXY(XX,YY+i);
write('L============================-');}
For I:=1 to kl do begin
GotoXY(XX+1,YY+i);
write(pun[i]);
end;
x1:=1;
repeat
if key=#80 then X1:=X1+1;
if key=#72 then X1:=X1-1;
if X1>KL then X1:=1;
if X1<1 then X1:=KL;
For I:=1 to kl do begin
If x1=i then begin textcolor(txt1); textbackground(fon1); end
else begin textcolor(txt); textbackground(fon); end;
GotoXY(XX+1,YY+i);
write(pun[i]);
end;
key:=#0;
key:=readkey;
Until (key=#13)or(key=#27);
end;
{Процедура для вывода горизонтального меню, для отдельных частных случаев требует некоторой правки.
Желающие могут усовершенствовать до универсального вида.}
Procedure Main_menu(var Y1:integer;Key:char);
begin
Y1:=1;
repeat
GotoXY(1,1);
write('Файлы БД Задачи Выход');
if key=#75 then Y1:=Y1-1;
if key=#77 then Y1:=Y1+1;
if Y1>3 then Y1:=1;
if Y1<1 then Y1:=3;
GotoXY(1,1);
If y1=1 then begin textcolor(15); textbackground(4); end
else begin textcolor(15); textbackground(9); end;
write(' Файлы БД ');
GotoXY(12,1);
If y1=2 then begin textcolor(15); textbackground(4); end
else begin textcolor(15); textbackground(9); end;
write(' Задачи ');
GotoXY(22,1);
If y1=3 then begin textcolor(15); textbackground(4); end
else begin textcolor(15); textbackground(9); end;
write(' Выход ');
key:=#0;
key:=readkey;
Until key=#13;
end;
Begin
{А вот и простейший пример использования данных процедур в комбинации.}
ClrScr;
{Заполняем массив пунктов первого меню}
str[2]:=' Файл 1 ';
str[3]:=' Файл 2 ';
str[4]:=' Файл 3 ';
str[5]:=' Файл 4 ';
str[6]:=' Файл 5 ';
str[7]:=' Выход ';
{Заполняем массив пунктов второго меню}
str2[2]:=' Задача 1 ';
str2[3]:=' Задача 2 ';
str2[4]:=' Задача 3 ';
str2[5]:=' Задача 4 ';
str2[6]:=' Задача 5 ';
str2[7]:=' Выход ';
{Заполняем массив пунктов третье меню(вложенность третьего уровня)}
str3[2]:=' Ввод в файл ';
str3[3]:=' Дополнение файла ';
str3[4]:=' Удаление из файла ';
str3[5]:=' Замена компонент файла ';
str3[6]:=' Вставка компонент файла ';
str3[7]:=' Просмотр файла ';
str3[8]:=' Выход ';
Main_menu(X11,K); {вызовим главное меню(горизонтальное).}
{Получив в переменную X11 номер выбранного пункта, вызовим соответствующее подменю.}
If (X11=1) then
begin
Menu(6,0,1,str,9,15,4,3,k,x22);
If (k=#13) then
Menu(7,11,X22+1,str3,9,15,4,3,k,x22);
end;
if (X11=2) then
Menu(6,11,1,str2,9,15,4,3,k,x22);
end.
Код конечно нуждается в хорошем рефакторинге, но сильно строго не судите, писал я его в 2005 году будуче не опытным студентом :) Но в качестве примера сойдет, да и основная мысль думаю ясна. Если все же что-то не понятно постите в комментариях свои вопросы, поясню.
К коду добавлю пару слов. Все операторы Goto были заменены такой конструкцией как процедура/функция, и циклами, на мой взгляд куда лучше чем перемещаться по дублирующим друг друга кускам кода которые в дальнейшем крайне тяжело править. Понятное дело что такие с позволения сказать программы, нужны наверное только студентам и тем кто делает на студентах деньги, но просто не мог смолчать =)
Это не большое отступление так сказать о наболевшем. В следующий раз постараюсь обозреть процесс создания игры-арканойда все на том же добром Турбо-Паскале, а затем уже буду потихоньку прекращать описывать "баяны" написанные на Паскале =)

Комментариев нет:
Отправить комментарий