39037

Разработка многооконных приложений с использованием Borland C++ Builder

Лабораторная работа

Информатика, кибернетика и программирование

Для добавления новой формы в проект приложения необходимо вызвать команду File New Form главного меню или нажать соответствующую кнопку на панели инструментов. Для каждой формы приложения вызывается метод CreteForm создать форму объекта приложения ppliction. Главная форма автоматически отображается на экране при запуске приложения в то время как остальные формы которые иногда называют вторичными будут созданы но останутся невидимыми для пользователя до тех пор пока не будут явно...

Русский

2013-09-30

88.5 KB

118 чел.

Лабораторная работа № 2

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

с использованием Borland C++ Builder 

Цель работы: Научиться разрабатывать многооконные приложения в среде программирования Borland C++ Builder.

Указания к выполнению лабораторной работы

Главным визуальным компонентом, используемым для проектирования пользовательского интерфейса программы, является форма. Форма соответствует окну создаваемого приложения и используется для размещения на нем прочих визуальных компонентов – кнопок, полей ввода, списков и т.п. Обычно пустая форма создается автоматически при создании нового приложения с помощью C++ Builder. Сложные программные продукты могут состоять из большого числа различных форм. Рассмотрим основные аспекты разработки многооконных приложений:

  1.  Создадим новый проект приложения командой File| New| Application из главного меню. Как уже было сказано, в приложение будет автоматически добавлена пустая форма. Ей соответствуют модуль программного кода (по умолчанию unit1.cpp), заголовочный файл (unit1.h) и файл описания формы C++ Builder (unit1.dfm).     
  2.  Для добавления новой формы в проект приложения необходимо вызвать команду File| New| Form главного меню или нажать соответствующую кнопку на панели инструментов. В этом случае проекте появится еще одна пустая форма, для описание которой также состоит из трех файлов, имена по умолчанию для которых, соотвтетственно, unit2.cpp, unit2.h и unit2.dfm.
  3.  Вызовом команды Project| View Source из главного меню можно открыть в редакторе кода основной файл проекта (по умолчанию он называется Project1.cpp). После выполнения описанных выше действий в нем автоматически генерируются следующие строки (см. функцию WinMain):

       Application->Initialize();

      Application->CreateForm(__classid(TForm1), &Form1);

Application->CreateForm(__classid(TForm2), &Form2);

      Application->Run();

За оператором инициализации объекта приложения (первая строка) здесь располагается список операторов, отвечающих за инициализацию форм приложения. Для каждой формы приложения вызывается метод CreateForm («создать форму») объекта приложения Application.  В рассматриваемом случае приложение состоит из 2 форм. Форма, которая создается самой первой (в данном случае – это Form1), считается главной формой приложения. Главная форма автоматически отображается на экране при запуске приложения, в то время как остальные формы (которые иногда называют вторичными) будут созданы, но останутся невидимыми для пользователя до тех пор, пока не будут явно отображены на экране (рекомендуется убедиться в этом, запустив приложение). Закрытие главной формы означает завершение всей работы приложения. Закрытие остальных форм может привести к завершению работы приложения только, если об этом специально позаботится программист.

  1.  Главную форму приложения можно изменить, соответствующим образом отредактировав вышеописанный список инициализируемых форм приложения. Кроме того, это можно сделать из окна свойств проекта, который вызывается сочетанием клавиш Shift+Ctrl+F11 или командой Project| Options главного меню. На вкладке Forms появившегося окна можно обнаружить свойство Main form, которому можно назначить любую форму приложения. Укажем, например, для нашего приложения форму Form2 в качестве главной. Изменение и подтверждение указанного свойства приведет к автоматическому помещению оператора создания соответствующей формы на самый верх списка инициализации форм приложения (см. файл Project.cpp в редакторе кода). После запуска приложения мы увидим, что теперь стала видимой форма Form2, а ее закрытие завершает работу приложения.
  2.  Попробуем теперь вызвать из главной формы приложения (From2) вторичную форму Form1. Для этого поместим на форму Form2 кнопку, озаглавив ее “Form1”. В качестве реакции на  событие нажатия этой кнопки напишем следующее:

Form1->Show();

