Печатать книгуПечатать книгу

§ 20. Создание приложений

Сайт: Профильное обучение
Курс: Информатика. 11 класс (Повышенный уровень)
Книга: § 20. Создание приложений
Напечатано:: Гость
Дата: Понедельник, 29 Апрель 2024, 13:22

20.1. Разработка оконных приложений

Создание любого оконного приложения осуществляется, как правило, в три этапа:

  1. Создание интерфейса приложения, т. е. средств взаимодействия пользователя с программой.
  2. Разработка сценария работы будущего приложения. На этом этапе определяют, какая информация будет выводиться на экран, какие события будут происходить при использовании различных компонентов, как приложение должно завершить работу, какие результаты и в каком виде сохранить и т. д.
  3. Разработка алгоритма решения поставленной задачи.

Большинство приложений в операционной системе Windows выглядят и ведут себя сходным образом. Компания Microsoft предложила рекомендации для разработки программного обеспечения, направленные на то, чтобы пользователь не тратил время на освоение нюансов пользовательского интерфейса новой программы, а сразу начал продуктивно ее использовать. Эти рекомендации основаны на психофизиологических особенностях человека и существенно облегчат жизнь будущим пользователям вашей программы.

Приведем некоторые рекомендации по разработке графического интерфейса оконных приложений (пример 20.1)

Пример 20.1. Рекомендации по созданию оконных приложений.

  1. В приложении рекомендуется разместить главное меню и инструментальную панель быстрых кнопок, дублирующих основные разделы меню.
  2. Желательно, чтобы объекты приложения обладали контекстными меню, появляющимися при нажатии правой клавишей мыши на объекте.
  3. Для объектов рекомендуется прописать подсказки, всплывающие при наведении указателя мыши на объект.
  4. Рекомендуется реализовать строку состояния, используемую для выдачи различной информации.
  5. При нажатии клавиши F1 должен загружаться файл справки.
  6. В программе желательно реализовать возможность настройки и сохранения настроек, чтобы при следующем сеансе работы их не пришлось устанавливать заново.
  7. Если результат работы приложения зависит от каких-либо параметров, обязательно укажите значения по умолчанию. Они позволят ускорить взаимодействие пользователя с программой, а также являются примером того, в каком формате данные следует вводить.
Мощным воздействием на психику человека является цвет, поэтому с ним нужно обращаться очень осторожно. Нужно стремиться использовать ограниченный набор цветов и уделять внимание их правильному сочетанию. Восприятие цвета у человека очень индивидуально, поэтому не стоит навязывать всем свое видение цвета. Желательно, чтобы основной цвет формы был нейтральным (например, у большинства приложений Microsoft — это светло-серый цвет).

20.2. Создание меню

Практически любое приложение должно иметь меню, которое дает удобный доступ к функциям программы. Существует несколько типов меню:

  • главное меню с выпадающими списками разделов;
  • каскадные меню, в которых разделу первичного меню ставится в соответствие список подразделов;
  •  контекстные меню, появляющиеся при нажатии правой клавишей мыши на объекте.

В Delphi меню создаются компонентами  MainMenu (главное меню) и PopupMenu  (контекстное меню), расположенными на панели Standard. На форме компоненты можно размещать в любом месте, во время выполнения программы сами компоненты не видны (пример 20.2). На этапе выполнения программы главное меню будет помещено на свое стандартное место — наверху формы, контекстное меню появится только после нажатия правой кнопки мыши по тому компоненту, к которому оно относится.

Для добавления новых пунктов меню нужно сделать двойной щелчок на MainMenu1 или нажать на кнопку  около свойства Items в окне инспектора объектов. Откроется окно редактора меню (пример 20.3). Каждый пункт меню является отдельным объектом. Названия пунктов меню прописываются в свойстве Caption в окне инспектора объектов. Созданием пунктов меню можно управлять из контекстного меню (пример 20.4). Пункт Create Submenu позволяет создавать каскадные меню. Структуру меню можно увидеть в окне Structure (пример 20.5).

