Главная

Популярная публикация

Научная публикация

Случайная публикация

Обратная связь

ТОР 5 статей:

Методические подходы к анализу финансового состояния предприятия

Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века

Ценовые и неценовые факторы

Характеристика шлифовальных кругов и ее маркировка

Служебные части речи. Предлог. Союз. Частицы

КАТЕГОРИИ:






Классы ObjectWindows




OWL содержит множество классов, способствующих более быстрому и простому написанию прикладных программ. OWL-классы представляют набор объектов, из которых создается Windows-приложение таких объек­тов, как окна, диалоговые окна, меню, элементы управления и другие, включая некоторые специальные объекты, такие как строки состояния и управления.

В частности, ObjectWindows 2.0 поддерживает следующие основные категории классов:

· Приложения (Applications)

· Окна (Windows)

· Меню (Menus)

· Окна диалога (Dialog boxes)

· Элементы управления (Controls)

· Графика (Graphics)

· Печать (Printing)

· Контроль ввода (Validators)

· Просмотр документов (Document and views)

· Буфер обмена (Clipboard)

 

Класс TApplication

Любая программа, написанная с использованием ObjectWindows, начинает свое существование, как объект приложения. Этот объект порождается классом TApplication библиотеки OWL и обеспечивает инициализацию, выполнение и завершение вашей Windows-программы. Более конкретно: TApplication регистрирует, создает и отображает основное окно приложения; поддерживает работу цикла обработки сообщений (таким образом, что прикладная программа может взаимодействовать как с пользователем, так и с Windows), и закрывает его, когда работа за­кончена.

Класс TApplication обеспечивает полноценную работающую Windows-программу, выполняющую, правда, не более сложное действие, чем вывод окна на экран. TApplication поддерживает некоторые дополнительные функции - такие, как обеспечение доступа к командной строке приложе­ния, позволяя подключать либо библиотеку настраиваемых элементов управления Borland, либо библиотеку 3-мерных элементов управления Microsoft, а также определить, когда Windows простаивает.

 

Оконные классы

Когда создаётся базовое OWL-приложение, TApplication автома­тически создает главное окно. Это окно полностью функционирует, то есть можно изменить его размеры, переместить, максимизировать, ми­нимизировать и закрыть.

Оконные OWL-классы, позволяют на­растить функциональные возможности вашего окна по сравнению со стандартными. Чтобы облегчить эту задачу, OWL вводит несколько раз­личных видов окон, а именно:

· Дочерние окна общего вида

· Родительские окна

· Декорированные обрамляющие окна

· MDI-окна

Каждый из этих типов обсуждается в следующих разделах.

Дочерние окна общего вида

Дочернее окно общего вида представлено в OWL 2.0 классом TWindow. Это основное окно, которое обеспечивает поддержку меню, линейки про­крутки, элементы управления, оконную графику, обмен данными, стан­дартную обработку сообщений и многое другое.

Хотя класс TWindow можно использовать для создания основного ок­на, его все же лучше попридержать для других целей. Основное окно приложения должно быть окном класса TFrameWindow, который описан в следующем разделе.

Родительские окна

Родительские окна, представленные классом TFrameWindow, поддержи­вают все функции класса TWindow и, вдобавок, работу с клавиатурой и окнами пользователя. Родительские окна являются также базовым классом для декорированных MDI-окон. Большинство функций TFrameWindow наследуется из базового класса TWindow, представляюще­го общие окна в ObjectWindows 1.0 и ObjectWindows 2.0, главное окно представлено классом TFrameWindow. Фактически, окно, создаваемое объектом TApplication по умолчанию, является обрамляющим.

 

Декорированные обрамляющие окна

Декорированные обрамляющие окна, инкапсулированные в классе TDecoratedFrame и производные от обычных обрамляющих окон и макет­ных (layout) окон, позволяют вставить в приложение такие элементы оформления, как панели инструментов, строки подсказки и состояния, инструментарии, представленные соответственно классами TControlBar, TToolBox, TMessageBar и TStatusBar.

Когда эти специальные элементы вставляются в декорированное обрамляющее окно, оно автоматически размещает их и поддерживает в нужном месте, если пользователь перемещает окно или изменяет его размеры. Кроме того, с помощью функции оформленного родительского окна Insert () можно вставлять в окно такие объекты, как панель инструментов и строка состояния. Существуют также функции для по­каза и удаления элементов оформления и отображения текста подсказ­ки для выделенных элементов меню. (Текст подсказки описывает дейст­вие данной команды меню и появляется, когда пользователь устанавливает курсор на соответствующий элемент меню.)

MDI-окна

Для обеспечения многодокументного интерфейса (MDI) ObjectWindows поддерживает несколько оконных классов, служащих специально для создания MDI-приложений. Родительское MDI-okho, включенное в класс TMDIFrame, работает как основное окно MDI-приложения. Во время работы такой программы это окно содержит, как минимум, невидимое окно пользователя и, возможно, несколько до­черних окон. Родительское окно обрабатывает основное меню прило­жения, включающее специальное меню Windows. Это меню позволя­ет выбирать окна и размещать их по принципу cascade, tile, либо произвольно.

MDI-окно пользователя, представленное классом TMDIClient, поддер­живает большинство функций MDI-приложений. Вообще говоря, сооб­щения, посылаемые MDI-приложению, направляются для обработки в
окно пользователя. Окно пользователя автоматически обрабатывает четыре основные команды оконного меню MDI-программы, позволяя без
особых усилий добавить новые окна по способу cascade или tile, а также
закрывать их. МТI-окно-клиент может также автоматически создавать
дочерние MDI-окна. '