В данном случае предполагается отобразить форму Form1 на экране, за что отвечает метод Show() компонента формы. Попробуем откомпилировать и запустить приложение. Процесс компиляции проекта будет прерван с ошибкой “Undefined symbolForm1’”. Причина этого заключается в том, что описание класса формы Form1 находится в заголовочном файле unit1.h. Поэтому прежде чем обращаться к форме Form1 из модуля формы Form2, необходимо подключить к нему заголовочный файл unit1.h. Это можно сделать вручную, добавив в include-секцию модуля unit2.cpp соответствующую запись (includeunit1.h”), либо открыть модуль unit2.cpp в редакторе кода, а затем вызвать команду главного меню File| Include Unit Hdr и выбрать нужный файл из предлагаемого списка заголовочных файлов проекта. И в том, и в другом случае include-секция модуля главной формы будет содержать заголовочный файл формы Form1, поэтому повторная компиляция проекта будет успешной. Нажатие кнопки “Form1” в запущенном приложении приведет к отображению на экране формы с одноименным названием. После вызова формы Form1 пользователь может свободно переключаться между обеими формами. Форму Form1 можно закрывать и снова вызывать повторными нажатиями кнопки на главной форме. Из этого факта можно сделать вывод, что закрытие неглавной формы по умолчанию не приводит к уничтожению объекта, а всего лишь делает эту форму невидимой. Таким образом, по умолчанию объект формы Form1 существует все время работы приложения, до тех пор, пока не будет закрыта форма Form2.

  1.  Результат закрытия любой неглавной формы можно изменить. Завершим запущенное приложение, откроем форму Form1 (для переключения между формами проекта целесообразно использовать список форм, который вызывается сочетанием клавиш Shift+F12 или командой View| Forms из главного меню) и в качестве реакции на событие OnClose запишем следующее:

Action = caFree;

Если пользователь закрывает форму, то за действия объекта формы в этот момент отвечает параметр Action, который специально объявлен  в обработчике событий OnClose. Он относится к перечислимому типу TCloseAction и может принимать одно из следующих значений:

  •  caNone – при закрытии формы никакие действия не производятся, т.е. форма не закрывается.
  •  caHide – при закрытии формы ее объект не уничтожается, но форма становится невидимой для пользователя.
  •  caFree – при закрытии формы ее объект уничтожается, занимаемая им память высвобождается, так что больше этой формы в запущенном приложении не существует.
  •  caMinimize – закрытие формы означает ее минимизацию на экране. Форма остается видимой, объект не уничтожается.

По умолчанию параметр Aсtion принимает значение caHide. Попробуем еще раз запустить приложение со значением параметра Action, измененным на caFree. При первом нажатии кнопки “Form1” форма по-прежнему вызывается и отображается на экране. Однако при ее закрытии объект формы будет уничтожен, следовательно, после ее закрытия обращаться к ней больше нельзя. Поэтому повторное нажатие кнопки на главной форме приводит к возникновению ошибки некорректного доступа к памяти.

  1.  Среди множества окон, из которых может быть построено приложение, принято выделять класс диалоговых окон. Диалоговые окна имеют следующие характерные черты, отличающие их от обычных окон:
  •  Фиксированный размер;
  •  Фиксированное размещение относительно главного окна;
  •  Наличие кнопки OK и других стандартных кнопок («Отмена», «Да», «Нет» и т.п.).
  •  Работа приложения приостанавливается (т.е. все прочие окна приложения остаются недоступными) до завершения работы с диалоговым окном

В C++ Builder диалоговое окно является разновидностью обычной формы. Добавим в рассматриваемый проект еще одну форму Form3. С помощью инспектора объектов необходимо изменить свойство  BorderStyle у добавленной формы. Указанное свойство характеризует внешний вид и поведение границы формы. По умолчанию значение этого свойства установлено в bsSizeable, что означает, что пользователь может изменять размеры формы стандартным образом (например, потянув мышью за ее правый нижний угол). Для диалогового окна свойству BorderStyle следует присвоить значение bsDialog. В этом случае при запуске приложения форма будет иметь фиксированный размер, определенный при разработке приложения. Кроме того, как и полагается для диалоговых окон, кнопки максимизации и минимизации окна формы исчезнут из системного меню.

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

  1.   Поместим на форму Form2 еще одну кнопку с заголовком “Dialog”. В качестве реакции на нажатие кнопки запишем:

Form3->ShowModal();

В отличие от формы Form1 форма Form3 будет отображаться на экране в модальном режиме. Это значит, что после ее появления на экране все остальные формы приложения  будут оставаться недоступными до тех пор, пока форма не будет закрыта. Рекомендуется убедиться в этом, запустив рассматриваемое приложение. Перед компиляцией проекта необходимо добавить в include-секцию модуля формы Form2 заголовочный файл формы Form3 (unit3.h).

  1.  Из неглавных форм можно обращаться к объекту главной формы (или других неглавных форм) точно так же, как это было описано выше. Добавим, например, в include-секцию модуля формы Form1 заголовочный файл главной формы unit2.h. Теперь можно описать обработчик события отображения формы Form1 на экране следующим образом:

