Delphi XE2 та VCL Styles
Продовжуємо нехай і повільно, але правильно розглядати новинки, які нам піднесла нова версія RAD Studio – XE2. І сьогодні ми розглянемо ще одне нововведення – VCL Styles, за допомогою якого можна організувати у своїй програмі підтримку скінів. До виходу Delphi XE2 ми могли використовувати стилі оформлення двома способами: або писати свій движок для підтримки скінів (довго, витратно), або скористатися вже готовими компонентами та бібліотеками, наприклад бібліотекою AlphaControls і підтримку скінів без особливих витрат часу. З виходом Delphi XE2 потреба у сторонніх компонентах може відпасти сама собою. Зараз я не говоритиму, щось типу "VCL Styles збанкрутує розробників AlphaControls" і т.д. - тут час все розставить по своїх місцях і, гадаю, місця під Сонцем вистачить усім. Сьогодні я просто розгляну максимально ті можливості для роботи зі скінами в Delphi, які ми можемо використовувати після початку роботи з Delphi XE2.
Для включення підтримки стилів у вашому проекті Delphi необхідно зайти в налаштування проекту:
Project -> Options -> Application -> Apperance
І вибрати ті стилі, які ви хочете використати для роботи:


Після того, як вибрані необхідні стилі, їх можна буде використовувати в програмі, а також вибрати стиль, який буде використовуватися в програмі за промовчанням. Тут одразу може виникнути питання у читачів, які цінують розмір своїх програм: на скільки зросте розмір EXE-файлу при включенні стилів?
Давайте перевіримо. Створюємо порожній проект Delphi, в Project Manager вибираємо Build Configuration -> Release та збираємо проект.
У результаті отримуємо розмір EXE-файлу 1596416 байт.
Тепер заходимо налаштування, включаємо всі стилі та знову збираємо проект.
З усіма включеними стилями (13 штук) отримуємо розмір EXE-файлу рівний 2602496 байт.
Тобто одержали приріст розміру приблизно на 40%. Багато? Можливо, але можна піти іншим шляхом і використовувати стилі без зміни розміру EXE-файлу. Для цього нам необхідно трохи розібратися з тим, як підвантажуються стилі в Delphi XE2 і вивчити роботу класу TStyleManager. Клас TStyleManager
Клас TStyleManager розташовується в модулі Vcl.Themes і є sealed-класом ("запечатаним"), тобто це означає, що ви не зможете створити спадкоємця від цього класу та код виду:
type TMyManager = class(TStyleManager) private public end;
При компіляції викликає виняток: "[DCC Error] . E2353 Cannot extend sealed class 'TStyleManager'". Але, для роботи зі стилями та запечатаного класу буде цілком достатньо. Клас TStyleManager містить ряд класових властивостей та методів, за допомогою яких можна керувати стилями у вашому додатку. Розглянемо основні можливості класу, які стануть у нагоді нам у майбутньому для роботи.
Методи класу TStyleManager
class function IsValidStyle(const FileName: string): Boolean; overload; class функція IsValidStyle(const FileName: string; var StyleInfo: TStyleInfo): Boolean; overload;
Метод повертає True у випадку, якщо вказаний у параметрі FileName файл є файлом стилів. При цьому перевантажений метод IsValidStyle може повертати в другому параметрі інформацію за стилем, яка є записом виду:
Після того, як файл перевірено, його можна завантажити в менеджер. Для цього використовується метод: class function LoadFromFile(const FileName: string):TStyleServicesHandle;
Метод LoadFromFile стиль файлу і реєструє його в менеджері.
Якщо стилі зберігаються в ресурсах проекту, можна скористатися наступними двома методами для завантаження стилів:
class function LoadFromResource(Instance: HINST; const ResourceName: string): TStyleServicesHandle; overload; class function LoadFromResource(Instance: HINST; const ResourceName: string; ResourceType: PChar): TStyleServicesHandle; overload; class function TryLoadFromResource(Instance: HINST; const ResourceName: string; ResourceType: PChar; var Handle: TStyleServicesHandle): Boolean;
Останній метод поверне True, якщо стиль буде успішно завантажений із ресурсів.
Після того, як стилі завантажені їх необхідно застосувати у вашому додатку. Для цього використовуються такі два методи:
class function TrySetStyle(const Name: string; ShowErrorDialog: Boolean = True): Boolean; class procedure SetStyle(Style: TCustomStyleServices); overload; class procedure SetStyle(Handle: TStyleServicesHandle); overload;
Метод TrySetStyle намагається встановити у додатку стиль з ім'ям Name і, якщо стиль успішно застосований, то метод повертає True. Другий параметр методу (ShowErrorDialog) вказує чи виводити повідомлення про помилку в тому випадку, якщо застосування стилю провалилося. Щоб дізнатися який стиль зараз використовується, які стилі доступні і т.д. необхідно скористатися властивостями класу.
Властивості класу TStyleManager
class property ActiveStyle: TCustomStyleServices read GetActiveStyle;
Властивість повертає стиль оформлення, що використовується в даний час. class property Enabled: Boolean read GetEnabled;
Повертає True, якщо програма підтримує стилі.оформлення. class property IsCustomStyleActive: Boolean read GetIsCustomStyleActive;
Повертає True у випадку, якщо використовується стиль відмінний від дефолтного (тобто НЕ стиль Windows) class property Style[const Name: string]:
Повертає об'єкт стилю на його ім'я. class property StyleNames: TArray read GetStyleNames;
Повертає масив назв зареєстрованих стилів. class property SystemStyle: TCustomStyleServices read GetSystemStyle;
Повертає системний імідж, тобто. стиль Windows.
Є й інші методи та властивості класу TStyleManager, які теж можу виявитися корисними при роботі зі стилями VCL, але їх ми сьогодні розглядати не будемо, а перейдемо до практичної частини статті та напишемо невелику програму роботи зі стилями у ваших додатках. Використання стилів у своїх додатках
Спочатку скористаємося найпростішим способом використання стилів, тобто. включимо їх відразу ж у налаштуваннях проекту.
Створюємо новий проект, заходимо до опцій і включаємо всі стилі, як це було показано на початку статті. Тепер перерахуємо всі стилі та випишемо їх назву, наприклад, у ComboBox. Для цього нам знадобиться властивість TStyleManager.StyleNames:
procedure TForm5.FormCreate (Sender: TObject); .StyleNames[i]); cbRegistredStyles.ItemIndex:=0; end;
Так як для програми в будь-якому випадку буде зареєстровано щонайменше один стиль (Windows), то в кінці методу я вибрав найперший стиль зі списку. Тепер зробимо таке: при виборі чергового стилю спробуємо застосувати цей стиль у додатку:
procedure TForm5.cbRegistredStylesChange(Sender:TObject); begin TStyleManager.TrySetStyle(cbRegistredStyles.Items[cbRegistredStyles.ItemIndex], false); end;
Ось, власне, найпростіший спосіб використання стилів у своїй програмі. Але, як я вже сказав раніше, такий підхід збільшить розмір проекту приблизно на 40%. Тепер скористаємося іншим способом – завантаженням стилю з файлу. Будемо робити наступне: при виборі файлу зі стилем перевірятимемо його на валідність і виводитимемо по ньому всю наявну інформацію, після чого будемо заносити ім'я стилю в наш ComboBox і застосовувати його при виборі в списку.
Перш за все заходимо знову в налаштування проекту і відключаємо всі вибрані раніше стилі, щоб не нарватися на винятки типу "Такий стиль вже зареєстрований". Можна було б перевіряти унікальність імені, використовуючи все те ж властивість StyleNames, але не повторюватимемося - для прикладу можна просто убезпечити себе вимкненням стилів в налаштуваннях проекту.
Додаємо на форму такі компоненти:
- TButtonedEdit
- TOpenDialog
- та кілька міток TLabel для виведення інформації по стилю.
У мене вийшла наступна форма:

