Объекты меню

Большинство прикладных программ Windows поддерживают меню в составе своего главного окна. Меню обеспечивает пользователю разнообразные возможности выбора, такие как Save, Open и Help. Иногда в приложениях требуются сложные меню. Объекты меню ObjectWindows (TMenu, TSystemMenu, TMenuDescr и TPopupMenu) дают вам простой способ создания меню и манипулирования ими.

Построение объектов меню

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

Конструктор Описание
TMenu() Создает пустое меню.
TMenu(HWND) Создает объект меню, представляющий текущее меню окна.
TMenu(HMENU) Создает объект меню из уже загруженного меню.
TMenu(LPCVOID*) Создает объект меню из шаблона меню в памяти.
TMenu(HINSTANCE, TResID) Создает объект меню из ресурса.

Модификация объектов меню

После создания объекта меню вы можете использовать функции-элементы TMenu для его модификации. Этот такие функции как AppendMenu, InsertMenu (для добавления пунктов меню), ModifyMenu (для модификации пункта меню), EnableMenu (для разрешения и запрещения пунктов меню), DeleteMenu и RemoveMenu (для удаления пунктов меню), CheckMenu и SetMenuItemBitMaps (для отметки пунктов меню) и TrackPopupMenu (для вывода всплывающих меню).

После модификации объекта меню вам следует вызвать для обновления строки меню функцию-элемент DrawMenuBar.

Опрос объектов меню

TMenu имеет ряд функций-элементов и операций, с помощью которых вы можете получать информацию об объекте и его меню. Это operator UINT и operator HMENU (возврат описателя меню), IsOK (проверка допустимости описателя меню), GetMenuItemCount (число пунктов меню), GetMenuCheckMarkDimensions (размер битового массива для вывода отметки меню), GetMenuItemID (идентификатор пункта в заданной позиции), GetMenuState (флаги состояния заданного пункта), GetMenuString (текст заданного пункта меню), GetSubMenu (описатель меню в заданной позиции).

Использование объектов меню

Класс TSystemMenu ObjectWindows позволяет вам модифицировать системное меню окна. Этот класс является производным от TMenu и отличается от него только конструктором, в аргументах которого указывается описатель окна и флаг. Если флаг имеет значение True, то текущее системное меню удаляется, и на его место помещается объект меню, представляющий немодифицированное меню. В случае False объект меню представляет текущее системное меню. Для работы с системным меню можно использовать все функции-элементы, наследуемые из TMenu.

Для создания всплывающего меню, которое вы можете добавить к окну или существующей системе меню, можно использовать TPopupMenu. Этот производный от TMenu класс также отличается от него только конструктором. После создания всплывающего меню для вывода "свободно плавающего меню" можно использовать TrackPoupMenu.

В ObjectWindows 2.0 для присваивания ресурсом меню используется функция AssignMenu, которая определяется в классе TFrameWindow и доступна в любом производном классе.

Объекты диалоговых блоков

Объекты диалоговых блоков - это интерфейсные объекты, которые инкапсулируют поведение диалоговых окон. Инициализацию, создание и выполнение всех типов диалоговых блоков поддерживает класс TDialog. Вы можете создать специализированные диалоговые блоки, производные от TDialog. ObjectWindows поддерживает также классы, инкапсулирующие общие диалоговые блоки Windows. Windows предусматривает общие диалоговые блоки, позволяющие пользователям выбирать имена файлов, шрифты, цвета и т.д.

Использование объектов диалоговых блоков

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

Использование объектов диалоговых окон требует следующих шагов:

Построение объекта диалогового блока

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

Каждый ресурс диалогового блока имеет идентификатор, который позволяет объекту диалогового блока задать, какой ресурс диалогового блока будет использоваться. Идентификатор может быть строкой или целым числом. Вы можете передать этот идентификатор конструктору диалогового блока.

Для построения объекта диалогового блока создайте его, используя указатель на родительское окно и идентификатор ресурса. Родительское окно почти всегда задается как this. Можно также использовать основное окно приложения (это единственное окно, всегда присутствующее в приложении ObjectWindows). Исключением является ситуация, когда вы задаете объект диалогового блока как клиентное окно в конструкторе TFrameWindow. Конструктор передает объект диалогового блока функции TFrameWindow::Init, которая автоматически устанавливает родительский объект диалогового блока.