Все дочерние окна в MDI-приложений должны быть дочерними MDI-окнами, поэтому для окон такого типа ObjectWindows, само собой, под­держивает специальный класс TMDIChild. Дочерние MDI-окна работают почти так же, как и родительские окна на главной панели Windows, только здесь «рабочий стол» (desktop) определяется окном-клиентом MDI-приложения. Пользователь может свернуть дочерние MDI-окна до иконки или максимизировать их, заполняя все окно-клиент.

 

Меню

Одной из отличительных черт Windows-программы является строка меню. Почти все приложения Windows используют меню, что подразу­мевает (или должно подразумевать) определенные правила их построе­ния. Следуя этим правилам, пользователь отыскивает известные ему ко­манды в ожидаемом месте независимо от того, какое приложение активно в данный момент. Для обработки простого меню отлично рабо­тают обычные методы, для более гибкой работы с меню используются OWL-классы TMenu, TSystemMenu и TPopupMenu.

Класс TMenu, служащий для работы с основным меню, содержит такие функции, как добавление в меню новых элементов, изменение их на­именования, разрешение и блокирование элементов меню, отображение и удаление маркеров и даже вставка в меню растровых изображений. Кроме того, вспомогательные функции класса выдают такую информа­цию, как число элементов меню, размер растрового изображения марке­ра, идентификаторы наименований (ID), состояние меню и т.п.

Класс TSystemMenu предлагает дополнительные функции управления системным меню. Этот класс позволяет заменить системное меню окна на свое собственное. Наконец, класс TPopupMenu позволяет создавать в любом месте окна всплывающее меню.

Окна диалога

Аналогично тому, как большинство Windows-приложений использует меню для получения от пользователя команд, окна диалога используются для ввода данных. Для окон диалога в OWL существует класс TDialog, по­добный классу TMenu. Класс TDialog выполняет всю работу, связанную с созданием, функционированием и закрытием окна диалога, включая встроенную обработку наиболее часто используемых типов кнопок и ме­ханизмы пересылки данных в и из окна диалога. Кроме того, окно может быть модальным и немодальным, может содержать множество элементов управления и может даже изображаться как 3-мерная пространственная форма с помощью библиотек DLL фирм Borland и Microsoft.

OWL также инкапсулирует в классы стандартные диалоговые окна
Windows и другие «сборные» диалоговые окна. Эти классы, включая
TInputDialog, TPrinterAbortDlg, TChooseColorDialog,

TFindReplaceDialog, TChooseFonDialog, TPrintDialog и

TOpenSaveDialog позволяют пользователю ввести одиночную строку тек­ста, выбрать имена файлов, найти текстовую строку, настроить принтер, подобрать цвета и шрифты.

 

 

Элементы управления

Приложения Windows загружаются вместе со специальными элемен­тами управления, такими, как кнопки, окна списков, линейки прокрут­ки и окна редактирования.

Поскольку в приложениях интенсивно используются элементы управления Windows, они реализованы в OWL в качестве классов. На­пример, элемент «окно списка», включенный в класс TListBox, содер­жит функции-члены для вставки и удаления строк списка, очистки списка, поиска в нем заданной строки, определения числа выбранных элементов списка, восстановления выбранных строк, пометки строк и другие. Класс TScrollBar, реализующий линейки прокрутки, позволя­ет, в частности, получить и задать позицию бегунка, задать диапазон прокрутки.

Кроме перечисленных выше классов, в OWL существуют классы для кно-пк (TButton), групповых окон (TGroupBox), комбинированных окон (TCornboBox), элементов управления редактированием (TEdit), окон переключателей (TCheckBox), радио-кнопок (TRadioButton) и управления статическим текстом (TStatic). OWL поддерживает также применяемые в приложениях классы управления настройкой. К примеру, элемент, представ­ленный классом TGauge, отображает вертикальную и горизонтальную шка­лы, показывающие, насколько процесс близок к завершению. Вертикальная и горизонтальная шкалы, включенные в классы THSlider и TVSlider, позво­ляют выбрать величину из заданного диапазона.

 

Графика

Поскольку Windows представляет собой графический интерфейс пользо­вателя (GUI), приложения в большей степени зависят от предоставляемых Windows графических средств. Эти средства и составляют графический ап­паратный интерфейс (GDI) Windows. С целью сделать функции GDI более доступными, в ObjectWindows реализованы десять специальных классов. Сюда входят классы контекстов устройств (TDS), кисти (ТРеn), пиктограм­мы (иконки) (ТТсоn), растровые изображения (TBitmap), курсоры (TCursor), шрифты (TFont), палитры (TPalette), аппаратно-независимые растровые изображения (TDib) и области (TRegion).

Класс TDC является основным классом для других специальных клас­сов контекстов устройств (DC). Этот класс содержит большинство GDI-функций Windows — таких, как рисование форм, отображение текста, кнопок и растровых изображений, задание режима рисования, выбор и восстановление объектов GDI, задание цвета и другие. Специальные классы DC включают контексты окна (TWindowDC), закраски (TPainfcDC), метафайла (TMetafileDC), памяти (TMemoryDC) и принтера (TPrintDC). Каждый класс DC включает множество функций, осуществдяющих вызов стандартных, относящихся к данному контексту устрой­ства (DC) функций Windows. Например, класс TPrintDC поддерживает функции запуска и остановки принтера, инициализации и завершения страницы, задания числа копий, снятия документа и другие.

 

В Windows-приложении вывод на экран гораздо более сложен, чем в програм­мах, работающих под DOS. Для вывода на экран в Windows-приложении необ­ходимо вначале получить контекст устройства (DC) для окна, в которое выво­дится информация. DC — это структура данных, содержащая разного рода графические установки для данного устройства, включая перо, кисть, типы ли­ний, а также информация о цвете и форме отображения. Хотя чаще всего уст­ройством является окно на экране, контекст требуется и для таких устройств, как принтер.

Печать

