- Программирование в Delphi. Трюки и эффекты Александр Чиртик, 2010
- Оглавление
- Изменение формы окна в Delphi
- Как использовать TStyleManager для изменения стандартных тем?
- Delphi XE2 и VCL Styles.
- Включаем поддержку стилей в проекте Delphi
- Класс TStyleManager
- Методы класса TStyleManager
- Свойства класса TStyleManager
- Использование стилей в своих приложениях
- Редактирование стилей. Создание собственных стилей для приложений, использующих VCL.
- Работа со свойствами объектов в редакторе стилей
Программирование в Delphi. Трюки и эффекты
Александр Чиртик, 2010
Как и все издания данной серии, эта книга адресована тем, кто хочет научиться делать с помощью уже знакомых программных пакетов новые интересные вещи. Издание будет полезно и новичкам, и опытным программистам. Автор описывает удивительные возможности, скрытые в языке, и на примерах учит читателя программистским фокусам – от «мышек-невидимок» и «непослушных окон» до воспроизведения MP3 и управления офисными программами Word и Excel из приложений Delphi. Купив эту книгу, вы пройдете непростой путь к вершинам программистского мастерства весело и интересно.
Оглавление
Приведённый ознакомительный фрагмент книги Программирование в Delphi. Трюки и эффекты предоставлен нашим книжным партнёром — компанией ЛитРес.
• Привлечение внимания к приложению
• Окна и кнопки нестандартной формы
• Немного о перемещении окон
• Добавление команды в системное меню окна
• Отображение формы поверх других окон
Почему было решено начать книгу именно с необычных приемов использования оконного интерфейса? Причиной стало то, что при работе с операционной системой Windows мы видим окна постоянно и повсюду (отсюда, собственно, и название этой операционной системы). Речь идет не только об окнах приложений, сообщений, свойств: понятие о таких окнах есть у любого начинающего пользователя Windows.
В своих собственных окнах рисуются и элементы управления (текстовые поля, панели инструментов, таблицы, полосы прокрутки, раскрывающиеся списки и т. д.). Взгляните на интерфейс, например, Microsoft Word. Здесь вы увидите, что даже содержимое документа находится в своем собственном окне с полосами прокрутки (правда, это необязательно элемент управления). Окна элементов управления отличаются от «самостоятельных» окон (упрощенно) отсутствием стиля, позволяющего им иметь заголовок, а также тем, что они являются дочерними по отношению к другим окнам. Понимание этого является важным, так как на нем основана часть примеров данной главы.
Рассматриваемые примеры частично используют средства, предусмотренные в Borland Delphi, а частично — возможности «чистого» API (см. гл. 2). Практически все API-функции работы с окнами требуют задания параметра с типом значения HWND — дескриптора окна. Это уникальное значение, идентифицирующее каждое существующее в текущем сеансе Windows окно. В Delphi дескриптор окна формы и элемента управления хранится в параметре Handle соответствующего объекта.
Нужно также уточнить, что в этой главе термины «окно» и «форма» употребляются как синонимы, когда речь идет о форме. Когда же речь идет об элементах управления, то так и говорится: «окно элемента управления».
Привлечение внимания к приложению
Начнем с простых примеров, позволяющих привлечь внимание пользователя к определенному окну приложения. Это может пригодиться в различных ситуациях: начиная от необходимости уведомления пользователя об ошибке программы и заканчивая простой сигнализацией ему, какое окно в данный момент времени ожидает пользовательского ввода.
Инверсия заголовка окна
Вероятно, вы не раз могли наблюдать, как некоторые приложения после выполнения длительной операции или при возникновении ошибки как бы подмигивают. При этом меняется цвет кнопки приложения на Панели задач, а состояние открытого окна меняется с активного на неактивное. Такой эффект легко достижим при использовании API-функции FlashWindow или ее усовершенствованного, но более сложного варианта — функции FlashWindowEx.
Здесь сказано, что функции изменяют цвет кнопки приложения на Панели задач. Однако этого не происходит при выполнении приведенных ниже примеров. Почему так получается и как это изменить, рассказано в следующем разделе этой главы (стр. 15).
Первая из этих функций позволяет один раз изменить состояние заголовка окна и кнопки на Панели задач (листинг 1.1).
procedure TForm1.cmbFlashOnceClick(Sender: TObject);
Как видите, функция принимает дескриптор нужного окна и параметр (тип BOOL) инверсии. Если значение флага равно T rue, то состояние заголовка окна изменяется на противоположное (из активного становится неактивным и наоборот). Если значение флага равно False, то состояние заголовка окна дважды меняет свое состояние, то есть восстанавливает свое первоначальное значение (активно или неактивно).
Более сложная функция FlashWindowEx в качестве дополнительного параметра (кроме дескриптора окна) принимает структуру FLASHWINFO, заполняя поля которой можно настроить параметры мигания кнопки приложения и/или заголовка окна.
В табл. 1.1 приведено описание полей структуры FLASHWINFO.
Значение параметра dwFlags формируется из приведенных ниже флагов с использованием операции побитового ИЛИ:
• FLASHW_CAPTION — инвертирует состояние заголовка окна;
• FLASHW_TRAY — заставляет мигать кнопку на Панели задач;
• FLASHW_ALL — сочетание FLASHW_CAPTION и FLASHW_TRAY;
• FLASHW_TIMER — периодически измененяет состояния заголовка окна и/или кнопки на Панели задач до того момента, пока функция FlashWindowEx не будет вызвана с флагом FLASHW_STOP;
• FLASHW_TIMERNOFG — периодически измененяет состояния заголовка окна и/или кнопки на Панели задач до тех пор, пока окно не станет активным;
• FLASHW_STOP — восстанавливает исходное состояние окна и кнопки на Панели задач.
Далее приведены два примера использования функции FlashWindowEx.
В первом примере состояние заголовка окна и кнопки на Панели задач изменяется десять раз в течение двух секунд (листинг 1.2).
procedure TForm1.cmbInverse10TimesClick(Sender: TObject);
fl.dwFlags:= FLASHW_CAPTION or FLASHW_TRAY; //аналогично FLASHW_ALL
Второй пример демонстрирует использование флагов FLASHW_TIMER и FLASHW_ STOP для инверсии заголовка окна в течение заданного промежутка времени (листинг 1.3).
//Запуск процесса периодической инверсии заголовка
procedure TForm1.cmbFlashFor4SecClick(Sender: TObject);
fl.dwFlags:= FLASHW_ALL or FLASHW_TIMER;
//Остановка инверсии и заголовка
procedure TForm1.Timer1Timer(Sender: TObject);
В данном примере используется таймер, срабатывающий каждые четыре секунды. Таймер первоначально неактивен. Конечно, можно было бы не использовать его, а просто посчитать количество инверсий, совершаемых в течение требуемого интервала времени (в данном случае четырех секунд) и задать его в поле uCount. Но приведенный пример предназначен именно для демонстрации использования флагов FLASHW_TIMER и FLASHW_STOP.
Теперь рассмотрим другой, гораздо более гибкий способ привлечения внимания к окну приложения. Он базируется на использовании API-функции SetForegroundWindow. Данная функция принимает один единственный параметр — дескриптор окна. Если выполняется ряд условий, то окно в заданным дескриптором будет выведено на передний план, и пользовательский ввод будет направлен в это окно. Функция возвращает нулевое значение, если не удалось сделать окно активным.
В приведенном ниже примере окно активизируется при каждом срабатывании таймера (листинг 1.4).
procedure TForm1.Timer1Timer(Sender: TObject);
В операционных системах старше Windows 95 и Windows NT 4.0 введен ряд ограничений на действие функции SetForegroundWindow. Приведенный выше пример как раз и является одним из случаев недружественного использования активизации окна — но это всего лишь пример.
Чтобы активизировать окно, процесс не должен быть фоновым либо должен иметь право устанавливать активное окно, назначенное ему другим процессом с таким правом, и т. д. Все возможные нюансы в пределах одного трюка рассматривать не имеет смысла. Стоит отметить, что в случае, когда окно не может быть активизировано, автоматически вызывается функция FlashWindow для окна приложения (эта функция заставляет мигать кнопку приложения на Панели задач). Поэтому даже при возникновении ошибки при вызове функции SetForegroundWindow приложение, нуждающееся во внимании, не останется незамеченным.
Обратите внимание на то, что название приложения, указанное на кнопке, расположенной на Панели задач, совпадает в названием проекта (можно установить на вкладке Application окна Project options, вызываемого командой меню Project ► Options). Но это название не совпадает с заголовком главной формы приложения. Взгляните на приведенный ниже код, который можно найти в DPR-файле (несущественная часть опущена).
В конструкторе класса TApplication, экземпляром которого является глобальная переменная Application (ее объявление находится в модуле Forms), происходит неявное создание главного окна приложения. Заголовок именно этого окна отображается на Панели задач (кстати, этот заголовок можно также изменить с помощью свойства Title объекта Application). Дескриптор главного окна приложения можно получить с помощью свойства Handle объекта Application.
Главное окно приложения делается невидимым (оно имеет нулевую высоту и ширину), чтобы создавалась иллюзия его отсутствия и можно было считать, что главной является именно форма, создаваемая первой.
Для подтверждения вышесказанного можно отобразить главное окно приложения, используя следующий код (листинг 1.5).
procedure TForm1.Button1Click(Sender: TObject);
SetWindowPos(Application.Handle, 0, 0, 0, 200, 100,
SWP_NOZORDER or SWP_NOMOVE);
В результате использования этого кода ширина окна станет равной 200, а высота 100, и вы сможете посмотреть на главное окно. Кстати, можно заметить, что при активизации этого окна (например, щелчке кнопкой мыши на заголовке) фокус ввода немедленно передается созданной первой, то есть главной, форме.
Теперь должно стать понятно, почему не мигала кнопка приложения при применении функций FlashWindow или FlashWindowEx к главной форме приложения. Недостаток этот теперь можно легко устранить, например, следующим образом (листинг 1.6).
procedure TForm1.Button2Click(Sender: TObject);
В данном случае одновременно инвертируется и заголовок окна приложения. Убедиться в этом можно, предварительно выполнив код листинга 1.5. Наконец, чтобы добиться одновременного мигания кнопки приложения на Панели задач и заголовка формы (произвольной, а не только главной), можно выполнить следующий код (листинг 1.7).
procedure TForm1.Button3Click(Sender: TObject);
Источник
Изменение формы окна в Delphi
Создание окна произвольной формы в Delphi
Здравствуйте, интересует вопрос, как сделать произвольную форму окна в Delphi посредством.
Изменение стиля формы с Delphi XE3 на Delphi 7
Сделал программу (2 месяца писал) на Delphi 7, но один раз открыл и скомпилировал её на Delphi.
Изменение формы окна
Здравствуйте! Что то после программирования на WinForms у меня несколько нескладывается понимание.
Изменение размеров окна формы
Есть кнопка, нажимаешь на неё, форма должна быть размером 10 на 15. сделала так: DoCmd.MoveSize.
Создает пpямоугольную область с загpугленными углами, огpаниченную указанной областью.
Паpаметpы:
X1, Y1: Веpхний левый угол области.
X2, Y2: Пpавый нижний угол области.
X3: Шиpина эллипса для закpугленных углов.
Y3: Высота эллипса для закpугленных углов.
Возвpащаемое значение:
В случае успешного завеpшения — идентификатоp области; 0 — в пpотивном случае.
Пример.
В FormCreate пишите:
Заказываю контрольные, курсовые, дипломные работы и диссертации здесь.
Изменение фона формы (окна) по кнопке
Доброго времени суток! Подскажите как осуществить такую задачку: Имеется форма, pictureBox и.
Изменение окна формы и добавление значений
Появилось несколько вопросов по формам. В одной форме расположены списки литературы по жанрам.
Растяжение окна формы и изменение размера компонентов
Есть значит вот такая вот программа — http://www.mediafire.com/download.php?vmynnyhgrgj Там.
Изменение формы — поставить определеный фон окна
Мне требуется поставить определеный фон на форму, то есть не внутри её, а фон окна. Подскажите, как.
Изменение системного меню (в заголовке окна) MDI-CHILD формы
Всем привет. Может кто-нибудь подсказать, как измененить системное меню MDI-CHILD формы. У.
Пропорциональное изменение размеров формы delphi
Ребят помогите. Нужно сделать пропорциональное изминение розмеров формы. если я начиною изминять.
Источник
Как использовать TStyleManager для изменения стандартных тем?
В последних версиях Delphi имеются стандартные темы в Project —> Options —> Aplications —> Appearance.
Возможно ли программно их менять (выбрать в настройках несколько), вывести список в ComboBox и после выбора нужной, нажимать на кнопку для применения.
Не смог найти примера как это сделать, да и при прописывании в Uses: Vcl.Themes — выдает ошибку.
У кого-то есть пример или объясните доходчиво как прописать все.
Как использовать API для изменения значения ключа в реестре?
Как использовать API для изменения значения ключа в реестре? Надо ли подключать dll ? и как она.
Как использовать Track bar для изменения размера image
Здравствуйте. Я начинаю обучаться на delphi и по практике мне выдали задание с помощью trackbar.
Как использовать наследников от стандартных классов? Например, CMyEdit?
Я начал изучать MFC. Программа — простой диалог со строкой ввода. Диалог со строкой ввода нарисовал.
Есть форма для добавления записи, как ее использовать и для изменения записи
Есть форма для добавления записи, хочу ее использоавть и для изменения записи. Изменить свойства.
Источник
Delphi XE2 и VCL Styles.
Продолжаем пусть и медленно, но верно рассматривать новинки, которые нам преподнесла новая версия RAD Studio – XE2. И сегодня мы рассмотрим ещё одно нововведение – VCL Styles, с помощью которого можно организовать в своей программе поддержку скинов. До выхода Delphi XE2 мы модгли использовать стили оформления двумя способами: либо писать свой движок для поддержки скинов (долго, затратно), либо воспользоваться уже готовыми компонентами и библиотеками, например библиотекой AlphaControls и поддержку скинов без особых затрат времени. С выходом Delphi XE2 потребность в сторонних компонентах может отпасть сама собой. Сейчас я не буду говорить, что-то типа “VCL Styles обанкротит разработчиков AlphaControls” и т.д. – тут время все расставит по своим местам и, думаю, что места под Солнцем хватит всем. Сегодня я просто рассмотрю максимально те возможности для работы со скинами в Delphi, которые мы можем использовать после начала работы с Delphi XE2.
Включаем поддержку стилей в проекте Delphi
Для включения поддержки стилей в вашем проекте Delphi необходимо зайти в настройки проекта:
Project -> Options -> Application -> Apperance
И выбрать те стили, которые вы хотите использовать для работы:
Для каждого выбранного стиля можно выполнить предварительный просмотр. Для этого необходимо выбрать стиль в списке и нажать “Preview…”:
После того, как выбраны необходимые стили их можно будет использовать в программе, а также выбрать стиль, который будет использоваться в программе по умолчанию. Здесь сразу может возникнуть вопрос у читателей, которые дорожат размером своих программ: на сколько возрастет размер EXE-файла при включении стилей?
Давайте проверим. Создаем пустой проект Delphi, в Project Manager выбираем Build Configuration -> Release и собираем проект.
В итоге получаем размер EXE-файла равный 1 596 416 байт.
Теперь заходим настройки, включаем все стили и снова собираем проект.
Со всеми включенными стилями (13 штук) получаем размер EXE-файла равный 2 602 496 байт.
То есть получили прирост размера примерно на 40%. Много? Может быть, но можно пойти и другим путем и использовать стили без изменения размера EXE-файла. Для этого нам необходимо немного разобраться с тем как подгружаются стили в Delphi XE2 и изучить работу класса TStyleManager.
Класс TStyleManager
Класс TStyleManager располагается в модуле Vcl.Themes и является sealed-классом (“запечатанным”), т.е это означает, что вы не сможете создать наследника от этого класса и код вида:
При компиляции вызовет исключение: “[DCC Error] …: E2353 Cannot extend sealed class ‘TStyleManager’“. Но, для работы со стилями и запечатанного класса будет вполне достаточно. Класс TStyleManager содержит ряд классовых свойств и методов, с помощью которых можно управлять стилями в вашем приложении. Рассмотрим основные возможности класса, которые пригодятся нам в будущем для работы.
Методы класса TStyleManager
Метод возвращает True в случае, если указанный в параметре FileName файл является файлом стилей. При этом перегруженный метод IsValidStyle может возвращать во втором параметре информацию по стилю, которая представляет собой запись вида:
После того, как файл проверен его можно загрузить в менеджер. Для этого используется метод:
Метод LoadFromFile стиль из файла и регистрирует его в менеджере.
Если стили сохраняются в ресурсах проекта, то можно воспользоваться следующими двумя методами для загрузки стилей:
Последний метод вернет True, если стиль будет успешно загружен из ресурсов.
После того как стили загружены их необходимо применить в вашем приложении. Для этого используются следующие два метода:
Метод TrySetStyle пробует установить в приложении стиль с именем Name и, если стиль успешно применен, то метод возвращает True. Второй параметр метода (ShowErrorDialog) указывает выводить ли сообщение об ошибке в том, случае, если применение стиля провалилось.
Чтобы узнать какой стиль в настоящий момент используется, какие стили доступны и т.д. необходимо воспользоваться свойствами класса.
Свойства класса TStyleManager
Свойство возвращает используемый в настоящее время стиль оформления.
Возвращает True, если в приложении включена поддержка стилей оформления.
Возвращает True в случае, если используется стиль отличный от дефолтного (т.е. НЕ стиль Windows)
Возвращает объект стиля по его имени.
Возвращает массив названий зарегистрированных стилей.
Возвращает системный стиль, т.е. стиль Windows.
Есть и другие методы и свойства класса TStyleManager, которые тоже могу оказаться полезными при работе со стилями VCL, но их мы сегодня рассматривать не будем, а перейдем к практической части статьи и напишем небольшое приложение по работе со стилями в ваших приложениях.
Использование стилей в своих приложениях
Вначале воспользуемся самым простым способом использования стилей, т.е. включим их сразу же в настройках проекта.
Создаем новый проект, заходим в опции и включаем все стили, как это было показано в начале статьи. Теперь перечислим все стили и выпишем их название, например, в ComboBox. Для этого нам пригодится свойство TStyleManager.StyleNames:
Так как для приложения в любом случае будет зарегистрирован минимум один стиль (Windows), то в конце метода я выбрал самый первый стиль из списка. Теперь сделаем следующее: при выборе очередного стиля попробуем применить этот стиль в приложении:
Вот, собственно, самый простой способ использования стилей в своем приложении. Но, как я уже сказал ранее, такой подход увеличит размер Вашего проекта примерно на 40%. Теперь воспользуемся другим способом – загрузкой стиля из файла. Будем делать следующее: при выборе файла со стилем будем проверять его на валидность и выводить по нему всю имеющуюся информацию, после чего будем заносить имя стиля в наш ComboBox и применять его при выборе в списке.
Прежде всего заходим опять в настройки проекта и отключаем все выбранные ранее стили, чтобы при не нарваться на исключения типа “Такой стиль уже зарегистрирован”. Можно было бы проверять уникальность имени, используя, всё то же свойство StyleNames, но не будем повторяться – для примера можно просто обезопасить себя выключением стилей в настройках проекта.
Добавляем на форму следующие компоненты:
- TButtonedEdit
- TOpenDialog
- и несколько меток TLabel для вывода информации по стилю.
У меня получилась следующая форма:
Где взять файлы со стилями VCL? Все имеющиеся в Delphi XE2 стили располагаются в директории:
c:\Program Files\Embarcadero\RAD Studio\9.0\Redist\styles\vcl\…
и имеют расширение *.vsf. Так что для примера можно воспользоваться этими файлами. Пишем обработчик на открытие файла со стилем:
Здесь мы вначале выводим информацию по выбранному файлу со стилем, а затем, если стиль с таким названием ещё не зарегистрирован, регистрируем его в менеджере и заносим в список.
В принципе, используя модуль IOUtils.pas, о котором я рассказывал в нескольких статьях блога webdelphi.ru, можно без каких-либо проблем организовать сканирование определенной директории с целью поиска файлов со стилями. Например, поиск необходимых файлов можно осуществить так:
Ещё одним способом работы со стилями является их хранение и загрузка из ресурсов. В принципе, этот способ в плане реализации не на много отличается от загрузки из файла, поэтому заострять на нем внимание не будем. Скажу только, что для загрузки стиля из файла лучше использовать метод TryLoadFromResource, чтобы в случае возникновения каких-либо исключений можно было их обработать самостоятельно.
Перейдем к следующим двум вопросам: Где взять файлы с готовыми стилями? и Как создать свой уникальный стиль?
Редактирование стилей. Создание собственных стилей для приложений, использующих VCL.
В отличие от стилей для Ribbon Controls, VCL Styles имеют свой достаточно удобный редактор, позволяющий как редактировать существующий, так и создавать собственный уникальный стиль. Редактор стилей находится в главном меню:
Tools -> VCL Style Designer
Посмотрим, что представляем из себя редактор стиля. После открытия редакторы вы увидите такое окно:
В дереве объектов можно выбрать любой объект (компонент), поддерживающий стили, в результате чего в предварительном просмотре будет показано как выглядит этот объект в данный момент, а с помощью редактора свойств можно внести необходимые изменения в стиль этого объекта.
Рассмотрим небольшой пример того как можно быстро изменить существующий VCL-стиль. Для этого нам потребуется минимум средств, а именно – любая программа для редактирования изображений, например, Paint.NET. Распишу весь процесс по шагам. Итак:
1. Заходим в главное меню редактора “Image – Export“. С помощью этого действия мы можем экспортировать изображение, использующееся для отрисовки стиля в отдельный png-файл. Задаем в открывшемся окне расположение файла и жмем “Export”:
Файл с изображение будет иметь название style.png и выглядеть следующим образом:
Как и при работе со стилями в Ribbon Controls в этом изображении содержатся все необходимые элементы для прорисовки форм и компонентов в приложении с VCL. Например, два элемента в верхнем левом углу изображения отвечают за отрисовку активной и неактивной формы.
2. Загружаем файл style.png в Paint.NET и проводим цветовую коррекцию:
Ещё одну коррекцию:
3. Сохраняем полученный файл. И импортируем его обратно в редактор. Для этого в редакторе выбираем “Image -> Update”
В открывшемся окне мы можем дополнительно указать цвет маски для изображений стиля. Для этого необходимо кликнуть по изображению слева. Можете поэкспериментировать и выбрать различные цвета для маски и увидите, что изображение справа будет изменяться в зависимости от выбранного цвета маски.
Теперь жмем “Ok” и обновляем изображение стиля.
4. Теперь в редакторе нажимаем F9 и смотрим, что получилось.
Если после обновления изображения стиль остался прежним, то необходимо в главном меню редактора выбрать “Style -> Assign Colors” и снова нажать F9.
Как видите, всего 4 шага нам потребовалось, чтобы сделать самое простейшее редактирование стиля. Конечно, таким образом можно насоздавать хоть миллион стилей различных оттенков цвета от чёрных до гламурно-розовых, но это мелочь – коррекция цвета в итоге не приводит к созданию какого-либо принципиально нового стиля. А создать уникальный стиль можно. Для этого необходимо разобраться с тем как работают различные свойства объектов, т.е. обратить свой взгляд на правый список в окне редактора.
Работа со свойствами объектов в редакторе стилей
Чтобы рассмотреть все свойства объектов в редакторе стилей, думаю, придётся создать отдельный блог =) Да это, собственно и не нужно. Рассмотрим работу со свойствами на примере отрисовки формы (TForm). Сейчас у меня под рукой файл с изображением стиля содержащий вот такой элемент отрисовки формы:
Как видите, здесь уже используются какие-то собственные элементы изображения (огонь) и просто так взять и обновить картинку стиля у нас не получится. Покажу на примере как будет выглядеть форма, если просто обновить изображение:
Видите? Огонь растянулся по всему заголовку формы. А если изменять размер формы, то появятся пиксели размером с кулак, в общем получится что-то с чем-то, но не стиль. Вот здесь-то нам и пригодятся свойства объекта.
Находим в дереве объектов “Objects -> Form -> Image -> Title” :
Теперь первое, что нам необходимо сделать – это отменить растягивание изображения заголовка и вместо этого использовать эффект “замостить”.
Для этого устанавливаем значения следующих свойств:
- BorderTitleStyle = tsTile
- TitleStyle = tsTile
Источник