Выполнение диалогового блока

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

Большинство диалоговых блоков режимные. При выводе такого диалогового блока пользователь не может использовать родительское окно, пока не закроет этот диалоговый блок. Таким образом, режимный диалоговый блок "замораживает" операции в остальной части приложения.

Для режимного выполнения диалогового блока используйте TDialog::Execute. При закрытии диалогового блока Execute возвращает целое значение, указывающее на характер закрытия (идентификатор "нажатого" управляющего элемента, например, IDOK). Если диалоговый блок распределялся динамически, не забудьте удалить объект.

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

Для безрежимного выполнения диалогового блока используйте TDialog::Create. При этом с помощью флага WS_VISIBLE или функции ShowWindow нужно явно задать видимость диалогового блока. Закрыть диалоговый блок и удалить объект можно с помощью TDialog::CmOk и TDialog::CmCancel.

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

Можно также использовать автоматическое создание. При этом ObjectWindows автоматически создает за вас дочерние диалоговые объекты. Создав эти объекты в конструкторе производного от TWindow класса (спецификацией в качестве родительского объекта this), производный от TWindow класс строит список дочерних окон. Это происходит также когда объект диалогового блока является элементом данных родительского класса. При создании производного от TWindow класса он пытается создать все дочерние объекты в списке с включенным флагом wfAutoCreate. В результате дочерние объекты выводятся на экране одновременно с родительским окном.

Включить флаг wfAutoCreate можно с помощью функции EnableAutoCreate, а выключить - с помощью DisableAutoCreate. Для автоматического создание дочерних объектов TWindow использует Create. При использовании автоматического создания нужно обеспечить видимость диалогового блока с помощью флага WS_VISIBLE. Для разрешения автоматического создания можно использовать ShowWindow.

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

Считать данные из диалогового блока можно в любое время, пока существует объект диалогового блока. Чаще всего это делается в функции CmOK диалогового блока, которая вызывается по кнопке OK.

Аналогично оконным объектам, функции-элементы Create и Execute диалогового блока могут порождать исключительную ситуацию TXWindow. Такая ситуация обычно возникает при невозможности создания диалогового окна. Можно также использовать глобальный обработчик особых ситуаций, который ObjectWindows инсталлирует при запуске приложения, или установить свой собственный. Чтобы задать собственный разработчик, заключите защищаемый код в блок try/catch.

Закрытие диалогового блока

Каждый диалоговый блок должен обеспечивать возможность закрытия его пользователем. Для режимных диалоговых блоков это делается обычно с помощью кнопки OK или Cancel. TDialog имеет функцию реакции на события CmOk или CmCancel, отвечающие на данные кнопки. CmOk вызывает CloseWindow, которая для проверки возможности закрытия диалогового блока вызывает CanClose. При возврате True CloseWindow передает данные диалогового блока и закрывает его вызовом CloseWindow. CmCancel вызывает функцию Destroy, которая закрывает диалоговый блок безусловно и без передачи данных. Для проверки ввода вы можете переопределить CanClose.

Использование диалогового блока в качестве основного окна

Чтобы использовать диалоговый блок в качестве основного окна, лучше создать окно-рамку с диалоговым блоком в качестве клиентного окна. Для этого создайте производный от Tapplication класс. Кроме конструктора, единственное, что для этого требуется, это функция InitMeinWindow, в которой строится объект окна-рамки. Конструктор TFrameWindow включает автоматическое создание объекта диалогового блока, который вы передаете в качестве клиента.

Требуется также обеспечить, чтобы объект диалогового блока имел определенные атрибуты:

Манипуляция управляющими элементами в диалоговых блоках

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

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

Windows определяет набор сообщений управляющих элементов, которые посылаются из приложения обратно в Windows. Управляющие сообщения определяют конкретный управляющий элемент и передают информацию в аргументах wParam и lParam. Каждый управляющий элемент в диалоговом ресурсе имеет идентификатор, с помощью которого вы можете задать получающий сообщение управляющий элемент. Чтобы послать сообщение, вызывается функция SendDlgItemMessage.

