уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

«Прямо и не знаю, что об этом думать»,
как сказал король Дезмонд, когда его прихватили на шулерстве
(с)Анджей Спаковский, «Ведьмак»  часть 7 «Владычица Озера»

Продолжаем копошиться в дебрях и хитросплетениях Ribbon Controls. Сегодня на повестке дня настройка Ribbon Controls для русскоязычного населения плюс немного креатива в плане создания своих тем оформления для Ribbon Controls.
Помниться у кого-то из читателей блога возникал вопрос «Как руссифицировать меню Costumize Dialog?» . Давайте разбираться. Ведь ни с потолка же падают строки и вставляются сами в менюшку?
Самый простой способ решения подобных вопросов – это заглянуть в папку

C:\Program Files\Embarcadero\RAD Studio\7.0\lib\

и посмотреть модуль с названием, наподобие RibbonSrt или RibbonConst. Ведь разработчики должны соблюдать все правила написания программного кода, в том числе и избегать использования строковых и, по возможности, других констант в телах процедур и функций. Открываем папку и действительно наблюдаем там замечательный файлик RibbonConsts.dcu. Одноименный файл, но с расширением *.pas находится в папке

C:\Program Files\Embarcadero\RAD Studio\7.0\source\Win32\vcl\

Перетаскиваем RibbonConsts.pas себе в проект, подключаем в uses и открываем в редакторе кода. Теперь все, что от нас требуется – это грамотно и без ошибок перевести на русский язык все, содержащиеся в модуле строки. Там их немного – всего двадцать четыре штучки.
После руссификации модуля меню будет выглядеть примерно следующим образом:

Как видите, всё просто и не требует особых программистских способностей. Только уменя пользоваться переводчиком.
А теперь переходим к вопросу, которым я, ради собственного нездорового интереса, сейчас сижу и занимаюсь на работе (только бы не пришло начальство), а именно – изменение внешнего вида Ribbon. Или, говоря более понятным языком – создание собственных тем оформления для Ribbon Controls. Неуверен, что смогу так вот сходу за несколько часов во всём разобраться, да ещё и расписать в блоге, но постараюсь выложить как можно больше информации, если что – надеюсь на Вашу помощь в освоении темы. Итак поехали.

Ribbon Skins в Delphi 2010



Начнем изучение темы с того, что наиболее просто – цветовые схемы. В Delphi уже изначально есть три готовых компонента для цветовых схем:

  • XPColorMap
  • StanderdColorMap
  • TwilightColorMap

Попробуем применить их на практике. По логике вещей и, судя по названию свойств у компонентов, в зависимости от цветовой схемы должны меняться цвета шрифтов и тени компонентов как минимум. Проверим на практике. Размещаем на форме, как обычно: ActionManager и Ribbon. Создаем парочку Action в менеджере, у риббона создаем один Tab и две группы (а можно и одну – как Вам угодно) и размещаем в группах наши Action’ы.
Теперь кидаем на форму простой ComboBox, все три доступные цветовые схемы и кнопку. У меня получилась вот такая неказистая формочка:

Теперь добавляем в ComboBox три строки, каждая из которых будет описывать одну из цветовых схем и в обработчике клика по кнопке пишем следующий код

[]
case ComboBox1.ItemIndex of
  0:Ribbon1.ColorMap:=XPColorMap1;
  1:Ribbon1.ColorMap:=StandardColorMap1;
  2:Ribbon1.ColorMap:=TwilightColorMap1;
end;
Ribbon1.Repaint:
[]

Запускаем приложение и проверяем, что получилось. Порадовало, что цвета шрифтов сменились:

Не порадовал глюк с панелью быстрого запуска – обратите на него внимание. Причём как оказалось глюк этот не пропадает даже если перезагрузить Delphi…хотя это может только на рабочей машинке глюк – дома проверю наверняка. А пока продолжим.
Сейчас мы рассмотрели один из вариантов смены цветовой схемы – с использованием стандартных, уже долгое время существующих компонентов цветовых схем.
Но у Ribbon также есть и свой тип TcustomRibbonColorMap в модуле Ribbon. Можно, да и видимо, нужно использовать этот тип данных при работе с цветовыми схемами Ribbon. Попробуем применить его.
После недолгих манипуляций с мышкой форма приложения приняла следующий вид:

Каждый из новых ColorBox будет описывать значение цвета для одного из свойств TcustomRibbonColorMap.
Дописывем обработчик события кнопки:

