Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсяк.rtf
Скачиваний:
1
Добавлен:
02.08.2019
Размер:
197.84 Кб
Скачать

Текст программы

#include <iostream.h>

#include <conio.h>

#include <graphics.h>

void fillscreen()

{

int i;

setcolor(CYAN); // Заполняем экран цветом

for (i=0;i<480;i++)

line(0,i,639,i);

setcolor(6); // Выводим информацию о программе

outtextxy(20,453,"Курсовая работа студента группы АМ-112 Какорина Сергея");

outtextxy(20,465,"программа написана на языке Си++ с использованием принципов ООП");

}

void draw_window(int x1, int y1, int x2, int y2)

{ // Функция рисует окошко с тенью

int i; // фиксированного набора цветов

setcolor(LIGHTGRAY);

for (i=0; i<=y2-y1; i++)

line(x1,y1+i,x2,y1+i);

setcolor(BLACK);

line(x1+2,y1+2,x2-2,y1+2); // вывод рамки

line(x1+2,y2-2,x2-2,y2-2);

line(x1+2,y1+2,x1+2,y2-2);

line(x2-2,y1+2,x2-2,y2-2);

setcolor(DARKGRAY);

line(x1+2,y2+1,x2+2,y2+1); // вывод тени

line(x1+2,y2+2,x2+2,y2+2);

line(x2+1,y1+2,x2+1,y2+2);

line(x2+2,y1+2,x2+2,y2+2);

}

void ShowDialog(char* text) // демонстрирует небольшое диалоговое окно

{

int w,ch;

draw_window(130,130,510,240); // выводим окно

w=textwidth("Радостная информация")+10;

setcolor(LIGHTGRAY);

line(320-w/2,132,320+w/2,132); // стираем кусочек верхней линии

setcolor(BLACK);

line(132,135,319-w/2,135); // подрисовываем еще парочку линий

line(321+w/2,135,508,135);

outtextxy(320-w/2+5,131,"Радостная информация");

outtextxy(250,165,"Выбран пункт меню"); // выводим заголовок и станд. текст

setcolor(RED);

outtextxy(320-textwidth(text)/2,180,text); // выводим переменную text

setcolor(BLACK);

outtextxy(225,195,"Нажмите любую клавишу...");

ch=getch(); // Ждем нажатия клавиши

if (ch==0) ch=getch();

fillscreen(); // Перерисовываем экран

}

class Menu // класс меню представляет собой