void __fastcall TForm1::FormShow(TObject *Sender)

{

Form2->Button1->Enabled = false;

}

При появлении на экране формы Form1 будет выполнена вышеприведенная процедура, которая сделает кнопку “Form1” на главной форме недоступной для пользователя. Таким образом, повторное нажатие на эту кнопку станет невозможным, следовательно, ошибка некорректного доступа к памяти появляться не будет.

  1.  В заключение отметим, что при создании многооконных приложений нередко бывает целесообразным использовать готовые шаблоны форм, которые хранятся в хранилище объектов Borland C++ Builder. Чтобы добавить в проект форму, основанную на каком-либо шаблоне, необходимо вызвать из главного меню команду File| New| Other. Появится окно хранилища объектов, в котором различные шаблоны форм предлагаются на вкладках Forms и Dialogs. Формы, созданные по шаблонам, в отличие от обычных форм, не являются пустыми и предлагают разработчику реализацию некоторого интерфейса и/или каких-либо функций. Программист C++ Builder имеет возможность добавлять в хранилище объектов и собственные шаблоны форм.

Мультидокументный интерфейс

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

Однодокументный интерфейс (SDI-интерфейс, Single Document Interface) – это метод организации графического пользовательского интерфейса в виде набора самостоятельных окон, каждое из которых имеет собственный дескриптор операционной системы (то есть ОС рассматривает каждое из окон как самостоятельный объект). Все окна располагаются прямо на рабочем столе, при максимизации могут разворачиваться на весь рабочий стол, а при минимизации – сворачиваться на панель задач или в нижнюю часть рабочего стола.

Другим способом организации графического пользовательского интерфейса является мультидокументный интерфейс (MDI-интерфейс, Multiple Document Interface). История его создания началась в конце 80-ых годов прошлого века, когда фирма IBM выпустила первую спецификацию соответствующего интерфейса. Его основные черты с тех пор практически не изменились:

  •  Приложение состоит из основного окна и ряда дочерних окон. Все дочерние окна находятся в границах родительского окна.
  •  Приложение и каждое дочернее окно допускает максимизацию и минимизацию. Максимизированные и минимизированные дочерние окна остаются в рамках основного окна.
  •  Основное окно имеет меню, расположенное в верхней части. Список всех дочерних окон содержится в выпадающем подменю, имеющем название Window (Окно).
  •  Приложение закрывается комбинацией Alt+F4, а дочернее окно – Ctrl+F4. Сочетание клавиш Ctrl+F6 используется для переключения между дочерними документами.

Среда разработки приложений Borland C++ Builder позволяет довольно просто разрабатывать приложения с мультидокументным интерфейсом. Чтобы создать MDI-приложение обычно требуется выполнение следующих шагов:

  1.  В только что созданном приложении установить значение свойства FormStyle равным fsMDIForm (по умолчанию его значение равно fsNormal). Тогда главная форма приложения станет основным окном многодокументного интерфейса.
  2.  Для каждой формы, которая проектируется как дочерняя, необходимо устанавливать значение свойства FormStyle равным fsMDIChild.
  3.  Особенностью дочерних окон приложения с MDI является невозможность сделать их невидимыми. Поэтому все дочерние окна, которые создаются на этапе инициализации программы, появятся в рамках основного окна сразу же после запуска приложения. Это не всегда желательно. Например, дочернее окно для отображения текстового документа имеет смысл показывать только после того, как пользователь решил открыть такой документ и выбрал соответствующий файл. По этой причине дочерние формы обычно убирают из списка инициализации форм основного файла проекта (см. п.3 в указаниях к работе). Их инициализация в этом случае обычно проводится непосредственно перед отображением дочерней формы на экране. Если пользователь из предыдущего примера решил открыть текстовый документ, то реакция на это событие будет включать в себя следующие строки программного кода:

{

...

Определяем, какой файл хочет открыть пользователь

...

}

// Создаем дочернюю форму. Параметр конструктора формы – владелец

// создаваемого объекта, в данном случае – это сама основная форма

TForm *w = new TForm2(this);

{

...

Работаем с указателем на объект формы:

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

...

}

// отображаем форму на экране