Для каждого пункта меню основным событием является событие OnClick.

Создание контекстных меню аналогично созданию главного меню. Пункты меню добавляются в окне редактора меню. Для того, чтобы при щелчке правой кнопкой мыши на некотором компоненте появлялось контекстное меню, нужно написать имя контекстного меню в свойстве PopupMenu для выбранного компонента (пример 20.6)

Пример 20.2. Меню на форме:

Пример 20.3. Редактор меню:

Если в качестве значения свойства Caption ввести «—», то вместо пункта меню появится разделитель.

Пример 20.4. Контекстное меню редактора:

Пример 20.5. Структура меню:

Пример 20.6. Контекстное меню для компонента Button1:

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

20.3. Создание приложения «Блокнот»

Разместить на форме (пример 20.7) следующие компоненты:

  • рабочая область для текста — Memo1;
  • диалоги для работы с файлами — OpenDialog1, SaveDialog1;
  • диалоги для настройки внешнего вида приложения — FontDialog1, ColorDialog1;
  • главное меню — MainMenu.

Компонент Мемо предназначен для набора и редактирования текста. Для того, чтобы компонент занимал все клиентскую часть формы, необходимо установить у свойства Align значение asClient, (пример 20.8). Добавить вертикальную полосу прокрутки, выбрав значение ssVertical для свойства ScrollBars.

Для того, чтобы очистить рабочую область компонента, необходимо вызвать редактор строк (String List Editor) и удалить текст Memo1. Редактор строк вызывается нажатием кнопки    у свойства компонента Lines (пример 20.9).

Структура меню представлена в примере 20.10. Для написания обработчиков пунктов меню нужно в инспекторе объектов выбрать соответствующий пункт меню, перейти на вкладку Events и выбрать событие OnClick. Поскольку событие OnClick является событием по умолчанию, то двойной клик по пункту в редакторе меню или по соответствующей строке в разделе Structure создаст функцию обработчик.

Обработчики событий для каждого из пунктов меню и создания формы представлены в примере 20.11.

Для сохранения и загрузки файлов опишем глобальную переменную FileName:

String FileName;

Обработчик пункта меню «Новый» (N3) очищает строки компонента Memo от введенного ранее текста.

Обработчики пунктов меню «Открыть» (N4) и «Сохранить» (N5) работают с файлом. Имя файла добавляется к заголовку окна.

Обработчик пункта меню «Выход» (N7) закрывает главную форму проекта.

Обработчик пункта меню «Шрифт» (N8) приписывает шрифту, связанному с компонентом Memo, свойства, выбранные пользователем.

Обработчик пункта меню «Цвет фона» (N9) устанавливает для Memo цвет фона, выбранный пользователем.

Окно работающего приложения показано в примере 20.12.

Для компонента Memo определены следующие действия: Копировать (Ctrl + C), Вырезать (Ctrl + X), Вставить (Ctrl + V), Отменить (Ctrl + Z).

Пример 20.7. Форма на этапе конструирования:

Пример 20.8. Настройка клиентской области:

Пример 20.9. Редактор строк:

Пример 20.10. Структура меню:

Пример 20.11. Обработчики событий:

void __fastcall TForm1::FormCreate
              (TObject *Sender) {

  OpenDialog1->InitialDir =

    ExtractFilePath(ParamStr(0));

  SaveDialog1->InitialDir = 

    OpenDialog1->InitialDir;

}

 

void __fastcall TForm1::N3Click
(TObject *Sender) {

  Memo1->Lines->Clear();

}

 

void __fastcall TForm1::N4Click
(TObject *Sender) {

  if (OpenDialog1->Execute()) {

    FileName = OpenDialog1->FileName;

    Memo1->Lines->LoadFromFile(FileName);

    Form1->Caption = "Блокнот " + FileName;

  }

}

 

