Как вы, наверное, знаете, My Visual Database позволяет задавать стили оформления приложений. Стиль – это совокупность внешнего вида заголовка окна, кнопок и цветов прочих элементов пользовательского интерфейса. Стиль приложения определяется при создании приложения, выбором нужного пункта в главном меню среды разработки. Список стилей внушителен, но всё же конечен. К тому же, стиль, выбранный разработчиком, не всегда совпадает с темой оформления операционной системы, что может затруднить работу конечного пользователя.
Рассмотрим возможность программного изменения стиля оформления конечного приложения, а также расширения палитры стилей.
Теория
При выборе стиля в среде разработки, генерируется файл “style.vsf”, который располагается рядом с исполняемым файлом и содержит все необходимые сведения о выбранном стиле. Таким образом, для смены стиля достаточно заменить этот файл на нужный и перезапустить приложение. Для этого создадим папку Styles, в которую заранее поместим файлы со стилями и будем их копировать по необходимости. Мне удалось получить все 34 файла встроенных в My Visual Database стилей, но вы можете добавить свои собственные. Их можно найти в интернете или создать с помощью Delphi.
Практика
Для хранения названий стилей понадобится строковый массив, а для названия текущего стиля – строковая переменная.
var arStyles: array[0..34] of string; // названия стилей оформления UI currentStyleName: string; // текущий стиль
Выбор стиля будет расположен в главном меню, поэтому необходимо позаботиться о его доработке с помощью скрипта, который необходимо запустить в секции begin end.
procedure Init; // инициализация var tmpItem: TMenuItem; tmpTopItem: TMenuItem; tmpForm: TAForm; i: integer; begin tmpForm := frmMain; // инициализация списка стилей arStyles[0] := 'По умолчанию'; arStyles[1] := 'Amakrits'; arStyles[2] := 'AmethystKamri'; arStyles[3] := 'AquaGraphite'; arStyles[4] := 'AquaLightSlate'; arStyles[5] := 'Auric'; arStyles[6] := 'Carbon'; arStyles[7] := 'CharcoalDarkSlate'; arStyles[8] := 'CobaltXEMedia'; arStyles[9] := 'CyanDusk'; arStyles[10] := 'CyanNight'; arStyles[11] := 'Glossy'; arStyles[12] := 'Glow'; arStyles[13] := 'GoldenGraphite'; arStyles[14] := 'IcebergClassico'; arStyles[15] := 'LavenderClassico'; arStyles[16] := 'Light'; arStyles[17] := 'LightGreen'; arStyles[18] := 'Lilac'; arStyles[19] := 'Luna'; arStyles[20] := 'Material'; arStyles[21] := 'MetropolisUIBlack'; arStyles[22] := 'MetropolisUIBlue'; arStyles[23] := 'MetropolisUIDark'; arStyles[24] := 'MetropolisUIGreen'; arStyles[25] := 'Obsidian'; arStyles[26] := 'RubyGraphite'; arStyles[27] := 'SapphireKamri'; arStyles[28] := 'Silver'; arStyles[29] := 'Sky'; arStyles[30] := 'SlateClassico'; arStyles[31] := 'SmokeyQuartzKamri'; arStyles[32] := 'TabletDark'; arStyles[33] := 'TabletLight'; arStyles[34] := 'TurquoiseGray'; // текущий стиль - прочитать из настройки currentStyleName := GetStrIni( 'APP', 'Style', arStyles[0] ); // создадим пункт меню верхнего уровня tmpTopItem := TMenuItem.Create( tmpForm ); tmpTopItem.Name := 'mniStyles'; tmpTopItem.Caption := 'Стили'; tmpForm.Menu.Items.Insert(1,tmpTopItem); // добавим пункты меню для смены стиля for i := 0 to Length(arStyles) - 1 do begin tmpItem := TMenuItem.Create( tmpForm ); tmpItem.Name := 'mniSetStyle_'+IntToStr(i); tmpItem.Caption := arStyles[i]; tmpItem.OnClick := @SetStyle_OnClick; tmpItem.RadioItem := True; // выделение точкой, зависимые переключатели tmpItem.GroupIndex := 1; // зависимые переключатели tmpItem.Autocheck := True; // автоматическое переключение при клике // выделить текущий стиль if arStyles[i] = currentStyleName then tmpItem.Checked := True; tmpTopItem.Insert(i,tmpItem); end; end;
Переключение стиля реализовано в обработчике события выбора пункта меню. Сначала происходит удаление текущего файла со стилем, а затем копируется выбранный файл, после чего пользователю предлагается перезапустить программу, чтобы изменения вступили в силу.
procedure SetStyle_OnClick (Sender: TObject; ); // переключение стиля var tmpItem : TMenuItem; tmpCurFile : string; tmpNewFile : string; begin tmpItem := TMenuItem(Sender); currentStyleName := tmpItem.Caption; // удаляем спецсимволы, которые добавились автоматически currentStyleName := ReplaceStr(currentStyleName,'&',''); SetStrIni( 'APP', 'Style', currentStyleName ); tmpCurFile := ExtractFilePath(Application.ExeName)+'style.vsf'; tmpNewFile := ExtractFilePath(Application.ExeName)+'Styles\'+currentStyleName+'.vsf'; // удаляем текущий стиль DeleteFile( tmpCurFile ); // копировать файл со стилем if FileExists(tmpNewFile) then CopyFile(tmpNewFile, tmpCurFile); // предупреждение if MessageBox('Для применения изменений требуется перезапуск программы. Выполнить сейчас?','Смена стиля ',MB_OKCANCEL ) = mrOK then begin frmMain.Close; // закрытие текущего приложения. На самом деле эта команда только создаёт сообщение, фактически закрытие произойдет после завершения текущей процедуры. OpenFile( Application.ExeName ); // запуск приложения end; end;
Для того, чтобы определить, какой именно стиль установлен в программе, соответствующая информация хранится в файле settins.ini, для работы с которым используются удобные процедура и функция для записи и чтения данных:
procedure SetStrIni(ASection: string; AKey: string; AVal: string); // запись единичного строкового значения в настройки var tmpIniFile: TIniFile; begin tmpIniFile := TIniFile.Create(Application.SettingsFile); tmpIniFile.WriteString(ASection, AKey, AVal); tmpIniFile.Free; end; function GetStrIni(ASection: string; AKey: string; ADefVal: string = ''): string; // чтение единичного строкового значения из настройки var tmpIniFile: TIniFile; begin tmpIniFile := TIniFile.Create(Application.SettingsFile); Result := tmpIniFile.ReadString(ASection, AKey, ADefVal); tmpIniFile.Free; end;
Результат
Смена стиля стала вопросом двух кликов в работающем приложении и не требует компиляции проекта.

Выбирайте стиль, который вам нравится.

Создавайте свои собственные стили

Послесловие
Описанный выше способ довольно простой, но, к сожалению, он не будет нормально работать, если приложение будет установлено в папку “Program Files” за изменениями которой операционная система Windows следит с особой тщательностью. Поэтому этот метод подойдет только для портабельной версии приложения.
Второе ограничение связано с тем, что не все компоненты, включенные в состав элементов пользовательского интерфейса, полностью поддерживают технологию смены стиля. Но тут уж вам решать, насколько это будет критично.
Также я рекомендую предварительно просмотреть стили, так как некоторые из них мне кажутся скучными или неудобными из-за плохой читаемости текста. Но никто не помещает создать ваш собственный, уникальный стиль!
Ещё одной проблемой может стать сочетания цвета темы и цвета картинок на кнопках, но это легко поправить, например, с помощью технологии, описанной в моей статье “Картинки на кнопках”