Помощь - Поиск - Пользователи - Календарь
Полная версия: Меню и файлы
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Sensitive
Здравствуйте.
У меня такой вопрос. Есть меню из 3-х пунктов. Если нажимается первый пункт, то должно появиться следующее меню, где также можно выбирать пункты второго меню. Содержимое второго меню хранится в файле. То есть при нажатии на первый пункт главного меню я вывожу пункты второго меню из файла. Как сделать, чтобы из этих (выведенных из файла) пунктов также можно было выбирать... или это невозможно?
Спасибо заранее за помощь.
Tan
Есть же оператор case(x), что тебе его мешает использовать для того, чтобы осуществить выбор.
Sensitive
Цитата(Tan @ 7.11.2007 19:30) *

Есть же оператор case(x), что тебе его мешает использовать для того, чтобы осуществить выбор.


с case у меня получается работать только если пункты меню заданы стринговской константой. А если я их вывела из файла, то не могу понять как использовать case в данном случае...
volvo
Sensitive, для этого надо максимально отделить функцию отображения меню от всего остального. То есть, есть какой-то массив строк, есть функция
function get_menu(const s_arr: array of string): integer;
, которая отображает этот массив и подсвечивает нужный элемент в зависимости от выбора пользователя. Когда нажат Enter - возвращается индекс выбранного значения. Все. Больше эта функция не должна быть привязана ни к чему. Только так ты сможешь обеспечить работу с одинаковой легкостью с меню любой вложенности.

Примеры я выкладывал у себя на сайте: http://volvo71.narod.ru/menus.htm
Sensitive
Спасибо, я попробую.
Sensitive
посмотрела меню на сайте. взяла пока что тупо меню оттуда... вот получается вывожу главное меню, и подменю. А дальше мне еще нужно выводить подменюшки-там где "Просмотр данных" и "Добавление данных"(код ниже)...не знаю как это сделать, и как отделить подпрограмму отрисовки меню не поняла (как говорил Volvo). Вот мой код, посмотрите плиз.

uses crt;
Type MenuType=(Vertical);
const
width = 12;
nItems = 3;
optNormal = LightGray;
optSelected = Yellow;
s: array [1..3] of string=('termini','podprogrammi','exit');
t: array[1..3] of string=('Prosmotr dannih','Dobavlenie dannih','Vozvrat v menu');
var
X, Y,
selected,
row: integer;
_style: MenuType;

procedure MakeMenu (optText: array of string; MaxItems: integer);
var
i, _X: byte;
begin
Y := row;
_X := X;
for i := 0 to MaxItems-1 do
begin
GoToXY (_X, Y);
if i = selected then
TextColor (optSelected)
else
TextColor (optNormal);
write (optText[ i ]);
inc (Y, 2);
end;
end;
function MenuOption (var optText: array of string; MaxItems: integer): byte;
var
ch: char;
begin
selected := 0;

X := (80 - width) div 2;
row := (25 - MaxItems) div 2;
repeat
MakeMenu (optText, MaxItems);

ch := readkey;
if ch = #0 then
ch := readkey;

case ch of
#80, #77: {Down/Right}
begin
inc (Selected);
if Selected = MaxItems then
Selected := 0;
MakeMenu (optText, MaxItems);
end;
end;
until ch = #13;

MenuOption := Selected + 1;
TextColor (optNormal);
clrscr;
end;
Procedure Prosmotr;
var g:text; s:string[20]; i:byte;
begin
assign(g,'termini.txt');
reset(g);
while not eof(g) do
begin
readln(g,s);
{gotoxy(14,whereY+1);}
writeln(s);
end;
end;

Procedure ShowMenu(s:array of string);
var
Option,i: byte;
begin
_style := Vertical;
repeat
clrscr;
Option := MenuOption (s, nItems);

case option of
1:showMenu(t);
{ 2: ...;
3: ...; }
end
until Option = nItems;
end;

begin
showMenu(s);
end.
volvo
Да хоть еще 10 уровней... Смотри, я добавил тип TProcedure, и еще один уровень меню (который ничего не делает, только отображается, но на него очень просто повесить какие-то действия) на "Prosmotr dannih":

Нажмите для просмотра прикрепленного файла

Разберешься?
Sensitive
Да, volvo, с этим поняла. И действительно можно сделать теперь много уровней меню-очень помог. Но... Мне получается сами пункты меню ("Просмотр данных" например) нужно выводить из файла, то есть я их никак не введу в строковую константу... как мне быть? выводить я их думала процедурой Prosmotr;
Procedure Prosmotr;
var g:text; s:string[20]; i:byte;
begin
assign(g,'termini.txt');
reset(g);
while not eof(g) do
begin
readln(g,s);
{gotoxy(14,whereY+1);}
writeln(s);
end;
end;

а куда и как её влепить? Пробовала, но ничего не выходит... то есть у меня получается эта процедура будет выводить список терминов, а пользователь уже должен из них выбрать тот,кторый он хочет просмотреть(описание каждого термина тоже будет выводиться из файла).
Вот и застряла...не продвигаюсь никуда-не получается.
volvo
А как, прости, ты будешь знать, какое ДЕЙСТВИЕ выполнять при выборе того или иного пункта меню, прочитанного из файла? Просто прочесть строки из файла и отобразить их в меню - без проблем:

const
max_lines_in_menu = 15;
type
myString = string;

PStrArr = ^strArr;
strArr = array[1 .. max_lines_in_menu] of myString;

function Prosmotr(f_name: string; var size: integer): PStrArr;
var
f: text;
s: string;
i: integer;
p: PStrArr;
begin
assign(f, f_name);
reset(f);
readln(f, size); { <--- Первая строка файла - количество строк в менюшке }
getmem(p, size * sizeof(myString)); { <--- берем столько памяти, сколько нужно для хранения }
i := 1;
while not eof(f) do begin
readln(f, s);
p^[i] := s; inc(i); { <--- заполняем массив }
end;
close(f);
Prosmotr := p;
end;


procedure do_termini;
var
p: PStrArr;
size: integer;
begin
p := Prosmotr('termini.txt', size); { <--- прочли файл в дин. память }
ShowMenu(p^, t_proc); { <--- отрисовали меню (вот только с ДЕЙСТВИЯМИ - непонятно) }
FreeMem(p, size * sizeof(myString)); { <--- освободили память }
end;


Файл: Нажмите для просмотра прикрепленного файла

Если у тебя возник вопрос о том, что в некоторых подменюшках может быть по 3, а в некоторых - и по 5 элементов, то это тоже не проблема, достаточно не брать nItems в ShowMenu из константы, а передавать еще одним параметром (как раз в приведенном выше коде Prosmotr заодно возвращает и длину массива строк).

Только вот с массивом Proc - непонятно, что делать... Откуда ты (вернее, программа, читающая файл 'termini.txt') будет знать, что по нажатию на первый пункт меню надо открыть еще один файл? Сейчас-то пока массив Proc для прочитанного из файла меню задается вручную... Ну, извратиться, конечно можно (если надо - говори, я попробую объяснить, как это преодолеть, есть кое-какая идея), но стоит ли оно таких ухищрений?
Sensitive
Ну пока что я разберусь с тем, что ты написал... а вообще нужно чтобы работала программа именно так, как ты понял, потому что еще будет процедура добавления термина, а как же я его добавлю в константу...поэтому подменюшку выводим из файла...
пока поразбираюсь с тем, что есть.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.