Учебное пособие для студентов Авторы А. Н. Вальвачев, К. А. Сурков, Д. А. Сурков, Ю. М. Четырько Содержание Содержание 1
Скачать 2.61 Mb.
|
OpenDialog и SaveDialog. Компоненты OpenDialog и SaveDialog очень схожи между собой, оба являются объектно-ориентированными оболочками стандартных диалоговых окон Windows: Open и Save. На следующем рисунке показано окно Open (рисунок 8.29). Рисунок 8.29. Стандартное окно Open для выбора открываемого файла Приблизительный сценарий работы с каждым из компонентов OpenDialog и SaveDialog таков. Компонент помещается на форму и конфигурируется для выбора тех или иных файлов. По команде меню Open... или SaveAs... у соответствующего компонента вызывается метод Execute. Он вызывает диалог и возвращает значение True, если пользователь выбрал файл. Полный маршрут к файлу запоминается в свойстве FileName. Ход дальнейших действий зависит от прикладной задачи и, как правило, включает или чтение, или запись файла, в зависимости от обрабатываемой команды меню. Придерживаясь написанного сценария, приспособим компоненты OpenDialog и SaveDialog для выбора графических файлов, поддерживаемых нашей программой. Чтобы пользователь мог просматривать файлы выборочно (какого-то одного типа) в диалоговых блоках имеется набор фильтров, оформленный в виде раскрывающегося списка с подписью Files of type (см. рис. выше). Исходные данные для этого списка устанавливаются в свойстве Filter. Номер активного в данный момент фильтра записывается в свойстве FilterIndex. Шаг 31. Приступим к формированию списка фильтров. Активизируйте на форме компонент OpenDialog и в окне свойств выберите свойство Filter (рисунок 8.30). Щелчком кнопки с многоточием откройте редактор фильтров — окно Filter Editor (рисунок 8.31). Рисунок 8.30. Нажатие кнопки с многоточием вызывает редактор фильтров Окно Filter Editor представляет собой список с двумя столбцами. В левой колонке вводится текст, отображаемый в раскрывающемся списке Filesoftype окна диалога. В правом столбце через точку с запятой записываются маски, на основании которых выполняется фильтрация файлов. Шаг 32. Установите в компоненте OpenDialog фильтры, как показано на рисунке 8.31. Рисунок 8.31. Окно для редактирования фильтров — Filter Editor Шаг 33. Аналогичным образом установите фильтры в компоненте SaveDialog. Самый простой и быстрый способ в данном случае — скопировать текст свойства Filter из компонента OpenDialog в компонент SaveDialog через буфер обмена (результат показан на рисунке 8.32): Рисунок 8.32. Фильтры для окна Save скопированы из окна Open Компоненты OpenDialog и SaveDialog имеют большое количество булевских параметров, организованных в виде составных свойств Options и OptionsEx. Эти параметры влияют на то, как окно диалога выглядит и работает. Их смысл поясняет таблица 8.7.
Таблица 8.7. Параметры компонентов OpenDialog и SaveDialog Шаг 34. В нашем простом примере ограничимся тем, что установим в компоненте SaveDialog параметр ofOverwritePrompt в значение True (см. табл. 6.6). Заметим, что проверить работу компонентов OpenDialog и SaveDialog можно с помощью команды Test Dialog. Она находится в контекстном меню значка компонента в форме. 8.2.2. Отображение рисунков Шаг 35. Ну вот, диалоговые компоненты настроены. Теперь нужен компонент, обеспечивающий отображение рисунков различных форматов. Такой компонент в среде Delphi есть, он называется Image и находится в палитре компонентов на вкладке Additional (рисунок 8.33). Выберите его из палитры и поместите на форму. Назовите новый компонент Image, а свойствам Left и Top установите значение 0. Рисунок 8.33. Компонент Image
Таблица 8.8. Основные свойства компонента Image Компонент Image позволяет отображать рисунки разных форматов: точечные рисунки (BMP), значки (ICO), метафайлы (WMF, EMF). Сам рисунок хранится в свойстве Picture. Шаг 36. Размеры установленного рисунка могут не совпадать с текущими размерами компонента. В этом случае лишняя часть изображения отсекается. Чтобы подогнать размеры компонента под размеры рисунка установите свойство AutoSize в значение True (рисунок 8.34). После этого при каждой установке свойства Picture размеры компонента (но не рисунка) будут изменяться автоматически. Рисунок 8.34. Свойство AutoSize в компоненте Image установлено в значение True Бывает и обратная ситуация, когда нужно подогнать размеры рисунка под заданные размеры компонента. Для этого свойство Stretch устанавливается в значение True, а AutoSize — в значение False. Масштабирование целесообразно применять только для векторных изображений; для точечных рисунков оно не всегда дает приятный результат — начинает сказываться точечная природа изображения. Сейчас компонент Image находится на своем месте и подготовлен к работе (свойство AutoSize имеет значение True). Рассмотрим, как осуществляется загрузка и сохранение рисунка по командам меню Open... и Save As... . Шаг 37. В исходном тексте уже имеется недописанный обработчик команды Open... . В нем нужно вызвать стандартное диалоговое окно открытия файла и загрузить рисунок в том случае, если пользователь ввел в этом окне имя файла: procedure TPictureForm.OpenMenuItemClick(Sender: TObject); begin if OpenDialog.Execute then begin Image.Picture.LoadFromFile(OpenDialog.FileName); EnableCommands(True); NormalSizeMenuItem.Click; end; end; В данном обработчике обратите внимание на вызов метода Click у компонента NormalSizeItem. Он имитирует выбор пункта меню NormalSize, чтобы сразу после загрузки рисунок имел нормальный размер. Шаг 38. Пункт меню SaveAs... еще не имеет обработчика события OnClick, поэтому вам придется его создать (напомним, что это делается в окне свойств на вкладке Events). Обработка команды Save As... состоит в вызове стандартного диалогового окна Save с последующем сохранением рисунка в файле: procedure TPictureForm.SaveAsMenuItemClick(Sender: TObject); begin if SaveDialog.Execute then Image.Picture.SaveToFile(SaveDialog.FileName); end; Шаг 39. Чтобы наш пример, наконец, заработал, осталось дописать несколько обработчиков событий. В обработчике команды меню Close добавим операторы удаления рисунка из компонента Image и уменьшения размеров компонента до нуля, чтобы в отсутствие рисунка компонент не занимал места на форме: procedure TPictureForm.CloseMenuItemClick(Sender: TObject); begin with Image do begin Picture := nil; Width := 0; Height := 0; end; NormalSizeMenuItem.Click; EnableCommands(False); end; Шаг 40. Еще остались незавершенными обработчики команд меню Half Size, Normal Size и Double Size, которые тоже нужно доработать. С ними вы легко разберетесь: procedure TPictureForm.HalfSizeMenuItemClick(Sender: TObject); begin HalfSizeMenuItem.Checked := True; HalfSizePopupItem.Checked := True; with Image do begin AutoSize := False; Width := Picture.Width div 2; Height := Picture.Height div 2; Stretch := True; end; end; procedure TPictureForm.NormalSizeMenuItemClick(Sender: TObject); begin NormalSizeMenuItem.Checked := True; NormalSizePopupItem.Checked := True; Image.AutoSize := True; // восстановить нормальные размеры компонента end; procedure TPictureForm.DoubleSizeMenuItemClick(Sender: TObject); begin DoubleSizeMenuItem.Checked := True; DoubleSizePopupItem.Checked := True; with Image do begin AutoSize := False; Width := Picture.Width * 2; Height := Picture.Height * 2; Stretch := True; end; end; В первом приближении программа для просмотра графических файлов готова. Выполните компиляцию программы и проверьте ее работоспособность. Например, откройте файл Chemical.bmp из стандартной коллекции изображений среды Delphi (C:\Program Files\Common Files\Borland Shared\Images\Splash\256Color). Вашему взору предстанет следующая картина (рисунок 8.35): Рисунок 8.35. Программа для просмотра графических файлов в работе Внимание! В каталоге C:\Program Files\Common Files\Borland Shared\Images вы найдете для своих приложений много полезных и красивых точечных рисунков, значков, курсоров. Если вы еще не исследовали этот каталог, то сделайте это с помощью своей программы. Экспериментируя с приложением, обратите внимание на способность формы прокручивать рисунки, которые в ней не умещаются. Это явление называется автоматической прокруткой. Автоматическая прокрутка не требует никаких забот со стороны программиста и очень хорошо выручает в тех случаях, когда изображение превышает размеры рабочей области формы. 8.3. Строка состояния 8.3.1. Создание строки состояния Строка состояния (status bar) — это панель в нижней части окна, предназначенная для вывода вспомогательной информации: параметров документа, с которым работает пользователь, подсказок к пунктам меню и др. В среде Delphi она организуется с помощью компонента StatusBar, расположенного в палитре компонентов на вкладке Win32 (рисунок 8.36). Шаг 41. Поместите компонент на форму и дайте ему имя StatusBar. Рисунок 8.36. Компонент StatusBar Таблица 8.9 знакомит вас с основными свойствами компонента StatusBar. Когда вы изучите компонент, она пригодится вам в качестве справочника, а сейчас просто окиньте ее взглядом и двигайтесь дальше.
Таблица 8.9. Важнейшие свойства и события компонента StatusBar Как только вы добавили на форму строку состояния, она тут же прижалась к нижнему краю формы и растянулась по всей ее ширине (см. рис. ниже). Какая сообразительная! А ну-ка изменим ширину формы. Ба! Строка состояния тоже корректирует свою ширину и всегда занимает всю нижнюю часть формы (рисунок 8.37). Рисунок 8.37. Строка состояния автоматически прижимается к нижнему краю формы Такое поведение обеспечивает свойство Align, которое в компоненте StatusBar изначально содержит значение alBottom. Свойство Align есть во многих визуальных компонентах. С его помощью вы можете заставить компонент подгонять свои размеры и положение при изменении размеров своего владельца (формы или компонента, на котором он находится). Возможные значения свойства Align описаны в таблице 8.10.
Таблица 8.10. Значения свойства Align Принимая во внимание, что некоторые компоненты могут содержать другие компоненты, становится ясно, какую мощь таит в себе свойство Align, избавляя программистов от огромной работы по перерасчету координат компонентов при изменении размеров формы. Всегда помните об этой чудесной возможности и старайтесь использовать ее в полной мере. Шаг 42. Вернемся к примеру и приспособим строку состояния для отображения размеров рисунка и имени файла, в котором рисунок хранится на диске. С этой целью разделим строку состояния на две информационные панели. Перейдите к окну свойств и в поле Panels щелкните кнопку с многоточием (либо в контекстном меню строки состояния выберите пункт Panels Editor…). Откроется специальное окно с заголовком Editing StatusBar.Panels для создания панелей в строке состояния (рисунок 8.38). Рисунок 8.38. Окно для создания панелей в строке состояния Шаг 43. В этом окне создаются, редактируются и удаляются панели строки состояния. Оно работает в паре с окном свойств, в котором настраиваются свойства отдельно взятой панели строки состояния. Нажатием кнопки Add New создайте первую панель и установите ее свойства так, чтобы она получилась шириной 70 пикселей (Width = 70), продавленной (Bevel = pbLowered) и с центрированным текстом (Alignment = taCenter). См. рисунок 8.39. Рисунок 8.39. В строке состояния создана панель В этой панели будут отображаться размеры рисунка. Аналогично создайте вторую панель (рисунок 8.40) неограниченной ширины (Width = -1), продавленной (Bevel = pbLowered) и с прижатым влево текстом (Alignment = taLeftJustify). В ней будет отображаться имя файла. Рисунок 8.40. В строке состояния создана еще одна панель После этого закройте окно Editing StatusBar.Panels. Строка состояния создана и сейчас рассмотрим, как вывести в ней текст. Доступ к панелям обеспечивает свойство Panels. Оно содержит массив Items, элементами которого являются объекты-панели. Каждая панель имеет свойство Text, в котором хранится отображаемый на панели текст. Итак, установка содержимого строки состояния в нашем примере будет выглядеть так: StatusBar.Panels.Items[0].Text := Format('%d x %d', [Image.Picture.Width, Image.Picture.Height]); StatusBar.Panels.Items[1].Text := OpenDialog.FileName; Учитывая, что массив Items выступает главным свойством объекта Panels, эти операторы можно записать короче: StatusBar.Panels[0].Text := Format('%d x %d', [Image.Picture.Width, Image.Picture.Height]); StatusBar.Panels[1].Text := OpenDialog.FileName; Для вывода информации на первую панель (с индексом 0) мы воспользовались функцией Format, форматирующей строку. Первый параметр функции — это строка-шаблон, а второй — открытый массив с аргументами, подставляемыми вместо управляющих символов строки-шаблона. Шаг 44. Обновление строки состояния удобно оформить в виде метода формы: procedure TPictureForm.UpdateStatusBar; begin if Image.Width <> 0 then begin StatusBar.Panels[0].Text := Format('%d x %d', [Image.Picture.Width, Image.Picture.Height]); StatusBar.Panels[1].Text := OpenDialog.FileName; end else // в компоненте Image нет рисунка begin StatusBar.Panels[0].Text := ''; StatusBar.Panels[1].Text := ''; end; end; Шаг 45. Вызовы метода UpdateStatusBar поместите в обработчики команд меню Open... и Close. procedure TPictureForm.OpenMenuItemClick(Sender: TObject); begin if OpenDialog.Execute then begin Image.Picture.LoadFromFile(OpenDialog.FileName); EnableCommands(True); NormalSizeMenuItem.Click; end; UpdateStatusBar; end; procedure TPictureForm.CloseMenuItemClick(Sender: TObject); begin with Image do begin Picture := nil; Width := 0; Height := 0; end; NormalSizeMenuItem.Click; EnableCommands(False); UpdateStatusBar; end; Наконец выполните компиляцию приложения и проверьте, что строка состояния работает. Например, откройте файл Chemical.bmp, расположенный по маршруту C:\Program Files\Common Files\Borland Shared\Images\Splash\256Color. В строке состояния отобразятся размеры рисунка и путь к файлу. Рисунок 8.41. Программа для просмотра графических файлов теперь имеет строку состояния 8.3.2. Подсказки в строке состояния Как вы хорошо знаете, строка состояния — это еще стандартное место отображения подсказок к пунктам меню. Сейчас самое время заняться этим вопросом. Вспомните, как работает строка состояния вашего любимого текстового процессора. Когда вы активизируете меню, строка состояния, состоящая из нескольких панелей, превращается в простую длинную панель и на ней отображается подсказка текущего пункта меню. Когда вы завершаете работу с меню (например, выбираете команду), строка состояния восстанавливает свой первоначальный вид. Для того чтобы вы могли получить строку состояния с описанной выше логикой работы, в компоненте StatusBar предусмотрен режим отображения простого текста. Его обеспечивает булевское свойство SimplePanel. По умолчанию оно равно значению False и в строке состояния отображаются панели объекта Panels. Если установить свойство SimplePanel в значение True, то в строке состояния будет отображаться текст, хранящийся в свойстве SimpleText. Итак, задача состоит в том, чтобы при активизации меню записывать подсказку выбранного пункта в свойстве SimpleText и, в том случае если подсказка содержит текст, устанавливать свойство SimplePanel в значение True. Для решения этой задачи вы должны представлять механизм работы подсказок. Его суть состоит в следующем. Каждый пункт меню имеет свойство Hint для хранения подсказки. Когда вы выделяете пункт меню с помощью мыши или клавиатуры, текст подсказки переписывается из пункта меню в объект Application, у которого тоже есть свойство Hint. При этом в объекте Application возникает событие OnHint. Все, что нам нужно — написать обработчик этого события, который отобразит значение свойства Hint объекта Application в строке состояния. Объект Application не виден в окне свойств, но вы можете получить доступ к его событиям на этапе проектирования. Для этого в форму помещается специальный компонент ApplicationEvents, который вы найдете в палитре компонентов на вкладке Additional (рисунок 8.42). Рисунок 8.42. Компонент ApplicationEvents Шаг 46. Поместите на форму компонент ApplicationEvents. Дайте ему имя ApplicationEvents. Обратите внимание, что у этого компонента всего два свойства: Name и Tag. Это не удивительно, так как основное назначение компонента — представить события объекта Application (таблица 8.11).
Таблица 8.11. События компонента ApplicationEvents Шаг 47. В окне свойств переключитесь на вкладку Events, найдите событие OnHint и создайте следующий обработчик: procedure TPictureForm.ApplicationEventsHint(Sender: TObject); begin with StatusBar do begin SimpleText := Application.Hint; SimplePanel := SimpleText <> ''; end; end; Шаг 48. Теперь в свойстве Hint каждого пункта меню впишите угодную вам строку-подсказку (рисунок 8.43). Рисунок 8.43. Подсказка для пункта меню Шаг 49. Выполните компиляцию и запустите программу. Проверьте работу механизма подсказок в строке состояния (рисунок 8.44). Рисунок 8.44. Программа для просмотра графических файлов теперь показывает подсказки для пунктов меню в строке состояния Если критически взглянуть на нынешний вариант программы, то среди прочих мелких замечаний выделяется существенный недостаток: форма неправильно прокручивает свое содержимое, когда размеры рисунка превышают размеры формы. Дело в том, что в прокрутке участвует и строка состояния, а этого быть не должно. Строка состояния должна оставаться на своем месте, прижимаясь к нижнему краю формы. Чтобы разобраться с этой проблемой, читайте следующий параграф. 8.4. Прокрутка 8.4.1. Прокрутка рабочей области формы На практике часто бывает, что отображаемая информация не умещается на форме целиком (даже если форма раскрыта на весь экран). Например, в нашем примере можно загрузить рисунок, размеры которого превосходят размеры формы (и даже всего экрана) в несколько раз. Лучшее, что можно предпринять в таком случае, — это организовать прокрутку (scrolling) рисунка внутри формы. В области прокрутки видна только часть всей картины. Доступ к скрытым частям происходит с помощью полос прокрутки. Щелчок мыши на стрелке полосы прокрутки сдвигает изображение на одну "информативную строку", а щелчок мыши на самой линейке прокрутки (но не на бегунке) сдвигает изображение на одну "информативную страницу" (понятия строки и страницы существуют для прокрутки и по вертикали, и по горизонтали). Перемещая бегунок, можно быстро прокрутить изображение на любое число информативных строк или страниц. Форма имеет встроенную поддержку прокрутки, благодаря чему реализуется просмотр содержимого формы при любом изменении ее размеров. Когда размеры или координаты компонентов превышают размеры формы, форма создает полосы прокрутки и пользователь получает возможность прокручивать изображение. Встроенные в форму полосы прокрутки представлены составными свойствами HorzScrollBar (горизонтальная полоса прокрутки) и VertScrollBar (вертикальная полоса прокрутки). Они кратко описаны в таблице 8.12.
Таблица 8.12. Составные свойства HorzScrollBar и VertScrollBar Наибольший интерес представляют вложенные свойства Tracking и Increment. Установка булевского свойства Tracking в значение True обеспечивает прокрутку изображения по мере передвижения бегунка с помощью мыши. Свойство Increment задает величину "информативной строки" в пикселях. Уменьшив это значение до 1, вы получите более плавную прокрутку. 8.4.2. Отдельная область прокрутки Как ни крути, а форма не позволяет организовать прокрутку в отдельной своей части. Например, в приложении для просмотра графических файлов хотелось бы организовать прокрутку рисунка, но так, чтобы строка состояния в прокрутке не участвовала. Форма этого сделать не позволяет. Здесь на помощь приходит компонент ScrollBox, представляющий собой отдельную область прокрутки. Он расположен в палитре компонентов на вкладке Additional (рисунок 8.45). Рисунок 8.45. Компонент ScrollBox Таблица 8.13 содержит краткую характеристику его отличительных свойств.
Таблица 8.13. Важнейшие свойства компонента ScrollBox Компонент ScrollBox служит контейнером для других компонентов и обеспечивает их прокрутку внутри себя. Давайте поместим на него рисунок (компонент Image), а область прокрутки расположим между меню и строкой состояния. В результате большие рисунки будут прокручиваться уже не формой, а компонентом ScrollBox и строка состояния останется на своем месте, прижатой к нижнему краю формы. Шаг 50. Выделите на форме компонент Image и временно удалите его в буфер (команда меню Edit | Cut). Теперь опустите на форму компонент ScrollBox, выбрав его из палитры компонентов. Назовите новый компонент ScrollBox и подгоните его под всю незанятую область формы, установив свойство Align в значение alClient (рисунок 8.46). Рисунок 8.46. Свойство Align обеспечивает подгонку компонента под размеры контейнера Шаг 51. А сейчас переключитесь на форму (так, чтобы компонент ScrollBox остался выделенным) и вставьте из буфера обмена компонент Image (команда меню Edit | Paste). Убедитесь, что он находится в левом верхнем углу области прокрутки. Готово. Выполните компиляцию и запустите приложение, загрузите в него какой-нибудь рисунок из каталога C:\Program Files\Common Files\Borland Shared\Images\Splash\256Color. Увеличивая и уменьшая окно, понаблюдайте за тем, как появляются и исчезают полосы прокрутки между меню и строкой состояния (рисунок 8.47). Обратите внимание, что величина бегунков на полосах прокрутки зависит от соотношения видимой части и всего изображения. Это работает компонент ScrollBox. Правда, здорово! А самое главное — быстро и без единой строчки кода. Рисунок 8.47. Программа для просмотра графических файлов теперь умеет прокручивать не уместившееся внутри окна изображение 8.4.3. Полосы прокрутки Коль уж речь зашла о прокрутке, сделаем небольшое отступление и скажем пару слов о компоненте ScrollBar. Вы, наверное, еще раньше заметили его в палитре компонентов на вкладке Standard и сейчас не совсем понимаете, для чего он нужен (рисунок 8.48). Рисунок 8.48. Компонент ScrollBar |