[]
var Ribbon: TCustomRibbonColorMap;
begin
case case ComboBox1.ItemIndex of
[]
3: begin
      Ribbon:=TCustomRibbonColorMap.Create(self);
      With Ribbon do
        begin
          BevelMinimizedInner:=ColorBox1.Selected;
          BevelMinimizedOuter:=ColorBox2.Selected;
          BtnSelectedFont:=ColorBox3.Selected;
          CaptionFontColor:=ColorBox4.Selected;
          ControlColor:=ColorBox5.Selected;
          ControlInactiveColor:=ColorBox6.Selected;
          ControlFrameColor:=ColorBox7.Selected;
          DisabledFontColor:=ColorBox8.Selected;
          DocumentFontColor:=ColorBox16.Selected;
          FontColor:=ColorBox15.Selected;
          HighlightColor:=ColorBox14.Selected;
          ActiveTabFontColor:=ColorBox13.Selected;
          GroupFontColor:=ColorBox12.Selected;
          InactiveTabFontColor:=ColorBox11.Selected;
          QuickAccessToolbarMoreColor:=ColorBox10.Selected;
          QuickAccessToolbarMoreBorderColor:=ColorBox9.Selected;
  end;
  Ribbon1.ColorMap:=Ribbon;
end;
end;
[]
end;

И теперь можем экспериментировать с цветовой схемой Ribbon сколько нашей душе угодно, подбирать свои цвета шрифтов и т.д. Например, я собрал вот такую «тошнотную» схемку:

Жуть, неправда ли? Но это проcто пример. А у нас остался ещё один открытый вопрос: как сменить не только цвет шрифта, но и тему оформления целиком? Ведь если просто прикинуть, сколько людей купили RAD Studio 2009-2010, сколько используют или пробуют использовать Ribbon Controls? И на всех всего 3 темы. Несерьёзно. Надо как-нибудь выделиться, создать что-то свое (на крайняк – купить за N зелёных енотов).
Благо разработчики из Embarcadero оставили нам возможность немного покреативить в свое удовольствие.
Судя по рисунку выше, креативщик из меня хреновенький, но я все-таки попробую. Первое, что следует сделать – понять каким образом и, самое главное, откуда беретя это красивое оформление панелей, менюшек и табов. Я решил оттолкнуться в своих поисках от модуля RibbonLunaStyleActnCtrls и поиски в итоге привели к следующему классу:

TCustomRibbonSkin = class
public
  type  TRibbonSkinLoadType = (ltResource, ltFile);
private
  FBitmap: TAlphaBitmap;
protected
  procedure DoLoadByResource; virtual;
  procedure DoLoadByFile; virtual;
public
  constructor Create; virtual;
  destructor Destroy; override;
  function GetLoadType: TRibbonSkinLoadType; virtual;
  function GetResourceHandle: THandle; virtual;
  function GetLoadTypeValue: string; virtual;
  procedure LoadSkin; virtual;
  property Bitmap: TAlphaBitmap read FBitmap;
end;

Получается с какого стиля оформления мы бы не начинали свои поиски – всё упрётся именно в этот класс. Как видите у этого класса не так уж и много свойств и методов.
С типом TribbonSkinLoadType всё вполне понятно – определяет откуда будет загружаться скрин: из ресурсного файла или же из файла на диске.
Далее одно единственное поле: FBitmap: TalphaBitmap – собственно это и есть файл с необходимыми изображениями для скина.
Следом идут два метода, которые срабатывают соответственно в зависимости от того откуда будет загружаться скин.
Но самое замечательное – это открытое для чтения свойство Bitmap. Помниться ещё когда у меня стояла Delphi 2009 я немог найти толком информации о расположении всех графических элементов в битмапе…надо было сразу искать здесь. Но это всё лирика. Давайте посмотрим как выглядит файл с элементами скина для Ribbon.
Возвращаемся к нашему приложению, бросаем на форму ещё одну кнопку, SaveDialog и пишем в свойстве Caption у кнопки «Сохранить скин», а в обработчике такой код:

[]
if SaveDialog1.Execute then
  Ribbon1.Style.RibbonSkin.Bitmap.SaveToFile(SaveDialog1.FileName);
[]

Теперь мы можем воочую взглянуть на битмап скрина Ribbon и состряпать свой по образу и подобию. Файл весит не много ни мало 1056kb поэтому ради иллюстрации я приведу сжатый в gif и уменьшенный немного по размеру рисунок. Вот он:

