Как вы, наверное, знаете, My Visual Database позволяет задавать стили оформления приложений. Стиль – это совокупность внешнего вида заголовка окна, кнопок и цветов прочих элементов пользовательского интерфейса. Стиль приложения определяется при создании приложения, выбором нужного пункта в главном меню среды разработки. Список стилей внушителен, но всё же конечен. К тому же, стиль, выбранный разработчиком, не всегда совпадает с темой оформления операционной системы, что может затруднить работу конечного пользователя.
Рассмотрим возможность программного изменения стиля оформления конечного приложения, а также расширения палитры стилей.
Теория
При выборе стиля в среде разработки, генерируется файл “style.vsf”, который располагается рядом с исполняемым файлом и содержит все необходимые сведения о выбранном стиле. Таким образом, для смены стиля достаточно заменить этот файл на нужный и перезапустить приложение. Для этого создадим папку Styles, в которую заранее поместим файлы со стилями и будем их копировать по необходимости. Мне удалось получить все 34 файла встроенных в My Visual Database стилей, но вы можете добавить свои собственные. Их можно найти в интернете или создать с помощью Delphi.
Практика
Для хранения названий стилей понадобится строковый массив, а для названия текущего стиля – строковая переменная.
var
arStyles: array[0..34] of string; // названия стилей оформления UI
currentStyleName: string; // текущий стиль
Code language: Delphi (delphi)
Выбор стиля будет расположен в главном меню, поэтому необходимо позаботиться о его доработке с помощью скрипта, который необходимо запустить в секции 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;
Code language: Delphi (delphi)
Переключение стиля реализовано в обработчике события выбора пункта меню. Сначала происходит удаление текущего файла со стилем, а затем копируется выбранный файл, после чего пользователю предлагается перезапустить программу, чтобы изменения вступили в силу.
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;
Code language: Delphi (delphi)
Для того, чтобы определить, какой именно стиль установлен в программе, соответствующая информация хранится в файле 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;
Code language: Delphi (delphi)
Результат
Смена стиля стала вопросом двух кликов в работающем приложении и не требует компиляции проекта.

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

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

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