void __fastcall TForm1::N5Click
(TObject *Sender) {

  if (SaveDialog1->Execute()) {

    FileName = SaveDialog1->FileName;

    Memo1->Lines->SaveToFile(FileName);

    Form1->Caption = "Блокнот " + FileName;

  }

}

 

void __fastcall TForm1::N7Click
(TObject *Sender)

{

   Form1->Close();

}

 

void __fastcall TForm1::N8Click

(TObject *Sender) {

  if (FontDialog1->Execute())

    Memo1->Font->Assign(FontDialog1->Font);

}

 

void __fastcall TForm1::N9Click

(TObject *Sender) {

  if (ColorDialog1->Execute())

    Memo1->Color = ColorDialog1->Color;

}

 Пример 20.12. Работающее приложение:

20.4. Создание приложения «Графический редактор»

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

Сначала спроектируем форму, разместив на ней следующие компоненты (пример 20.13):

  • область для рисования — Image1;
  • палитру основных 16 цветов — ColorGrid1 (панель компонентов Samples);
  • компоненты, отображающие выбранный цвет для рисования и цвет фона — Panel1, Panel2;
  • компонент выбора цвета — ColorDialog1;
  • компонент для выбора толщины линии — SpinEdit1 (панель компонентов Samples);
  • главное меню — MainMenu1 и компоненты для работы с файлами — OpenPictureDialog1, SavePictureDialog1.

У свойства GridOrdening для компонента ColorGrid1 установить значение go8x2, которое позволит разместить компонент горизонтально.

На этапе конструирования установить значение свойства Color у компонентов Panel1 и Panel2, clBlack и clWhite соответственно.

У свойств Value и MinValue для компонента SpinEdit1 установить значение 1.

Структура меню показана в примере 20.14. Обработчики событий приведены в примере 20.15.

Для того, чтобы программа загружалась с видимой областью для рисования, нужно при создании формы выполнить какое-либо обращение к Image1, например, закрасить белым цветом пиксел с координатами (0; 0).

Для проверки нажатой клавиши мыши опишем обработчик события OnMouseDown для компонента Image1. Параметр Button у этого обработчика может принимать значения mbLeft или mbRight в зависимости от нажатой левой или правой клавиши мыши.

Для отслеживания траектории движения мыши по компоненту Image1 создаем обработчик события OnMouseMove. Параметр Shift у обработчика позволяет определить, какая из клавиш мыши была нажата, а параметры x, y  возвращают координаты точки, в которой произошло нажатие кнопки.

Для перемещения мыши нужно использовать методы Canvas: LineTo(x, y) — перемещение со следом и MoveTo(x, y) — перемещение без следа.

Обработчик события OnChange для компонента ColorGrid1 позволит определить выбранный цвет. Свойства ForegroundColor и BackgroundColor у этого компонента, отвечающие за основной и фоновый цвета, изменяются при нажатии левой и правой кнопок соответственно. Параллельно изменяется цвет панелей.

Толщина линии определяется значением свойства Value для компонента SpinEdit1. Обработчик события — OnChange.

Обработчики событий для компонентов OpenPictureDialog1, SavePictureDialog1, вызываются из соответствующих пунктов меню и аналогичны обработчикам, описанным для программы Блокнот. Для сохранения и загрузки файлов нужно описать глобальную строковую переменную FileName. Приложение может сохранять и загружать файлы формата bmp.

С помощью компонента ColorDialog1 можно выбрать цвет линии или заливки, отсутствующие на панели ColorGrid1. Пункты меню Цвет, позволяют выбрать цвет линии или заливки соответственно. При выборе цвета на панели ColorGrid1 доступны только 16 базовых цветов, при выборе цета из меню — стандартная RGB палитра.

Создание рисунка и загрузка файла в приложение приведены в примере 20.16.

Пример 20.13. Форма на этапе конструирования:

Пример 20.14. Структура меню:

Пример 20.15. Обработчики событий:

void __fastcall TForm1::FormCreate
               (TObject *Sender)