Так как я не дизайнер и в PhotoShop практически ничего не соображаю, то ради эксперимнта я раскрасил немного некоторые области, дабы видеть что у меня получилось загрузить свой скин в программу. Теперь приступаем к фазе №2 – пишем свой модуль для загрузки скина.
Вы обращали внимание, что после первой же компиляции проекта с Ribbon в uses появляется как минимум один дополнительный модуль RibbonLunaStyleActnCtrls? Вот такой же самый модуль мы и будем писать.
Создаем пустой модуль и даем ему какое0нибудь громогласное название, например: RibbonMegaStyleActnCtrls. Сразу в uses подключаем три модуля: ActnMan, RibbonStyleActnCtrls и Ribbon. А также объявляем одну константу:

const LoadType: TCustomRibbonSkin.TRibbonSkinLoadType = ltFile;

То есть договариваемся, что самодельный скин будем грузить из bmp-файла. Теперь обявляем такой класс:

type
TRibbonMegaStyleActionBars = class(TRibbonStyleActionBars)
public
  function GetColorMapClass(ActionBar: TCustomActionBar):   TCustomColorMapClass; override;
  function GetSkinClass: TCustomRibbonSkinClass; override;
  function GetStyleName: string; override;
end;

и расписываем его методы:

implementation
 
uses
ActnMenus, SysUtils;
 
function TRibbonMegaStyleActionBars.GetColorMapClass(
ActionBar: TCustomActionBar): TCustomColorMapClass;
begin
  Result := TRibbonLunaColorMap;
end;
 
function TRibbonMegaStyleActionBars.GetSkinClass: TCustomRibbonSkinClass;
begin
  Result := TRibbonMegaSkin;
end;
 
function TRibbonMegaStyleActionBars.GetStyleName: string;
begin
  Result := 'Ribbon - Mega'; // русскими буквами не писать!
end;

Обратите внимание на первый метод – я использовал уже готовую цветовую схему от скина Luna, чтобы сильно не забивать пост лишними строками кода, Вы же можете определить в своем модуле собственную цветовую схему для скина, полагаю, что много времени это не займёт.

Теперь создаем класс для нашего скина, который будем использовать в программе:

TRibbonMegaSkin = class(TCustomRibbonSkin)
public
  function GetLoadTypeValue: string; override;
  function GetLoadType: TCustomRibbonSkin.TRibbonSkinLoadType; override;
end;

Методы опять же просты и неказисты (дли примера):

function TRibbonMegaSkin.GetLoadType: TCustomRibbonSkin.TRibbonSkinLoadType;
begin
  Result := LoadType; //использовали нашу константу
end;
function TRibbonMegaSkin.GetLoadTypeValue: string;
begin
  Result := ExtractFilePath(ParamStr(0)) + 'mega.bmp'; //указали расположение файла
end;
end;

Если не устраивает то, что скин будет лежать прямо рядом с исполняемым файлом – нет проблем, укажите свой путь. А нам остается только зарегистрировать наш новый скин и вовремя его выгрузить. Не будем опять же изобретать велосипед (тем более, что на скорую руку он может получиться далеко не с круглыми колесами), а пишем тоже самое, что и для стандартных скинов в секциях initialization и finalization:

initialization
RibbonMegaStyle := TRibbonMegaStyleActionBars.Create;
RegisterActnBarStyle(RibbonMegaStyle);
 
finalization
UnregisterActnBarStyle(RibbonMegaStyle);
RibbonMegaStyle.Free;

Да и незабудьте перед implementation объявить глобальную переменную:

var
RibbonMegaStyle: TRibbonMegaStyleActionBars;

Теперь подключаем наш модуль в uses и в любом удобном для вас обработчике пишем:

[]
  Ribbon1.Style:=RibbonMegaStyle;
  Ribbon1.Repaint;
[]

Я добавил эти строки в обработчик кнопки для применения цветовой схемы. Вот какой вид приняла моя программа после того как я поиздевался над скином:

Жутко некрасиво, но зато ярко и сразу видно, что кто-то нарочно изуродовал Ribbon.
На сегодня всё. В качестве бонуса к посту прилагается та самая программка, которую я писал по ходу дела работы над статьей. В архиве с программой вы найдёте также её исходники, включая модули RibbonConsts (с одной переведенной строкой) и модулем тестового скина, который, в случае чего, избавит Вас от лишней писанины – просто поменяете путь и название файла и скин готов.

А вот и сам архив.

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
43 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
bambarmia
bambarmia
13/01/2010 21:56

Низкий поклон автору и всех благ в наступающем старом новом году))) материал особенно ценен тем, что методом научного тыка до подобного недопетрить, а если не секрет, что служило первоисточником?