w->Show();

 

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

  1.  Ранее уже говорилось, что стандартным способом закрытия SDI-формы является ее исчезновение с экрана. При этом объект формы продолжает существовать. Поскольку дочерние MDI-формы не могут быть невидимыми, то попытка закрыть дочернюю форму приложения приведет к ее минимизации в рамках основного окна. Чтобы убрать форму с экрана и освободить занимаемую ее объектом память, необходимо для этой формы написать обработчик события OnClose, в котором значение параметра Action устанавливается равным caFree. Таким образом, объект формы будет создаваться в тот момент, когда соответствующее дочернее окно потребовалось пользователю и уничтожаться сразу после того, как это окно было закрыто.
  2.  Для организации главного меню в основной форме приложения следует использовать визуальный компонент MainMenu. Каждый пункт/подпункт главного меню представляет собой объект класса TMenuItem. Если свойство WindowMenu основной формы MDI-приложения будет содержать указатель на объект TMenuItem, соответствующий некоторому пункту главного меню, то при запуске приложения в этом пункте меню будет автоматически формироваться список открытых дочерних окон.
  3.  Кроме того, для основной формы приложения можно вызывать различные методы упорядочения дочерних форм и управления ими:
    •  Метод Cascade() – Расположение дочерних форм каскадом;
    •  Метод Tile() – Расположение окон «черепицей» («мозаикой»), для задания способа упорядочения (по вертикали или по горизонтали) используется свойство формы TileMode;
    •  Метод ArrangeIcons() – Упорядочение иконок свернутых дочерних форм;
    •  Метод Next() – Активируется следующее дочернее окно;
    •  Метод Previous() – Активируется предыдущее дочерние окно.

Методы Next() и Previous() предполагают работу со списком дочерних форм. Этот список изменяется в процессе работы приложения – каждая вновь созданная дочерняя форма попадает в конец списка. У программиста есть возможность работать со списком дочерних форм непосредственно. Для этого используются свойства основной формы MDIChildCount и MDIChildren. Свойство MDIChildren – представляет собой список указателей на объекты открытых дочерних форм, а MDIChildCount определяет их количество.

  1.  Реализацию многих элементов MDI-интерфейса взяли на себя разработчики среды C++ Builder. В частности, программисту не надо беспокоиться за стандартные назначения определенных комбинаций клавиш – эти требования будут выполняться для его приложения автоматически.

На сегодняшний день нет единого мнения относительно того, какой из двух подходов к организации пользовательского интерфейса –  SDI или MDI – лучше. Долгое время считалось, что SDI можно использовать только в небольших программах, а для приложений с большим количеством окон необходимо применение MDI. В последнее время, наоборот, стали говорить о том, что SDI является более гибким подходом к проектированию пользовательского интерфейса, так как в мультидокументных приложениях отсутствует возможность быстрого переключения между дочерними окнами. Некоторые специалисты даже рекомендуют разработчикам отказываться от проектирования и реализации MDI-приложений, несмотря на то, что разработка сложных многооконных SDI-приложений обычно требует больших временных затрат (по сравнению с аналогичным MDI-приложением). В этой связи интересным представляется подход разработчиков продукта Microsoft Office. Первые версии программных продуктов этого пакета имели SDI-интерфейс, потом использовался MDI-интерфейс, а начиная с версии Microsoft Office 2000 – снова SDI. Однако многие элементы многодокументного интерфейса (привычные сочетания клавиш, пункт Window (Окно) и др.) при этом были сохранены. Думается, что такой подход, основанный на грамотном сочетании двух методов организации пользовательского интерфейса, является оправданным.

Задания к лабораторной работе

  1.  Изучить аспекты создания многооконных приложений. Выполнить действия, описанные в пунктах 1-10 указаний к лабораторной работе. Отразить ход выполнения в отчете.
  2.  Выяснить назначение, а также основные свойства, методы и события для следующих компонентов:
    •  MainMenu (вкладка Standard);
    •  Image (вкладка Additional) – обратить особое внимание на свойства Align и Stretch;
    •  OpenDialog, SaveDialog, OpenPictureDialog, SavePictureDialog (вкладка Dialogs) – обратить особое внимание на свойство Filter и метод Execute.

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

  1.  Спроектировать и реализовать MDI-приложение «Обозреватель картинок». Основная функция: открывать и просматривать графические файлы. Предусмотреть возможности:
  •  сохранения графического файла с другими именем;
  •  переключения между открытыми картинками с помощью главного меню;
  •  включения/выключения режима изменения масштаба и пропорций картинки под размеры окна;
  •  упорядочения открытых дочерних окон;
  •  вывода информации о количестве открытых в данный момент файлов.