{

  OpenPictureDialog1->InitialDir = 

    ExtractFilePath(ParamStr(0));

  SavePictureDialog1->InitialDir = 

    OpenPictureDialog1->InitialDir;

  Image1->Canvas->Pixels[0][0] = clWhite;

}

 

void __fastcall TForm1::
Image1MouseDown(TObject *Sender, 
TMouseButton Button, TShiftState Shift, 
int X, int Y)

{

  //нажата левая клавиша мыши

  if (Button == mbLeft)

  Image1->Canvas->MoveTo(X,Y);

  //нажата правая клавиша мыши

  if (Button == mbRight)

  Image1->Canvas->FloodFill

    (X, Y, Image1->Canvas->

    Pixels[X][Y],fsSurface);

}

 

void __fastcall TForm1::

Image1MouseMove(TObject *Sender, 
TShiftState Shift, int X, int Y)

{

  //перемещение с нажатой левой

  //кнопкой мыши

  if (Shift.Contains(ssLeft))

  Image1->Canvas->LineTo(X,Y);

}

 

void __fastcall TForm1::

ColorGrid1Change(TObject *Sender)

{

  //выбор основного цвета

  //левой клавишей мыши

  Image1->Canvas->Pen->Color = 

    ColorGrid1->ForegroundColor;

  Panel1->Color = 

    ColorGrid1->ForegroundColor;

  //выбор фонового цвета

  //правой клавишей мыши

  Image1->Canvas->Brush->Color = 

    ColorGrid1->BackgroundColor;

  Panel2->Color = 

    ColorGrid1->BackgroundColor;

}

 

void __fastcall TForm1::

SpinEdit1Change(TObject *Sender)

{

  Image1->Canvas->Pen->Width = 

    SpinEdit1->Value;

}

 

void __fastcall TForm1::N2Click

(TObject *Sender)

{

  Image1->Picture = NULL;

  Image1->Canvas->Pixels[0][0] = clWhite;

  SpinEdit1->Value = 1;

  Panel1->Color = clWhite;

  Panel2->Color = clBlack;

}

 

void __fastcall TForm1::N3Click

(TObject *Sender)

{

  if (OpenPictureDialog1->Execute()) {

  FileName = OpenPictureDialog1->FileName;

  Image1->Picture->LoadFromFile(FileName);

  Form1->Caption = "MyPaint " + FileName;

  }

}

 

void __fastcall TForm1::N4Click

(TObject *Sender)

{

  if (SavePictureDialog1->Execute()) {

  FileName = SavePictureDialog1->FileName;

  Image1->Picture->SaveToFile(FileName);

  Form1->Caption = "MyPaint " + FileName;

  }

}

 

void __fastcall TForm1::N6Click

(TObject *Sender)

{

  Form1->Close();

}

 

void __fastcall TForm1::N8Click

(TObject *Sender)

{

  if (ColorDialog1->Execute()) {

    Panel1->Color = ColorDialog1->Color;

    Image1->Canvas->Pen->Color = 

      ColorDialog1->Color;

  }

}

 

void __fastcall TForm1::N9Click

(TObject *Sender)

{

  if (ColorDialog1->Execute()) {

    Panel2->Color = ColorDialog1->Color;

    Image1->Canvas->Brush->Color = 

      ColorDialog1->Color;

  }

}

Пример 20.16. Работающее приложение:

20.5. Создание приложения «Калькулятор»

Создание калькулятора начнем с конструирования формы. На форме нужно разместить: поле Edit для ввода/вывода чисел, 10 кнопок с цифрами, 4 кнопки с арифметическими действиями, кнопку «=» и кнопку «С» — очистить (пример 20.17).

При нажатии на кнопку с цифрой программа должна дописать эту цифру к числу в поле Edit. При нажатии на кнопку с арифметическим действием нужно запомнить число, которое в данный момент находится в поле Edit и очистить поле для ввода второго числа. Числа будем хранить в двух переменных n1, n2 типа int. Знак операции будем хранить в переменной znak типа char. Переменные описываются как глобальные. При нажатии на кнопку «=» выполняется арифметическое действие и выводится результат.