Дмитрий
Дмитрий
19/01/2010 12:07

Здравствуйте, Vlad.
Скажите, пожалуйста, можно ли изменить высоту элементов в Application Menu?

Дмитрий
Дмитрий
20/01/2010 07:51

Спасибо.
Хотелось бы, конечно, полноценные элеметы меню.
Ещё вопрос. Изменение ширины Application Menu.
А то добавляю длинные строки, а они не помещаются и ширина меню не увеличивается.

~AquaZ~
21/01/2010 17:18

Здравствуйте, Vlad. Респект за все 4 статьи! У меня вот два вопроса дурацких возникло. 
Во-первых, как использовать класс RibbonMegaStyleActnCtrls :)  в Си++?
И во-вторых, (у меня Win 7) ваши Delphi- приложения — с прозрачной строкой заголовка, а мои Builder-приложения — нет. Почему мир так жесток?

~AquaZ~
21/01/2010 19:59

Спасибо, пороюсь… Ещё вопросик: какой параметр отвечает за цвет на изломе элемента меню и стрелочки справа, ведущей на sub-menu (в главном меню)?

~AquaZ~
21/01/2010 20:15

А насчёт прозрачности — я нашёл только про изображения, что решается указанием у ImageList ColorDepth = cd32Bit. А я про строку заголовка в стиле Vista. Хотя мне это не так важно…

~AquaZ~
21/01/2010 20:52

А какие проблемы с авторизацией?

vitek_tlt
vitek_tlt
29/01/2010 16:20

Спасибо за статьи я тут покряхтел и собрал воедино все 4 шага в Ворде 2010, куда их выложить?

vitek_tlt
vitek_tlt
29/01/2010 16:22

Можешь их и отредактировать если что то не то

vitek_tlt
vitek_tlt
29/01/2010 19:41

Отправил!!! отредактированый если сможешь отправь на мой ящик vitek_tlt@mail.ru

Дмитрий
Дмитрий
10/02/2010 08:37

Никак не могу заставить показываться Hints у элементов Aplication Menu.
Буду благодарен за помощь.

Дмитрий
Дмитрий
10/02/2010 12:15

для recent items  — достаточно стандартных
для элементов слева — можно и ScreenTips
 

regs
regs
12/07/2010 14:49

Пытаюсь тут перенести скин Офиса 2010 в это дело. Если бы только не несколько проблем, то в принципе получается достаточно хорошо. Кнопочки, радиобоксы, сепараторы ещё не перенёс. Пока попробовал вкладки, фон и чекбоксы. Но если чекбоксы идеально наложились, то с фонами груб, страницы и вкладок возникли проблемы. Под активной вкладкой проявляется линии. Альфа каналы подправил, так что теоретически её быть не должно. А в начале групп появляется артефакт. Чем дальше группа — тем больше артефакт.
s005. radikal .ru/i212/1007/4e/ff774e03f8be.png

бипшка
slil .ru/29455498

есть какие-нибудь идеи как решить проблему?

Дмитрий
Дмитрий
01/10/2010 20:19

У меня очень итересний вопрос!!!! Возможно ли както изменить стиль СТРОКИ СОСТОЯНИЯ как у ВОРД-а заокруглиными углами?

Дмитрий
Дмитрий
01/10/2010 21:08

Привет, а не мог бы ты мне рассказать как примерно? заранее спасибо!!!!!
Или какие то статьи в кинуть!

Дмитрий
Дмитрий
01/10/2010 22:04

На фотошопе я сам нарисую, мне интересно как обратиться к скину Строки состояния!!!!

Дмитрий
Дмитрий
01/10/2010 22:39

В папке C:\Program Files\CodeGear\RAD Studio\6.0\source\Win32\vcl нету такого файла
у меня 2009 год

Дмитрий
Дмитрий
01/10/2010 22:48

2010?

Дмитрий
Дмитрий
01/10/2010 22:57

Delphi Prism 2011  с Visual Studio 2010?

Дмитрий
Дмитрий
01/10/2010 23:03

Я нашол тторент почти 2 гб, тебе кинуть торрент?

Дмитрий
Дмитрий
01/10/2010 23:13

Инсталяха есть?

Дмитрий
Дмитрий
01/10/2010 23:27

Я себе скачаю пиратку, у меня еще один вопрос, както я спрашивал как разширить меню главное, можно както?

trackback

[…] отличие от стилей для Ribbon Controls, VCL Styles имеют свой достаточно удобный редактор, […]