ТОР 5 статей: Методические подходы к анализу финансового состояния предприятия Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века Характеристика шлифовальных кругов и ее маркировка Служебные части речи. Предлог. Союз. Частицы КАТЕГОРИИ:
|
Классы ObjectWindowsOWL содержит множество классов, способствующих более быстрому и простому написанию прикладных программ. 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-приложений должны быть дочерними 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 также инкапсулирует в классы стандартные диалоговые окна 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, поддерживаемая большим количеством возможных драйверов, приводит к тому, что вывод на принтер в Windows — задача непростая. Но теперь, благодаря новым классам OWL, вы можете напечатать документ любого типа, приложив при этом минимум усилий. В частности, для управления заданиями для принтера OWL поддерживает два класса: класс TPrinter, включающий функции принтера и поддержку драйверов, и класс TPrintout, отвечающий за подготовку документа к печати. Оба эти класса вместе служат для получения твердых копий с помощью установленного в данный момент принтера. Когда вы создаете объект, относящийся к классу TPrinter, приложение автоматически связывается с принтером пользователя, заданным по умолчанию так, как указано в файле WIN.INI. Объект TPrintout, будучи весьма мощным средством, позволяет также легко напечатать простой, в одну страницу, документ с помощью одной-единственной функции, как и осуществить вывод в область окна с помощью оконной функции закраски. Для более сложных многостраничных документов TPrintout помогает произвести разбивку на страницы, компоновку, управлять размером страниц и взаимодействовать с пользователем через специальное окно диалога.
В 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); Поскольку этот единственный аргумент конструктора по умолчанию принимает значение нулевой строки, можно создавать приложение, вообще не используя никаких аргументов. При этом, однако, основное окно останется без заголовка.
Другой конструктор 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, используемого 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.
Создание настраиваемого основного окна Теперь, объявив собственный оконный класс, вам предстоит использовать его для создания главного окна приложения. Для этого вызывается конструктор класса 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.
Как отвечать на сообщения Windows Помимо многих функций, которые приложение в конечном счете должно выполнять, есть одна, обязательная для каждой Windows-программы, — обработка сообщений Windows. Сообщения, посылаемые программе, поддерживают ее связь не только с внешним миром (пользователем), но и с внутренними действиями Windows. Для этого OWL-приложения имеют определённых механизм для принятия и обработки тысяч сообщений, получаемых от Windows. Это осуществляется путем создания функций-ответов специально для тех сообщений, которые должны обрабатываться. Затем создается таблица откликов, устанавливающая связь между этими функциями и соответствующими им сообщениями. В примере 3 показано, как это осуществляется. Пример 3. MSGAPP.CPP — программа, отвечающая на сообщения Windows.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //MSGAPP.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) 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 Приложение, отвечающее на нажатие кнопки мыши.
Как вставить в класс окна таблицу ответов В примере 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().
Пользуясь встроенными макросами таблиц ответов Borland, программа может обработать любое стандартное сообщение Windows.
Установка атрибутов окна Каждое окно, имеющее в качестве предка TWindow, наследует переменную Attr, содержащую атрибуты окна. Переменная Attr - это структура типа TWindowAttr, включающая поля, приведённые в таблице.
Для задания атрибутов окна необходимо только указать соответствующие поля 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;
Последнее, что делает конструктор TWndw, — задает исходное положение и размеры окна. Это производится через установку значения 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; 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
Не нашли, что искали? Воспользуйтесь поиском:
|