Для отображения кнопок можно использовать компонент BitBtn, тогда кнопки могут содержать рисунок на поверхности (например, изображения с цифрами). Свойство для размещения рисунка — Glyph.

Установить значение bsDialog для свойства BorderStyle формы. В этом случае граница формы не позволит менять ее размеры.

Коды функций обработчиков приведены в примере 20.18.

Для каждой кнопки на форме нужно создать обработчик события OnClick.

Обработчики событий для всех цифровых кнопок будут идентичны.

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

Основные вычисления происходят в обработчике кнопки «=». Преобразуем в число n2 значение поля Edit и выполняем арифметическую операцию в зависимости от значения переменной znak. После чего обнуляем переменные.

В обработчике кнопки «С» (от англ. clear — очистить) происходит обнуление переменных и очистка поля Edit.

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

Пример 20.17. Форма на этапе конструирования:

Пример 20.18. Обработчики событий:

//описание глобальных переменных

int n1, n2;

char znak;

 

void __fastcall TForm1::

Button10Click(TObject *Sender)

{

  //приписывание цифры к числу

  Edit1->Text = Edit1->Text + '0';

}

 

void __fastcall TForm1::

Button1Click(TObject *Sender)

{

  Edit1->Text = Edit1->Text + '1';

}

Для остальных цифровых кнопок нужно изменить только '1' на соответствующую цифру.

void __fastcall TForm1::

Button12Click(TObject *Sender)

{

  n1 = StrToInt(Edit1->Text);

  //запоминание знака операции

  znak = '+';

  Edit1->Clear();

}

Для остальных кнопок со знаками арифметических действий нужно изменить только '+' на соответствующий знак.

void __fastcall TForm1::

Button16Click(TObject *Sender)

{

  n2 = StrToInt(Edit1->Text);

  switch (znak){

  case '+': {

    Edit1->Text = IntToStr(n1 + n2);

    break;

  }

  case '-': {

    Edit1->Text = IntToStr(n1 - n2);

    break;

  }

  case '*': {

    Edit1->Text = IntToStr(n1 * n2);

    break;

  }

  case '/': {

    Edit1->Text = IntToStr(n1 / n2);

      break;

  }

  }

  n1 = 0;

  n2 = 0;

  znak = ' ';

}

 

void __fastcall TForm1::

Button11Click(TObject *Sender)

{

  Edit1->Clear();

  n1 = 0;

  n2 = 0;

  znak = ' ';

} 

 

Упражнения

1. Дополните проект Блокнот следующими возможностями.

  1. Пункт «меню Сохранить файл» заменить двумя: «Сохранить» и «Сохранить как…»
  2. Добавьте пункт меню «Переносить по словам».
  3. Добавьте возможность управления полосами прокрутки: установить горизонтальную, вертикальную, обе.
  4. *Добавьте следующие диалоги: Параметры страницы, Печать, Поиск, Замена и соответствующие пункты в меню.
  5. Добавьте контекстное меню для управления компонентом Memo. Команды контекстного меню, дублирующие команды основного меню должны вызывать те же обработчики.
  6. Предложите свои возможности.

2. Для проекта «Графический» редактор добавьте следующие возможности:

  1.  Рисовать отрезки, овалы и прямоугольники.
  2.  Выбирать способ заливки: перекрашивание цвета или до контура.
  3.  Предложите свои возможности.

3. Для проекта «Калькулятор» добавьте следующие возможности:

  1.  Возможность работы с вещественными числами.
  2.  Возможность вычислять значения функций: извлечение квадратного корня, возведение в квадрат, тригонометрические функции (для градусов и радиан) и др.
  3. * Возможность перевода чисел в другие системы счисления.
  4.  Предложите свои возможности.

4*. Создайте проект игры на клеточном поле. Возможные варианты:

  1. Сапер.
  2. Пятнашки (Игра 15).
  3. Парные картинки.
  4. Морской бой.
  5. Свой вариант игры.