{ // пункты меню и подменю

private:

char* name; // Имя пункта меню

Menu* next; // Указатель на следующий пункт

Menu* parent; // Указатель на родителя

Menu* sub; // Указатель на первый пункт подменю

unsigned int opened; // Пункт меню раскрыт

unsigned int selected; // Пункт меню выделен

public:

Menu(char* n) // Конструктор: создает пункт без подменю

{

name=n;

next=0;

sub=0;

parent=0;

opened=0;

selected=0;

}

Menu* AddItem(char* n) // Добавляет элемент следующим к текущему

{

next = new Menu(n);

next->SetParent(parent); // Родитель тот же

return next;

}

Menu* AddSubmenu(char* n) // Добавляет подменю к текущему

{

sub = new Menu(n);

sub->SetParent(this); // Родитель - текущий

return sub;

}

Menu* LevelUp() // Возвращает родителя текущего

{

if (parent!=0) return parent;

else return this;

}

void SetParent(Menu* m) // Устанавливает родителя

{

parent=m;

}

Menu* GetParent() // Возвращает родителя

{

return parent;

}

Menu* GetNext() // Возвращает указатель на седующий

{

return next;

}

Menu* GetSub() // Возвращает указатель на первый пункт

{ // подменю

return sub;

}

char* GetName() // Возвращает имя пункта

{

return name;

}

void PrintInfo() // Выводит информацию о пункте меню

{

cout<<name<<"\n";

}

void Select() // Выделяет данный пункт

{

selected=1;

}

void UnSelect() // Сбрасывает выделение

{

selected=0;

}

void OpenSubmenu() // Открывает подменю, если есть

{ // и выделяет там первый пункт

if (sub!=0)

{

opened=1;

sub->Select();

}

}

void CloseSubmenu() // Закрывает подменю, сбрасывая выделения

{ // и закрывая более "глубокие" открытые

opened=0; // подменю

Menu* tmp;

if (sub!=0)

{

tmp=sub;

while (tmp)

{

tmp->UnSelect();

tmp->CloseSubmenu();

tmp=tmp->GetNext();

}

}

}

int IsOpened() // Открыто ли здесь подменю?

{

return opened;

}

int IsSelected() // Выбран ли этот пункт?

{

return selected;

}

void paint(int x, int y) // Отрисовка системы подменю Главного Меню

{

Menu* tmp;

Menu* open=0; // Пункт с открытым подменю

int max_width=0, height, tw, num=0, i, xo,yo;

// max_width - максимальная длина названия пункта меню в пикселах

// height - суммарная высота пунктов в пикселах

// tw - рабочая переменная, смысловой нагрузки не несет

// num - количество пунктов

// i - рабочая переменная, смысловой нагрузки не несет

// xo, yo - координаты для отрисовки вложенного открытого подменю

tmp=this;

while (tmp) // Подсчитываем максимальную длину названий,

{ // кол-во пунктов

tw=textwidth(tmp->GetName());

if (tw > max_width) max_width=tw;

tmp=tmp->GetNext();

num++;

}

height = (textheight("A") + 4) * num + 6;

if (x+max_width+30 > 633) x=633 - max_width - 30;

if (y+height > 470) y=470 - height; // выполняем сдвиг,

// если меню выходит за границы

// экрана

draw_window(x,y,x+max_width+30,y+height);

// рисуем окошко, куда будем

// помещать пункты

tmp=this;

setcolor(BLACK);

x+=10;

y+=5;

while (tmp) // пока все не нарисуем

{

if (tmp->IsSelected()) // Пункт меню выделен - его надо инвертировать

{

setcolor(GREEN);

for (i=1;i<=textheight("A")+2;i++) // Высота: строка+2 пикс.

line(x-5,i+y-2,x+max_width+15,i+y-2);

setcolor(BLACK);

outtextxy(x,y,tmp->GetName());

// Если пункт открыт, это тоже надо нарисовать

if (tmp->IsOpened()) // но мы это сделаем позже

{

open=tmp->GetSub(); // сохраняем координаты и указатель

xo=x+max_width+23;

yo=y;

}

}

else outtextxy(x,y,tmp->GetName()); // рисуем обычный пункт

if (tmp->GetSub()) // рисуем "треугольничек", если у пункта

{ // есть подменю (в т.ч. и неоткрытое)

line(x+max_width+12,y+4,x+max_width+13,y+4);

line(x+max_width+12,y+3,x+max_width+12,y+5);

}

y+=textheight("A")+4;

tmp=tmp->GetNext();

// Нарисовав все текущее подменю, можем приступать

// к рисованию следующего вложенного. Если бы мы

// это сделали сразу, то потом дорисовывали бы

// текущее меню поверх уже нарисованного подменю

if (open) open->paint(xo,yo);

}

};

class MainMenu // Класс главное меню.

{

private:

Menu* list; // Список подменю

Menu* current; // Текущий пункт

Menu* selected; // Выделенный пункт

public:

MainMenu() // Конструктор

{

list=0;

current=0;

}

void AddItem(char* n) // Добавляет элемент следующим к текущему

{ // и делает новый элемент текущим

if (list==0)

{

selected = current = list = new Menu(n);

selected->Select();

}

else current = current->AddItem(n);

}

void AddSubmenu(char* n) // Добавляет подменю текущему и

{ // его первый элемент текущим

if (current!=0) current = current->AddSubmenu(n);

}

void LevelUp() // Делает текущим родителя текущего элемента

{

if (current!=0) current = current->LevelUp();

}

void paint() // Вывод системы меню на экран

{

Menu* tmp=list; // Рабочая переменная

int i, cur_x=18; // счетчик и координата вывода текста

setcolor(LIGHTGRAY); // Выводим полоску главного меню

for (i=0; i <= (textheight("A")+6); i++) // Высота: строка+6 пикс.

line(3,i+3,636,i+3);

setcolor(DARKGRAY); // Выводим тень полоски

line(5,i+3,638,i+3);

line(5,i+4,638,i+4);

line(637,4,637,i+4);

line(638,4,638,i+4);

setcolor(0); // Выводим пункты меню

while (tmp!=0 && cur_x<633) // Проверка на выход за полоску

{

if ( cur_x+textwidth (tmp->GetName()+18) < 633)

{

if (tmp==selected) // Пункт меню выделен - его надо инвертировать

{

setcolor(GREEN);

for (i=0;i<=textheight("A")+2;i++) // Высота: строка+2 пикс.

line(cur_x-3,i+5,cur_x+textwidth(tmp->GetName())+3,i+5);

setcolor(BLACK);

outtextxy(cur_x,6,tmp->GetName());

// Если пункт открыт, это тоже надо нарисовать

if (tmp->IsOpened()) tmp->GetSub()->paint(cur_x,12+textheight("A"));

}

else outtextxy(cur_x,6,tmp->GetName()); // Выводим обычный пункт

cur_x+=textwidth(tmp->GetName())+18; // Увеличиваем позицию курсора

tmp=tmp->GetNext(); // Берем следующий пункт

}

}

}

Menu* FindSelection() // Поиск "активного" выделения

{ // по всей иерархии меню

Menu* tmp;

int found=0;

tmp=selected;

while (!found)

{

if (tmp->IsOpened()) tmp=tmp->GetSub(); // открыто - заходим

else if (tmp->IsSelected()) found=1; // выделено - нашли!

else tmp=tmp->GetNext(); // не выделено - дальше

}

return tmp;

}

int keypress(int ch) // Обработчик нажатий клавиш

{

Menu* tmp;

Menu* sel;

switch (ch)

{

case 0: // Спецклавиша, за ней идет другой код

{

ch=getch();

return keypress(ch);

}

case 75: // Нажата клавиша "Влево"

{ // реакция - если находимся в подменю

int open=0; // выходим из него, иначе - перемещаем

sel=FindSelection(); // выделение Главного меню

tmp=sel->GetParent();

if ((tmp->GetParent() != 0) && tmp)

{

tmp->CloseSubmenu();

fillscreen();

}

else

{

if (selected->IsOpened()) // Если мы не в главном меню

{ // то надо заново открыть подменю

selected->CloseSubmenu();

fillscreen();

open=1;

}

selected->UnSelect();

tmp=list;

while (tmp->GetNext() != selected && tmp->GetNext()!=0) tmp=tmp->GetNext();

selected=tmp;

selected->Select();

if (open) selected->OpenSubmenu();

}

paint(); // Перерисовываем меню

return 0;

}

case 72: // Нажата клавиша "Вверх"

{ // реакция - перемещение курсора вверх,

if (selected->IsOpened()) // если в Главном меню - открываем

{ // подменю

sel=FindSelection();

tmp = sel->GetParent();

tmp = tmp->GetSub();

if (tmp==sel)

while (tmp->GetNext()!=0) tmp=tmp->GetNext();

else

while (tmp->GetNext()!=sel) tmp=tmp->GetNext();

sel->UnSelect();

tmp->Select();

}

else keypress(13);

paint();

return 0;

}

case 77: // Нажата клавиша "Вправо"

{ // Реакция - если у данного пункта есть

int open=0; // подменю - открываем, если нет - переходим

sel=FindSelection(); // к след. пункту Главного меню.

// В Главном меню - просто переход.

if (sel->GetSub() && (sel != selected)) sel->OpenSubmenu();

else

{

if (selected->IsOpened())

{

selected->CloseSubmenu();

fillscreen();

open=1;

}

selected->UnSelect();

selected=selected->GetNext();

if (selected==0) selected=list;

selected->Select();

if (open) selected->OpenSubmenu();

}

paint(); // Перерисовываем меню

return 0;

}

case 80: // Нажата клавиша "Вниз"

{ // Просто перемещение, в Главном меню

if (selected->IsOpened()) // окрывает подменю

{

sel=selected->GetSub();

tmp=selected->GetSub();

while (tmp)

{

while (tmp && !tmp->IsOpened())

tmp=tmp->GetNext();

if (tmp) tmp=sel=tmp->GetSub();

}

tmp = sel;

while (!tmp->IsSelected())

tmp=tmp->GetNext();

tmp->UnSelect();

tmp=tmp->GetNext();

if (!tmp) tmp = sel;

tmp->Select();

}

else keypress(13);

paint();

return 0;

}

case 27: // Нажата клавиша "Escape"

{ // Реакция - выход и программы

return 1;

}

case 13: // Нажата клавиша "Enter"

{ // Реакция - открытие подменю, если есть,

Menu* tmp; // если нет - диалоговое окно с названием,

tmp=FindSelection(); // и закрываем все вплоть до Главного

if (tmp->GetSub())

{

tmp->OpenSubmenu();

paint();

}

else

{

selected->CloseSubmenu();

fillscreen();

paint();

ShowDialog(tmp->GetName());

paint();

}

return 0;

}

}

return 0;

}

void Run() // Основной цикл программы

{

int ch,rez=0;

fillscreen();

paint(); // Рисуем меню

while (rez!=1) // Пока не ключ выхода

{

ch=getch(); // Ждем нажатия кнопки

rez=keypress(ch); // Обрабатываем нажатие кнопки

}

}

};

void main()

{

MainMenu MyMenu; // Создание Главного Меню

MyMenu.AddItem("Файл"); // Формирование структуры меню

MyMenu.AddSubmenu("Новый");

MyMenu.AddItem("Открыть");

MyMenu.AddSubmenu("Программу");

MyMenu.AddItem("Проект");

MyMenu.LevelUp();

MyMenu.AddItem("Печать");

MyMenu.AddSubmenu("Программы");

MyMenu.AddItem("Проекта");

MyMenu.AddItem("Параметры страницы");

MyMenu.AddItem("Предварительный просмотр");

MyMenu.AddItem("Установки принтера");

MyMenu.LevelUp();

MyMenu.LevelUp();

MyMenu.AddItem("Правка");

MyMenu.AddSubmenu("Поиск");

MyMenu.AddSubmenu("Поиск вперед");

MyMenu.AddItem("Поиск назад");

MyMenu.AddItem("Поиск и замена");

MyMenu.LevelUp();

MyMenu.AddItem("Переход");

MyMenu.AddItem("Стили");

MyMenu.AddSubmenu("Основной текст");

MyMenu.AddItem("Комментарий");

MyMenu.AddItem("Заголовок");

MyMenu.AddItem("Ссылка");

MyMenu.LevelUp();

MyMenu.AddItem("Очистить");

MyMenu.AddItem("Вставить объект");

MyMenu.AddSubmenu("Из файла");

MyMenu.AddItem("Таблица");

MyMenu.AddItem("Диаграмма");

MyMenu.AddItem("Со сканнера");

MyMenu.AddItem("Сноска");

MyMenu.LevelUp();

MyMenu.AddItem("Выделить все");

MyMenu.LevelUp();

MyMenu.AddItem("Вид");

MyMenu.AddSubmenu("Документ");

MyMenu.AddSubmenu("Обычный");

MyMenu.AddItem("Разметка");

MyMenu.AddItem("Синтаксическая подсветка");

MyMenu.AddItem("Показывать ссылки");

MyMenu.LevelUp();

MyMenu.AddItem("Среда");

MyMenu.AddSubmenu("Панели инструментов");

MyMenu.AddItem("Окно отладчика");

MyMenu.AddItem("Окно процессора");

MyMenu.LevelUp();

MyMenu.LevelUp();

MyMenu.AddItem("Сервис");

MyMenu.AddSubmenu("Совместная работа");

MyMenu.AddSubmenu("Сверить версии");

MyMenu.AddItem("Сформировать апдейт");

MyMenu.AddItem("Сопроводительная информация");

MyMenu.AddItem("Подключить модуль");

MyMenu.AddItem("Список сотрудников");

MyMenu.LevelUp();

MyMenu.AddItem("Авто-подсказки");

MyMenu.AddItem("Макросы");

MyMenu.AddSubmenu("Список");

MyMenu.AddItem("Записать");

MyMenu.AddItem("Отредактировать");

MyMenu.LevelUp();

MyMenu.AddItem("Язык");

MyMenu.AddSubmenu("Изменить основной язык");

MyMenu.AddItem("Добавить язык к проекту");

MyMenu.LevelUp();

MyMenu.LevelUp();

MyMenu.AddItem("Отладка");

MyMenu.AddSubmenu("Компилировать");

MyMenu.AddItem("Точки останова");

MyMenu.AddSubmenu("Установить/сбросить");

MyMenu.AddItem("Перейти к следующей");

MyMenu.AddItem("Сбросить все");

MyMenu.LevelUp();

MyMenu.AddItem("Отследить значение переменной");

MyMenu.AddItem("Пошаговое выполнение");

MyMenu.AddSubmenu("Через");

MyMenu.AddItem("Внутрь");

MyMenu.LevelUp();

MyMenu.AddItem("Выполнить");

MyMenu.AddSubmenu("До курсора");

MyMenu.AddItem("Итерацию");

MyMenu.AddItem("До конца блока");

MyMenu.AddItem("До конца модуля");

MyMenu.LevelUp();

MyMenu.LevelUp();

MyMenu.AddItem("Справка");

MyMenu.AddSubmenu("О программе");

MyMenu.AddItem("Помощь по среде");

MyMenu.AddSubmenu("Содержание");

MyMenu.AddItem("Интерфейс");

MyMenu.AddItem("Меню");

MyMenu.AddItem("Горячие клавиши");

MyMenu.LevelUp();

MyMenu.AddItem("Помощь по языку");

MyMenu.AddSubmenu("Содержание");

MyMenu.AddItem("Поиск");

MyMenu.AddItem("Помощь по контексту");

MyMenu.LevelUp();

MyMenu.AddItem("Он-лайн");

MyMenu.AddSubmenu("Официальный сервер");

MyMenu.AddItem("Неофициальные страницы");

int driver=DETECT,mode=VGAHI; // Переводим комп в граф-режим

initgraph(&driver,&mode,"");

MyMenu.Run(); // Запускаем систему

closegraph(); // Переводим назад в текст. режим

}