Реализовать вывод информации о программе в специальном диалоговом окне.

  1.  Кратко отразить в отчете к лабораторной работе ход выполнения задания № 3 и результаты тестирования приложения.
  2.  Сформулировать выводы по выполненной работе.

Контрольные вопросы

  1.  Понятие формы в C++ Builder. Свойства Owner и Parent.
  2.  Главная форма приложения в C++ Builder.
  3.  Основные черты диалоговых окон. Модальные и немодальные окна.
  4.  Свойства формы BorderStyle и Position.
  5.  Смысл и назначение указателя this.
  6.  Понятие однодокументного и мультидокументного интерфейса.
  7.  Основные черты мультидокументного интерфейса.
  8.  Свойства формы FormStyle и WindowMenu.
  9.  Методы упорядочения и управления дочерними формами в MDI-приложениях.
  10.  SDI или MDI: какой подход, по вашему мнению, лучше?


 

А также другие работы, которые могут Вас заинтересовать

53959. Легенди та перекази рідного краю 72.5 KB
  Обладнання: книги Хуст над Тисою легенди рідного краю Замки Закарпаття довідник для туристів Хуст альбом Наше місто альбом Легенди нашого краю малюнки учнів. Повідомлення теми та мети уроку Сьогодні ми проводимо виховну годину на тему Легенди й перекази рідного краю на якій ми краще дізнаємось про минуле рідного краю зокрема Хустський замок від чого пішла назва нашого міста річок мікрорайонів; будемо розвивати своє зв’язне мовлення; вчитися шанувати і берегти історичні пам’ятки природу. Друга сторінка нашого журналу...
53960. Легкая атлетика в 4-м классе 100 KB
  В работе представлен конспект для проведения урока по физкультуре в системе государственных средних общеобразовательных школ. Тема урока: Легкая атлетика в 4м классе. Конспект урока по физической культуре.
53961. Geburtstag und Geschenke 1.59 MB
  Sch?n ist es im Herbstwald. Die Birken bekommen goldene, rote, dunkelbraune Bl?tter. Der Espenwald steht wie im Flammen da, und nur die Tannen bleiben immer dunkelgr?n. Die Pappeln haben braune Kleidung an. Ab und zu fliegt ein Vogel vorbei. Meisen, Spechte
53962. Стилістичні шари лексики. Практичне заняття клубу любителів української словесності 85.5 KB
  Мета заняття: 1 навчальна: закріпити й розширити знання учнів із зазначеної теми; 2 розвивальна: розвивати вміння й навички пов’язані зі стилістичною диференціацією лексики української мови; сприяти розвитку вмінь аналізувати порівнювати мовні явища конструювати мовні одиниці; сприяти розвитку логічного мислення; 3 виховна: виховувати повагу до слова естетичні смаки учнів. Большой энциклопедический...
53963. Удосконалення лексичних вмінь 40 KB
  З перших днів навчання дитини у школі повсякденно працюємо над словом: пояснюємо значення добираємо синонімічні пари вводимо слова в речення виявляємо синоніми в ілюстративному матеріалі й текстах. Виробляємо в учнів уміння добирати такі слова якими можна найточніше образно виразити свою думку. Визначення лексичного значення слова формування поняття про пряме та переносне значення слова. Ворота Додати в реченні потрібні слова.
53965. Психологический анализ урока в деятельности педагога 108.5 KB
  Анализ урока является одним из важных способов осознания объективации этой деятельности ее участниками и прежде всего учителем. Анализу урока посвящено достаточно много собственно психологических педагогических и методических работ Т. Исследователи подчеркивают многообъектность анализа урока важность учета учителем преподавателем всех сторон педагогического взаимодействия особенностей его субъектов и их деятельности.
53966. Понятие культуры. Культура как объект научного исследования 28.5 KB
  Культура – это особый духовный опыт человеческих сообществ, накапливаемый и передаваемый от поколения к поколению, содержанием которого является ценностные смыслы вещей, форм
53967. Психология как наука и сиситема житейских знаний 55.5 KB
  Психология состоит из многочисленных школ по разному трактующих психологические явления. Психология одновременно является наукой гуманитарной и естественной. Предмет Психология менялся в ходе ее формирования как отдельной науки: 1. Психология как наука и сиситема житейских знаний Отличие житейских психологических знаний и научных: 1.