Аппаратная независимость Windows, поддерживаемая большим ко­личеством возможных драйверов, приводит к тому, что вывод на прин­тер в Windows — задача непростая. Но теперь, благодаря новым клас­сам OWL, вы можете напечатать документ любого типа, приложив при этом минимум усилий. В частности, для управления заданиями для принтера OWL поддерживает два класса: класс TPrinter, включающий функции принтера и поддержку драйверов, и класс TPrintout, от­вечающий за подготовку документа к печати. Оба эти класса вместе служат для получения твердых копий с помощью установленного в данный момент принтера.

Когда вы создаете объект, относящийся к классу TPrinter, приложе­ние автоматически связывается с принтером пользователя, заданным по умолчанию так, как указано в файле WIN.INI. Объект TPrintout, будучи весьма мощным средством, позволяет также легко напечатать простой, в одну страницу, документ с помощью одной-единственной функции, как и осуществить вывод в область окна с помощью оконной функции закрас­ки. Для более сложных многостраничных документов TPrintout помога­ет произвести разбивку на страницы, компоновку, управлять размером страниц и взаимодействовать с пользователем через специальное окно диалога.

 

Компоновка — это стандартный метод печати документов в Windows. Он за­ключается в разбиении документа на серию горизонтальных прямоугольников, называемых группами (bands).

В OWL включен также класс TPreviewPage, позволяющий с мини­мальными усилиями реализовать функцию предварительного просмот­ра. С помощью этой функции пользователь может отобразить на экране окно с данными, которые он собирается напечатать.

 

 

Контроль ввода

Другой громоздкой функцией при написании Windows-программ являет­ся контроль содержимого окон диалога после ввода данных пользователем. До появления ObjectWindows 2.0 вам приходилось самому писать функции контроля данных, которые вызывались до закрытия окна. Теперь OWL про­делывает все это с помощью объектов. Пять специальных классов, осущест­вляющих контроль, а именно: TFilterValidator, TRangeValidator, TLookupValidator, TStringLookupValidator и TPXPictureValidator — по­зволяют проверять вводимые данные на допустимые символы, диапазон, идентифицировать принадлежность элемента к таблице допустимых ответов и применять шаблон при вводе.

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

 

Просмотр документов

Большинство Windows-приложений имеет дело с обработкой документов того или иного вида. Текстовые процессоры работают с текстовыми файла­ми, графические редакторы — с изображениями, генераторы звуковых эф­фектов — со звуковыми файлами. В некоторых случаях приложение долж­но уметь обработать документ несколькими способами. Например,

редактор файлов может обрабатывать как текстовые ASCII-файлы, так и двоичные данные, выводимые на экран в двоичном или шестнадцатирич­ном формате. Чтобы помочь вести обработку документов, OWL предлагает модель Doc/View, включающую объект документа, объект просмотра и об­работчик документа.

OWL-объект документа, представленный классом TDocument, может со­держать данные любого типа. Этот класс поддерживает функции обработ­ки документа и просмотра, связанного с этим документом. Например, вы можете открыть и закрыть документ, получить или задать соответствую­щий путь к директорию, получить или задать заголовок документа, про­верить, вносились ли в документ изменения, и сообщить объекту просмот­ра об этих изменениях.

Объект просмотра, относящийся к классу TView, представляет собой функциональную црослойку между документом и интерфейсной частью, используемой для его обработки (например, окном или диалоговым ок­ном). Просмотр позволяет отображать данные различными способами и дает пользователю возможность их обрабатывать. Чтобы извлечь из просмотра дополнительную пользу, вы должны переписать ряд вирту­альных функций класса, заставляя их работать так, как требуется для данного типа просмотра. Один документ может быть связан с несколь­кими различными объектами просмотра.

Буфер обмена

Одним из многих преимуществ Windows является возможность обме­на данными между приложениями. Наиболее распространенным меха­низмом такой передачи является буфер обмена (Clipboard). Данные мо­гут быть вырезаны или скопированы в буфер обмена одного приложения, а затем переданы оттуда в документ другого приложения.

Поскольку буфер обмена регулярно используется в Windows-програм­мах, в OWL существует класс TClipboard, вобравший в себя множество функций Windows для работы с буфером обмена. Используя TClipboard, вы можете открыть и закрыть буфер, очистить его, проверить формат дан­ных, хранящихся в нем, копировать в него и извлекать из него данные, а также выполнить любую из других 14 функций работы с буфером обмена.

OWL включает также специальный класс TClipboardViewer, который автоматически добавляется и удаляется из цепочки Windows, осуществ­ляющей просмотр буфера обмена. Этот класс поддерживает также отве­ты на сообщения, генерируемые Windows^для просмотра буфера обмена.

Создание объекта приложения

Пример 1. TINIEST.CPP — простейшее OWL-приложение.

 

#include <owl\applicat.h>

int OwlMain(int, char*[])