Связь интерфейсных объектов с управляющими элементами

Так как диалоговый блок создается из ресурса, вам не нужно использовать для задания его вида или вида его управляющих элементов код С++. Это позволяет создавать диалоговый блок визуально, но затрудняет управление управляющими элементами из приложения. ObjectWindows позволяет связать или ассоциировать управляющие элементы в диалоговом блоке с интерфейсными объектами. Такая связь позволяет делать следующее:

Объекты управляющих элементов

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

Манипулировать управляющими элементами вы не сможете, пока не будет выполнена функция SetupWindow диалогового блока, поскольку до этого момента связь управляющих элементов с соответствующими объектами отсутствует. После установления связи элемента данных HWindows для управляющих элементов становится допустимым.

Использование диалоговых блоков

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

Тип Класс ObjectWindows
Цвет TChooseColorDialog
Шрифт TChooseFontDialog
Открытие файла TFileOpenDialog
Сохранение файла TFileSaveDialog
Поиск строки TFindDialog
Ввод от пользователя TInputDialog
Диалог прерывания принтера TPrinterAbortDialog
Управление принтером TPrintDialog
Замена строки TReplaceDialog

Диалоговые блоки ввода

Диалоговые блоки ввода - это простые диалоговые блоки, выводящие пользователю подсказку для ввода одной строки текста. Вы можете выполнять диалоговые блоки как режимные или безрежимным, но обычно они являются режимными. С объектами диалоговых блоков связан ресурс диалогового блока, который находится в файле сценария ресурса inputdia.rc. Файл ресурса вашего приложения должен включать в себя этот файл.

При построении объекта диалогового блока задается указатель на объект родительского окна, заголовок, подсказку, текстовый буфер и его размер. В этом буфере содержится заданный по умолчанию текст ввода. Когда пользователь выбирает OK или нажимает Enter, строка введенного текста автоматически передается в массив символов.

Использование общих диалоговых блоков

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

Каждый общий диалоговый блок имеет вложенный класс TData, который содержит некоторые служебные функции-элементы и данные, соответствующие каждому типу общего диалогового блока. Например, TChooseCologDialog:TData имеет функции-элементы для выбора цветов и массив цветов. Однако TData имеют два элемента, общих для всех вложенных классов TData. Элемент Flag представляет собой набор специальных флагов, управляющих внешним видом и поведением диалогового блока, а Error содержит код ошибки, которая происходит при обработке общего диалогового блока, или 0.

Каждый класс общего диалогового блока имеет конструктор, которому передается указатель на объект родительского окна, ссылка на вложенный класс TData данного класса и дополнительные необязательные параметры, содержащие шаблон диалогового блока, строку заголовка и модуль принтера.

После построения объекта общего диалогового блока его следует выполнить (если это режимный диалоговый блок) или создать (если он безрежимный). Создание выполняется с помощью функции Create, а выполнение - Execute. К безрежимным относятся типы Color, Font, File open, File save и Printer, а безрежимным - Find и Find/replace. Успешность выполнения Execute проверяется по возвращаемому значению.

Диалоговые блоки выбора цвета

Общие диалоговые блоки выбора цвета позволяют вам выбирать и создавать используемые в приложениях цвета. TChooseColorDialog::TData имеет несколько элементов типа TColor и TColor*, которые перед построением объекта диалогового блока нужно инициализировать. Color задает выбранный цвет. При выполнении диалогового блока это будет цвет, используемый по умолчанию, а при закрытии диалогового окна - выбранный пользователем цвет. CustColors - это указатель на 16 специальных цветов. На входе он задает используемые по умолчанию цвета, а на выходе - выбранные пользователем цвета.

Диалоговые блоки выбора шрифтов

Общие диалоговые блоки выбора шрифтов позволяют вам выбрать используемый в приложении шрифт, включая гарнитуру, стиль, размер и т.д. TChooseFontsDialog::TData имеет несколько элементов которые перед построением объекта диалогового блока нужно инициализировать.