Де взяти файли зі стилями VCL? Всі існуючі в Delphi XE2 стилі розташовуються в директорії:
c:\Program Files\Embarcadero\RAD Studio\9.0\Redist\styles\vcl\.
та мають розширення *.vsf. Так що для прикладу можна скористатися цими файлами. Пишемо обробник на відкриття файлу зі стилем:
procedure TForm5.ButtonedEdit1RightButtonClick(Sender: TObject); var si: TStyleInfo; begin if OpenDialog1.Execute then if TStyleManager.IsValidStyle(OpenDialog1.FileName,si) then ButtonedEdit1.Text:=OpenDialog1.FileName; label8.Caption:=si.Name; label9.Caption:=si.Author; label10.Caption:=si.AuthorEMail; label11.Caption:=si.AuthorURL; label12.Caption:=si.Version; if TStyleManager.Style[si.Name]=nil then begin TStyleManager.LoadFromFile(OpenDialog1.FileName); cbRegistredStyles.Items.Add(si.Name); end; end else ShowMessage('Цей файл не містить стилів оформлення'); end;
Тут ми спочатку виводимо інформацію з вибраного файлу зі стилем, а потім, якщо стиль з такою назвою ще не зареєстрований, реєструємо його в менеджері та заносимо до списку.
uses. IOUtils; [. ] var FileArray:TStringDynArray; begin FileArray:=TDirectory.GetFiles(Dir,'*.vsf'); for I := 0 to Length(FileArray)-1 do if TStyleManager.IsValidStyle(FileArray[i])then FFiles.Add(FileArray[i]); end ;
Ще одним способом роботи зі стилями є їх зберігання та завантаження із ресурсів. У принципі, цей спосіб у плані реалізації не багато відрізняється від завантаження з файлу, тому загострювати на ньому увагу не будемо. Скажу тільки, що для завантаження стилю з файлу краще використовувати метод TryLoadFromResource, щоб у разі виникнення будь-яких винятків можна було їх обробити самостійно.
Перейдемо до двох питань: Де взяти файли з готовими стилями? Як створити свій унікальний стиль?
Редагування стилів. Створення власних стилів для програм, які використовують VCL.
Tools -> VCL Style Designer