{

TApplication App('Tinest App");

return app.Run();

}

В примере 1 приведено самое короткое возможное OWL-приложение. Как видно, оно состоит всего из семи строк, включая пустую строку, от­крывающую и закрывающую фигурные скобки. При более тщательном подходе к программе можно уложиться и в меньшее число строк. Когда программа будет откомпилирована и запущена, на экране появится окно, показанное на рис. 1. Это полноценное окно с системным меню и всеми элементами управления, необходимыми для перемещения окна, из­менения его размеров, минимизации и максимизации.


 

Рис. 1. Простейшее приложение

Первая строка программы 1 включает в OWL-приложение заголовочный файл для объекта приложения OWL. Для большинства OWL-объектов заголовочный файл содержится в каталоге BC4\INCLUDE\OWL. Чтобы получить доступ к OWL-объекту, необходимо включить его заголовочный файл в про­грамму. В примере 1 используется только один OWL-объект — объ­ект приложения, поэтому в начале примера подключается только один заголовочный файл.

Следующая строка (после пустой) является первой строкой функции OwlMain(), с которой начинается работа любой OWL-программы. Поми­мо того, что отпадает нужда в сложной функции WinMainO, OwLMain() обеспечивает доступ к аргументам командной строки argc и argv (кото­рые не используются в примере 1).

Внутри функции OwlMain () вы выделяете из базового OWL-класса TApplication объект вашей программы. Класс TApplication имеет два конструктора. Первый (который как раз и используется в программе 1) имеет единственный аргумент — имя приложения, которое появляется в строке заголовка основного окна. Прототип этого конструктора выглядит следующим образом:

TApplication (const char far *name = 0);

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

 

 

Внимание! В приложениях, написанных с помощью ObjectWindows 1.0, выполнение про­граммы начинается с вызова функции WinMain (), как и в большинстве Windows-программ. В ObjectWindows 2.0 же выполнение программы начинает­ся с обращения к функции OwlMain(). Это связано тем, что в OWL предусмот­рена своя версия функции WinMain(), которая обеспечивает собственную проверку и обработку ошибок. Эта принятая по умолчанию версия автоматически вызывает функцию OwдMain(). И хотя можно написать свою собственную WinMain (), в этом нет никакой необходимости.  

 

Другой конструктор TApplication, который следует использовать лишь при необходимости написать собственную версию WinMain () (это бывает, хотя и не чаще, чем вы ходите по потолку), поддерживает дос­туп к аргументам, используемым функцией WinMain (). Этот конструк­тор приведен ниже:

TApplication (const char far *name,

HINSTANCE instance, HINSTANCE prevlnstance,

const char far *cmdLine, int cmdShow);

 

Функция WinMain () из примера 1 вначале генерирует объект - приложение под названием Арр. В следующей строке вы вызываете функцию-член Run () объекта Арр, которая переводит приложение в активное и состояние, инициализирует его и запускает цикл обработки сообщений.

Run() заканчивает работу только тогда, когда пользователь закрывает приложение.

Понятие об основном окне приложения

Хотя простейшая OWL-программа из примера 2.1 создает полноценное; работающее основное окно, оно не способно взаимодействовать с пользо-' вателем, кроме как через элементы управления, и может только переме­щаться, менять размер, сворачиваться и разворачиваться. Такое прило­жение не только скучно, как соревнование по стрижке газона, — оно также по большому счету бесполезно, разумеется, если только целью не является демонстрация работы основных элементов управления окном.

Чтобы сделать OWL-приложение полезным, нужно заставить объект приложения создать окно более сложное, чем то, которое создается по умолчанию. Для этого необходимо переписать виртуальную функцию InitMainWindow() класса TApplication, как показано в примере 2.

Пример2. TINYAPP.CPP — программа, задающая регулируемое основное окно.

/////////////////////////////////////////////////// TINYAPP2.СРР: /////////////////////////////////////////////////

// Демонстрирует создание,класса

// приложения и задание класса его основного окна

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

#tinclude <owl\applicat.h>

#include <owl\framewin.h>

// Класс приложения.

class TApp: public TApplication

{

public:

TAppO: TApplication () {}

void InitMainWindowO;

// Класс основного окна.

class Twndw: public TFrameWindow

{

public:

TWndw(TWindow *parent, const char far *title):

TFrameWindow(parent, title) {} };

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// TApp::InitMainWindow()

// Эта функция создает основное окно приложения.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ТАрр::InitMainWindow()

{

TFrameWindow *wndw = new Twndw(0, "Tiny App 2");

SetMainWindow(wndw);

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// OwlMain()

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int OwlMain(int, char*[])

{

return TApp().Run();

}

Создание регулируемого (настраиваемого) окна

При запуске программы из примера 2 появляется окно, показан­ное на рис. 2. Это окно выглядит и функционирует точно так же, как и ок­но, созданное программой из примера 1, только имеет другой заголо­вок. Существует и более важное отличие. Теперь основное окно — это окно вашего собственного класса TWndw, а не класса, определенного по умолчанию TFrameWindow. Как следствие, вы можете добавлять в этот класс любые функции, обеспечивающие необходимое поведение основного окна.

Рис. 2. Простейшее приложение с настраиваемым окном.

Для замены новым оконным классом класса TApplication, используемого
по умолчанию, необходимо переопределить функцию InitMainWindow(). Для
этого необходимо сначала создать собственный класс приложения, производный от
TApplication. В примере 2 этот новый класс выглядит следующим образом:

class TApp: public TApplication

public:

TApp(): TApplication() void InitMainWindow();

Здесь конструктор ТАрр не содержит строки заголовка, а вместо нее берет для данного аргумента нулевую строку, принимаемую в классе TApplication по умолчанию. В строке заголовка: нет необходимости, её можно указать при задании основного окна приложения. Конст­руктор в ТАрр вызывает конструктор TApplication. Это позволяет ба­зовому классу ТАрр выполнять любую необходимую для программы инициализацию.

В классе ТАрр переопределяется функцию InitMainWindow() класса TApplication.

При переопреде­лении функции из OWL необходимо убеди­ться, что выполняется обращение к версии функции базового класса. Для этого необходимо проверить по справочнику OWL, не произво­дит ли функция, которую вы используете, какие-либо другие важные действия в приклад­ной программе.

Создание окна на базе TFrameWindow

После объявления нового класса, производного от TApplication, мы полу­чили полноценное приложение, не похожее на программу из примера 1. Основная разница в том, что здесь создан собственный экземпляр TApplication. Далее необходимо объявить класс главного окна для вашего прило­жения:

class Twndw: public TFrameWindow

{

public:

TWndw(TWindow *parent, const char far *title): TFrameWindow(parent, title) {}

Здесь создан класс TWndw основного окна на базе класса TFrameWindow, являющегося общим оконным классом. Конструктор TWndw берет два аргумента — указатель на родительское окно и заголовок окна — и передает их конструктору TFrameWindow. (Сам TFrameWindow яв­ляется производным по отношению к TWindow.) Помните, что, поскольку вы намереваетесь использовать класс TFrameWindow, необходимо вклю­чить в вашу программу его заголовочный файл FRAMEWIN.H.

 

Внимание! Библиотека ObjectWindows 1.0 поддерживает два типа общих окон. Класс TWindowObject содержал базовые функции, требуемые для всех оконных объ­ектов, но является абстрактным классом. Класс TWindow использовался для создания окон всех видов, включая основные окна. Программируя в ObjectWindows 2.0, вы должны использовать TFrameWindow там, где исполь­зовали бы TWindows версии 1.0. Новый класс TWindow в версии 2.0 очень по­хож на старый TWindowsObject, за исключением того, что не является абст­рактным.

 

Создание настраиваемого основного окна

Теперь, объявив собственный оконный класс, вам предстоит исполь­зовать его для создания главного окна приложения. Для этого вызыва­ется конструктор класса TWndw, тот самый, который вызывался в функ­ции initMainWindowO класса ТАрр:

void ТАрр:: InitMainWindow()

{

TFrameWindow *wndw = new Twndw(0, "Tiny App 2");

SetMainWindow(wndw);

}

Оператор new динамически создает объект TWndw, возвращая требуе­мый указатель типа TWindow. Первый аргумент конструктора TWndw равен нулю, поскольку это окно не имеет окон-родителей. Второй аргумент — заглавие, появляющееся в строке заголовка при создании окна. Если вы передаете окну заголовок при создании объекта приложения (как в при­мере 2.1), в окне появляется заголовок, указанный в конструкторе. Вот почему в примере 2.2 строится объект приложения без строки заголовка. Зачем его включать, если он не используется?

MainWindow, указатель на TWindow, входит в состав класса TApplication, являющегося базовым для класса ТАрр (стало быть, ТАрр имеет собственную копию MainWindow). Чтобы задать значение этого ука­зателя, вызывается функция SetMainWindow () объекта прикладной про­граммы, имеющая в качестве единственного аргумента указатель на TFrameWindow или окно, производное oт TFrameWindow.

На экране появляется новое основное окно. Необходимо, чтобы оно могло отвечать на сообщения Windows.

 

Внимание! В программах, написанных в ObjectWindows 1.0, назначение указателяMainWindow об-ьекта программы производилось, как правило, напрямик:MainWindow = new TWindow (). В OWL 2.0 существует функцияSetMainWindow (), которая избавляет вас от прямого обращения к MainWindow. Доступ к данным класса через его функ­ции — это в духе объектно-ориентированного программирования, требующего мак­симального сокрытия данных класса.

Как отвечать на сообщения Windows

Помимо многих функций, которые приложение в конечном сче­те должно выполнять, есть одна, обязательная для каждой Windows-про­граммы, — обработка сообщений Windows. Сообщения, посылаемые программе, поддерживают ее связь не только с внешним миром (пользователем), но и с внутренними действиями Windows.

Для этого OWL-приложения имеют определённых механизм для принятия и обработки тысяч сооб­щений, получаемых от Windows. Это осуществляется путем создания функций-ответов специально для тех сообщений, которые должны обра­батываться. Затем создается таблица откликов, устанавливающая связь между этими функциями и соответствующими им сообщениями. В при­мере 3 показано, как это осуществляется.

Пример 3. MSGAPP.CPP — программа, отвечающая на сообщения Windows.

 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//MSGAPP.CPP: Демонстрирует ответ на сообщения
// Windows.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

#include <owl\applicat,h>

#include <owl\framewin.h>

// Класс приложения.

class TApp: public TApplication

{

public:

TApp(): TApplication() {}

void InitMainWindow();

// Класс основного окна.

class TWndw: public TFrameWindow

{

public:

TWndw(TWindow *parent, const char far *title)

TFrameWindow(parent, title) {}

protected:

void EvLButtonDown(UINT, TPoint &point);

DECLARE RESPONSE TABLE(TWndw);

};

DEFINE_RESPONSE_TABLE1(TWndw, TFrameWindow)

EV_WM_LBUTTONDOWN,

END__RESPONSE_TABLE;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// TWndw::EvLButtonDown()

//

// Эта функция отвечает на сообщения

// WM_LBUTTONDOWN,которые приложение получает в

// момент нажатия левой кнопки мыши, когда указатель

// мыши находится в пределах окна.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void TWndw::EvlButtonDown(UINT, TPoint&)

{

MessageBox("Got the click!", "Message", MB OK);

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// TApp::InitMainWindow()

//

// Эта функция создает основное окно приложения.

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

void ТАрр::InitMainWindow()

{

TFrameWindow *wndw = new TWndw(0, "Message App");

SetMainWindow fwndw);

}

 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// OwlMain()

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int OwlMain(int, char*[])

{

return TApp().Run();

}

 

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

 

 

 

Рис. 3 Приложение, отвечающее на нажатие кнопки мыши.

 

  Windows-программы управляются событиями. Любое действие со стороны пользователя генерирует событие, которое программа получает в виде со­общения Windows. Существует более 100 различных сообщений Windows. Ка­ждое из них представлено стандартной константой. Например, когда пользо­ватель нажимает левую кнопку мыши, Windows генерирует сообщение WMLBUTTONDOWN. Когда пользователь выбирает другой элемент в списке, Windows генерирует сообщение CBNjSELCHANGE. Все сообщения о типах событий, на которые должна реагировать программа, содержатся в справочнике по Windows.  

 

Как вставить в класс окна таблицу ответов

В примере 2.3 класс ТАрр приложения остается без изменений. Одна­ко главный класс окна TWndw содержит теперь таблицу ответов и функ- ответа на сообщения, обрабатывающую нажатие левой клавиши

ши. И таблица ответов, и функция ответа на сообщение содержатся в описании класса:

class TWndw: public TFrameWindow

public

TWndw(TWindow *parent, const char far *title)

TFrameWindow(parent, title){} protected:

void EvLButtonDown(UINT, TPoint &point);

DECLARE RESPONSE TABLE(TWndw);

В классе TWindow (базовом классе для TFrameWindow и нашего собственного TWndw) встроены макросы для таблицы ответов на стандартные сообщения Windows. Этими макросами пользуются для автоматической настройки конкретной акции, отвечающей на заданные сообщения Windows. К примеру, EvLButtonDown() является функцией ответа на соответствующее сообщение WM_LBUTTONDOWN.

строгим правилам, с тем, чтрбы Borland C++ мог сопоставить функцию с соответствующим ей сообщением.

Необходимое имя функции определяется для конкретного сообщения Windows путем замены в имени сообщения приставки WM^ на Ev и пропис­ных букв на строчные, за исключением первых букв каждого «слова», вклю­ченного в имя сообщения. Таким образом, WM_LBUTTONrowN дает EvLButtonDown, WMJPAINT — EvPaint, WM_MOUSEMOVE — EvMouseMove и т.д. Теперь мы видим, что в приведенном выше объявлении функция EvLButtonDown отвечает на сообщение WM_LBUTTONDOWN.

Для объявления в классе таблицы откликов используется макрос DECLARE_RESPONSE_TABLE, требующий в качестве единственного аргумен­та имя класса, для которого объявляется таблица. Сама таблица опре­деляется за пределами класса, как правило, сразу за его объявлением:

DEFINE_RESPONSE_TABLE1 (TWndw, TFrameWindow)

EV_WM_LBUTTONDOWN,

END_RESPONSE_TABLE;

Таблица начинается с макроса DECLARE_RESPONSE_TABLE. За именем макроса должно следовать число непосредственных базовых классов, про­изводным которых является данный класс. Как и в случае TWndw, это чис­ло почти всегда равно 1. Исключение составляют классы, произведенные с использованием множественного наследования. За именем макроса и числом непосредственных базовых классов указывается имя класса, для которого определяется таблица, а также имена непосредственных базо­вых классов. Единственным непосредственным базовым классом для TWndw является TFramneWindow, поэтому только он и указан в макросе. Имена классов заключаются в скобки и разделяются запятыми.

Как уже говорилось раньше, Borland определил макрос таблицы откликов на все стандартные сообщения Windows. Чтобы дать возмож­ность вашему окну ответить на конкретное сообщение, необходимо толь­ко включить его макрос в вашу таблицу ответов и указать соответствую­щую обрабатывающую функцию. Можно определить имя макроса путем добавления к имени сообщения приставки EV_. Таким образом, макро­сом таблицы откликов на сообщение WM_LBUTTONDOWN будет ev_wm_lbuttondown, макросом для wm_paint будет ev_wm_paint, макро-

СОМ ДЛЯ WM_MOUSEMOVE будет EV_WM_MOUSEMOVE и т.д.

В предыдущем примере была определена таблица откликов, устанавли­вающая соответствие между сообщением WM_LBUTT0NDOWN и обрабатываю­щей функцией EvLButtonDown () класса TWndw. Использование макроса таблицы откликов для сообщения WM_LBUTTONDOWN и соответствующее, по всем правилам, указание имени обрабатывающей функции — это всё, что требуется для получения этого сообщения.

Borland C++ сгенерирует код, необходимый для посылки сообщения WM_BUTTONDOWN вашей функции EvLButtonDown (). Заметьте, что все на­именования в таблице ответов должны заканчиваться запятой — даже последнее.

Написание функций ответа на сообщения

 

Теперь, объявив свой класс и определив таблицу ответов, вам необходи­мо определить функцию ответа на сообщения EvlButtonDown():

void TWndw::EvLButtonDown(UINT, TPoint&)

{

MessageBox("Got the click!", "Message", MB_OK);

}

Как узнать, какие типы аргументов возвращает и получает конкрет­ная обрабатывающая функция? Прототипы каждой из множества функций приведены в справочном руководстве по ObjectWindows, по­ставляемом вместе с вашей копией Borland C++. Как вы увидите из этого списка прототипов, одним из преимуществ использования встроенных макросов таблиц ответов является то, что перед тем, как быть переданным вашей обрабатывающей функции, соответствующее сообщение Windows «вскрывается». Другими словами, Borland C++ автоматически выделяет нужные значения, передаваемые в параметрах wParam и lParam.

Например, в случае сообщения WM_LBUTTONDOWN Windows определяет виртуальный ключ-флаг в wParam, а также х- и у-координаты указателя мыши в lParam. Но вместо того, чтобы заставлять вас извлекать эту ин­формацию, Borland C++ автоматически делает это сам и посылает значе­ния вашей функции EvLButtonDown(), где виртуальный ключ-флаг находит­ся в поле UNIT, а х- и у-координаты мыши — в объекте TPoint.

В функции EvLButtonDown() обращение к MessageBox() отображает стандартное окно сообщений Windows в момент нажатия левой кнопки мыши. Однако не следует путать MessageBox() в этой функции и MessageBox() в Windows API. Данный MessageBox() — это функция класса TWindow. Как уже говорилось раньше, ObjectWindows 2.0 берет максимум возможного из Windows API, делая обращения ко многим функциям более удобными.

Например, вызывая MessageBox() в Windows API, в качестве первого пара­метра вы должны передать дескриптор окна. Поскольку объект TWindow уже «знает» собственный ключ, его MessageBox() не требует дескриптора окна. Во время вызова MessageBox() класса TWindow он автоматически генерирует этот дескриптор и далее передает его в Windows-функцию MessageBox().

 

Функция MessageBox() отображает на экране окно сообщений. Версия WindowsAPI этой функции требует четыре аргумента: дескриптор окна; указатель настроку с символом «\0» на конце, содержащую текст сообщения; указатель настроку с символом «\0» на конце, используемую в качестве заголовка окна; ислово, содержащее различные флаги отображения. Флаги отображения позволя­ют выбрать, какие графические элементы и кнопки должны появиться в окнесообщения. За более подробной информацией о перечне этих флагов обращай­тесь к справочнику по Windows. Функция MessageBox () возвращает целое, оз­начающее, какую кнопку нажал пользователь. Заметьте, что версия MessageBox() библиотеки ObjectWindows 2.0, являющаяся функцией-членом классаTWindow, не требует в качестве параметра дескриптор окна.

 

Пользуясь встроенными макросами таблиц ответов Borland, программа может обработать любое стандартное сообщение Windows.

 

Установка атрибутов окна

Каждое окно, имеющее в качестве предка TWindow, наследует переменную Attr, содержащую атрибуты окна. Переменная Attr - это структура типа TWindowAttr, включающая поля, приведённые в таблице.

Таблица 2.1. Члены классаTWindowAttr.
Имя Тип Описание
Style DWORD Стиль окна
ExStyle DWORD Расширенный стиль
X int х-координата
Y int у-координата
W int Ширина
H int Высота
Menu TResId ID(идентификатор) ресурса меню
AccelTable TResId ID ресурса акселератора
Param char far* Информация МDI-окна

 

Для задания атрибутов окна необходимо только указать соответствующие поля Attr в оконном конструкторе. В примере 4 показано, это сделать.

Пример 4. WINATTR.CPP — программа, задающая атрибуты окна.

///////////////////////////////////////////////////////////////////////////////////////////////////////////// WINATTR.CPP: Показывает установку атрибутов окна.

///////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <owl\applicat.h>

#include <owl\framewin.h>

// Класс приложения.

class TApp: public Tapplication

{

public:

TApp(): TApplication(void InitMainWindow(); { }

void InitMainWindow();

};

// Класс главного окна,

class TWndw: public TFrameWindow

{

public:

TWndw(TWindow *parent, const char far *title);

};

 

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////

// TWndw::Twndw()

// Это конструктор главного окна.

TWndw::TWndw(TWindow *parent, const char far *title):

TFrameWindow(parent, title)

{

// Выключить кнопку максимизации.

Attr.Style &= ~WS_MAXIMIZEBOX;

// Добавить к окну вертикальную линейку прокрутки.

Attr.Style |= WS_VSCROLL;

//Определить расположение и размеры окна.

Attr.X = 100;

Attr.Y = 100;

Attr.W = 400;

Attr.H = 300;

}

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////

// TApp::InitMainWindow

// Эта функция создает главное окно приложения.

///////////////////////////////////////////////////////////////////////////////////////////////////////////

void TApp::InitMainWindow()

{

TFrameWindow *wndw = new TWndw(0, "Attribute App");

SetMainWindow(wndw);

}

 

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////

// OwlMain()

///////////////////////////////////////////////////////////////////////////////////////////////////////////

int OwlMain(int, char*[])

{

return TApp().Run();

}

Программа из примера 4 похожа на программы, ранее рассмотрен­ные в этой главе. Ее отличие в том, что конструктор класса главного ок­на не является теперь встроенным и расширен за счет включения команд, устанавливающих некоторые атрибуты окна. Как всегда, конструктор сначала вызывает конструкторы базового класса:

TWNDW::Twndw (Twindow *parent, const char far *title): TFrameWindow (parent, title)

Затем первая команда в теле конструктора выключает кнопку макси­мизации:

Attr.Style &= ~WS_MAXIMIZEBOX;

Окно, производ­ное от TFrameWindow, имеет по умолчанию стиль WS_OVERLAPPEDWINDOW. Окно этого стиля включает заглавие, системное меню, широкую рамку, кнопки минимизации и максимизации. Поэтому, чтобы выключить кноп­ку максимизации, необходимо произвести логическое умножение (AND) отрицания WS_MAXIMIZEBOX и Attr.Stile.

Из следующей строки конструктора видно, как к окну добавляется стиль с помощью логического сложения нового стиля с Attr.Stile:

Attr.Style |= WS_VSCROLL;

В данном случае к окну добавляется вертикальная линейка прокрут­ки. Разумеется, можно осуществить полный сброс стиля окна с по­мощью присваивания:

Attr.Style = WS POPUP | WS SYSMENU | WS CAPTION;

 

Стиль окна хранится в двойном слове, биты которого отвечают за тип и состав­ные части окна. Различные стили окон определены заранее через список кон­стант. Вот некоторые из них: WS_BORDER — создает границу, WS_CAPTION — соз­дает линейку заголовка, WS_CHILD — создает дочернее окно, WS_HSCROLL — создает горизонтальную линейку прокрутки, WS_MAXIMIZE — максимизирует ок­но, WS_MAXIMIZEBOX — создает кнопку максимизации, WS_SYSMENU — создает системное меню, WS_VISIBLE — создает изначально видимое окно, и т.д. Чтобы создать конкретный оконный стиль, необходимо логически сложить константы, представляющие желаемые атрибуты. Для ознакомления с полным списком этих констант обращайтесь к справочнику по Windows.  

Последнее, что делает конструктор TWndw, — задает исходное положе­ние и размеры окна. Это производится через установку значения
элементов X, Y, w и Н структуры Attr, определяющих соответственно х-
и у-координаты, ширину и высоту:

Attr.X = 100;

Attr.Y = 100;

Attr.W = 400;

Attr.H = 300;

В вышеприведённом случае основное окно будет иметь координаты 100, 100 и размер 400 пикселов в высоту.

Закрытие окна

Любой объект OWL-программы, так же, как и любое окно, производное от TWindow, содержит функцию CanCloseO, которая автоматически вызывается, когда пользователь пытается закрыть приложение или окно функция CanClose() приложения вызывает CanClose() основного окна та, в свою очередь, — CanClose() каждого дочернего окна. Прежде, чем приложение или окно закрывается, каждая функция CanClose() должна возвратить TRUE.

Если CanCloseO для ваших оконных классов не определена, то CanClose() класса TWindow возвращает TRUE, не выполняя никаких действий. Поэтому, если вы хотите защитить данные пользователя, необходимо переопределить CanClose() для каждого оконного класса, co­стояние которого требует проверки перед закрытием. В примере 5 показано, как это сделать. Окно, создаваемое в результате работы программы, показано на рис.5.


Рис 5. Это окно проверяет, можно ли закрыть приложение.


Пример 5. CANCLOSE.CPP — программа, которая спрашивает пользователя, можно ли закрыть приложение.

/////////////////////////////////////////////////////////////////////////////////////////////////////////

// CANCLOSE.CPP: Показывает, как проверить, можно
// ли закрыть окно.

///////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <owl\applicat.h>

#include <owl\framewin.h>

// Класс приложения.

class TApp: public TApplication

{

public:

TApp(): TApplication() {}

void InitMainWindow();

// Класс главного окна.

class TWndw: public TFrameWindow

{

public:

TWndw(TWindow *parent, const char far *title);

protected:

BOOL CanClose();

}

// Реализация класса TWndw.

/////////////////////////////////////////////////////////////////////////////////////////////////////////

// TWndw::TWndw()

///////////////////////////////////////////////////////////////////////////////////////////////////////////

// Это конструктор главного окна.

///////////////////////////////////////////////////////////////////////////////////////////////////////////

 

Twndw::Twndw(TWindow *parent, const char far *title):

TFrameWindow(parent, title)

{

// Задать размер и расположение окна.

Attr.X = 100;

Attr.Y = 100;

Attr.W = 400;

Attr.H = 300;

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////

// TWndw::CanCloseO

//

// Эта функция, переопределяющая функцию CanClose()

// базового класса, позволяет пользователю

// подтвердить, что он хочет закрыть основное окно.

// Закрытие главного окна влечет закрытие всей

// программы.

BOOL TWndw::CanClose()

{

// Переспросить пользователя, можно ли закрывать окно,

int result = MessageBox("Okay to close?", "Close",

MB_YESNO | MB_ICONQUESTTON);

// Если CanCloseO возвращает TRUE, окно закроется

if (result == IDYES)

return TRUE;

else

return FALSE;

 

// Реализация класса ТАрр.

// ТАрр::InitMainWindow0

//

// Эта функция создает главное окно приложения.

void ТАрр::InitMainWindow()

{

TFrameWindow *wndw = new TWndw(0, "CanClose App");

SetMainWindow(wndw);

}

 

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////

// OwlMain()

///////////////////////////////////////////////////////////////////////////////////////////////////////////

 

int QwlMain(int, char*[])

{

return TApp().Run();

}

Функция CanClose()

Функция CanClose () класса Twndw:

 

BOOL TWndw::CanClose()

{

// Переспросить пользователя, можно ли закрывать

// окно.

int result = MessageBox("Okay to close?", "Close", MB_YESNO

| MB_ICONQUESTION);

// Если CanClose() возвращает TRUE, окно закроется,

if (result == IDYES)

return TRUE;
else

return FALSE;

}

 

Когда пользователь пытается закрыть окно или завершить приложение, вызывается ваша версия CanClose (). В этой функции окно сообщений спрашивает пользователя, действительно ли он хочет закрыть окно. Если пользователь нажимает клавишу Yes, CanClose () возвращает TRUE, и программа закрывает окно. Если пользователь нажимает кноп­ку No, CanClose () возвращает FALSE, и программа оставляет все, как есть.

В реальной программе нужен флаг, кото­рый отслеживает, изменял ли пользователь данные в окне. Если этот флаг равен TRUE в момент вызова CanClose() (что означает: все изме­нения были сохранены), вы закрываете приложение без отображения ок­на сообщений. Если флаг установлен в FALSE, вы спрашиваете пользо­вателя, не желает ли он сохранить текущий файл. Следует не только предоставить возможность сохранить файл, но и возможность отменить команду Close, если она была сделана случайно. Такие окна сообщений обычно содержат кнопки Yes, No и Cancel. В этом случае функция CanClose () может выводить на экран окно, показанное на рис. 6, и мо­жет быть реализована следующим образом:

 

 

BOOL TWndw::CanClose()

{

if (saveFlad) return TRUE;

int result = MessageBox ("Your file was change.Save it?", "Close",

MB_YESNOCANCEL | MB_ICONQUESTION);

if (result == IDYES)

{

SaveFile (); return TRUE;

}

else

if (result == IDNO) return TRUE;

else return FALSE;

}

 



 

Рис. 2.6

Профессионально сделанное прило­жение

позволяет пользователю сохранить или

проигнорировать внесенные изменения

или отменить команду Close.


Приложение

КОДЫ КЛАВИШ

 

Латинский алфавит

A – 65, B – 66, С – 67, D – 68, …, Z – 90;

а – 97, b – 98, …, z- 122;

Русский алфавит (Кодировка некотрый символов совпадает с англ)

А – 70, Б – 60,

F1 – 1083

F2 – 1084

F3 – 1085

F4 – 1086

F5 – 1087

F6 – 1088

F7 – 1089

F8 – 1090

F10 –1091

F11 – 1092

F12 –1093

 

ESC – 27

ENTER – 13

LEFT - 1099

RIGHT – 1101

UP – 1096

DOWN 1104

BCSPASE - 8

DEL – 1107

 






Не нашли, что искали? Воспользуйтесь поиском:

vikidalka.ru - 2015-2024 год. Все права принадлежат их авторам! Нарушение авторских прав | Нарушение персональных данных