Элемент TData Описание
DC Описатель контекста устройства принтера, шрифты которого вы хотите выбрать при задании флага CF_PRINTERFONTS в Flags.
LogFont Описатель LOGFONT, который задает внешний вид шрифта. При выполнении диалогового блока и задании флага CF_INITTOLOGFONTSTRUCT диалоговое окно выводится с заданным шрифтом.
PointSize Размер выбранного шрифта (в 1/10 пункта). На входе задает размер выбранного по умолчанию шрифта, а на выходе возвращает выбранный пользователем размер.
Color Цвет выбранного шрифта, если установлен флаг CF_EFFECT. На входе устанавливает цвет выбранного шрифта, а на выходе - цвет, выбранный пользователем.
Style Позволяет задать стиль диалога.
FontType Набор флагов, описывающих стили выбранного шрифта. Устанавливается только на выходе.
SizeMin
SizeMax
Задает минимум и максимум размера (в пунктах), который может выбирать пользователь при установке флага CF_LIMITSIZE.

Диалоговые блоки открытия файлов

Эти общие диалоговые блоки используются в различных типах приложений для открытия файлов. TOpenSaveDialog::TData имеет несколько элементов которые перед построением объекта диалогового блока нужно инициализировать. Это можно сделать присваиванием значений или с помощью конструктора TOpenSaveDialog::TData.

Элемент TData Описание
FileName Имя выбранного файла. На входе задает исполь- зуемое по умолчанию имя файла, на выходе - имя выбранного файла.
Filter Фильтры имени файла и фильтр-шаблоны имеет форму:

          фильтр фильтр шаблон ...  

где "фильтр" - это текстовая строка, описывающая фильтр, а шаблон фильтра - трафарет имени файла DOS.
CustomFile Позволяет задать специальные фильтры.
FilterIndex Определяет, какой из фильтров (Filter) следует выводить по умолчанию.
InitialDir Каталог, который должен выводиться при открытии файлового диалогового окна.
DelExt Заданное по умолчанию расширение, добавляемое к имени файла, если пользователь его не указывает.

Диалоговые блоки сохранения файла

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

Диалоговые блоки поиска и замены

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

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

TFindReplaceDialog::TData имеет стандартные элементы данных Flags, плюс элементы данных, содержащие строки поиска и замены. Так как блоки поиска и замены являются безрежимными, они взаимодействуют с объектом родительского окна, используя зарегистрированное сообщение FINDMSGSTRING. Вы должны написать функцию реакции на это сообщение. Эта функция воспринимает два параметра WPARAM и LPARAM и возвращает LRESULT. Параметр LPARAM содержит указатель, который вы должны передавать функции-элементу UpdateData.

После вызова UpdateData нужно проверить FR_DIALOGTERM. Этот флаг устанавливается, когда пользователь закрывает безрежимный диалоговый блок. При этом ваша функция реакции на событие должна обнулять указатель на объект диалогового блока, после чего вы можете строить и создавать этот объект снова.

Пока вы можете обновлять флаг FR_DIALOGTERM, вы может обрабатывать сообщение FINDMSGSTRING, выполняя фактический поиск. Это может быть простой поиск в редактирующем управляющем элементе или сложный поиск в таблице Paradox или dBASE.

Общие диалоговые блоки имеют командную кнопку Find Next (найти следующий), которую пользователи могут активизировать при выводе диалогового блока. Большинство приложений также имеют команду Find Next в меню Search, так что пользователь может найти следующее вхождение за один шаг, не открывая диалогового блока. Те же функциональные возможности предлагают TFindDialog и TReplaceDialog.

Диалоговые блоки печати

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

Элементы данных TPrintDialog::TData позволяет вам управлять внешним видом и поведением общих диалоговых окон печати.

Элемент TData Описание
FromPage Первая страница вывода, если задан флаг PG_PAGENUMS. На входе определяет заданную по умолчанию первую страницу. На выходе задает первую страницу, выбранную пользователю.
ToPage Последняя страница вывода, если установлен флаг PG_PAGENUMS. На входе определяет заданную по умолчанию последнюю страницу. На выходе задает выбранный пользователем номер последней страницы.
MinPage Наименьшее число страниц, которые может выбрать пользователь.
MaxPage Наибольшее число страниц, которые может выбрать пользователь.
Copies Число печатаемых копий. На входе задает число копий по умолчанию, на выходе - число копий, заданное пользователем.

Назад | Содержание | Вперед