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

В процессе написания целого цикла статей по работе с Ribbon Controls мне довольно часто приходилось отвечать на различного рода вопросы основная суть которых, по большому счёту, сводилась к примерно такому: «Почему Ribbon Controls в Delphi такие глючные и недоделанные?«. И ведь сильно-то тут и не поспоришь…Если по бОльшей части «глюков» можно было бы и поспорить, то с недоделками — врядли. Взять хотя бы сам внешний вид ленты — он изменился. Не сказать, что стал совершенно другой, но тем не менее откройте тот же Office 2007 и Office 2010 и ощутите разницу. Она есть. То есть получается, что мы в Delphi опять как бы застряли на пару лет в прошлом по части Ribbon? Оказывается, что совсем не застряли и даже более того — мы имеем возможность собирать приложения с интерфейсом «а-ля Office 2010» без использования каких-либо дорогостоящих компонентов типа DevExpress. Не верите? =) Смотрите скрин ниже:

На библиотеку, с помощью которой можно сделать такой интерфейс я наткнулся абсолютно случайно — хотел по-быстрому найти информацию по тем же Ribbon Controls и скинуть ссылочку на форум, а натолкнулся на довольно интересную библиотеку под названием «Windows Ribbon Framework for Delphi» автором которой является Erik van Bilsen. Библиотека отличная, но чтобы так прям сходу «въехать» в работу с ней — придётся плотненько подучить мат.часть по Ribbon в MSDN…ну или продолжать дальше пользоваться Ribbon Controls и ожидать. Так как в данный момент я по большей части работаю с Firemonkey (опять же конкурс новый на Delphifeeds.ru), то сегодня я расскажу про эту библиотеку совсем немного, ну, а дальше посмотрим.

[adsenseyu1]

 Итак, что нам понадобится для работы с библиотекой:

  1. ОС Windows 7. В Windows XP не пойдет.
  2. Delphi не ниже Delphi 2010.
  3. Сама библиотека и необходимые инструменты для создания Ribbon-интерфейса. Скачать их можно тут.
  4. Руки и голова с, хотя бы, основными сведениями о том, как создается Ribbon UI в Windows. Без этих знаний работа с библиотекой — темный лес.
В архиве с библиотекой вы обнаружите следующие директории:
  1. Designer — здесь содержатся исходники дизайнера Ribbon, а также в поддиректории Bin уже готовый к использованию дизайнер с необходимыми библиотеками и компилятором Ribbon (UICC.EXE)
  2. Doc — файл с лицензией и readme.txt
  3. Lib — исходники библиотеки. Путь к этой директории надо будет прописывать в настройках проекта.
  4. Samples — содержит примеры с MSDN, но портированные под Delphi.
Так как библиотека напрямую использует Windows Ribbon Framework, то стоит сказать пару слов о создании Ribbon UI вообще — так как это делается, например, при работе в C#. Создание Ribbon-интерфейса проходит следующие стадии:
  1. Разработка XML-документа, который содержит информацию по ленте и командам. Этот же файл носит название Ribbon Markup.
  2. Полученный файл необходимо указать компилятору UICC.EXE, который в итоге сформирует нам из файла разметки следующие файлы: *.h — заголовочный файл с набором команд, *.rc — файл с ресурсами ленты, *.bml — бинарник с ресурсами ленты.
А дальше? А дальше подключаете rc- или bml-файл к проекту и пишете на своем языке программирования обработчики команд, используя, константы и интерфейсы  фреймворка. И никаких Вам тут компонентов и готовых решений как в Ribbon Controls — полная свобода действий =). Сложно? А кто сказал, что миграция на новый интерфейс — это такое же плевое дело, как кинуть на форму компонент Ribbon и потом «бороться с его глюками»?
Но благо, что у Delphi-сообщества есть Erik van Bilsen, который не поленился и создал для нас вполне удобный дизайнер для создания разметки Ribbon и компиляции необходимых для Delphi библиотек и ресурсных файлов. Дизайнер содержит, конечно, не все возможные варианты элементов Ribbon UI, но, тем не менее значительно облегчает создание Ribbon Markup.
Рассмотрим работу с библиотекой Windows Ribbon Framework for Delphi на примере, который уже любезно предоставлен нам разработчиком библиотеки. Итак, выполняем всё по шагам:
Заходим в директорию Designer->Bin и запускаем RibbonDesigner.exe. Перед вами появится вот такой дизайнер:
Сейчас в нем ничего нет. Для того, чтобы создать новый проект, выбираем в главном меню File->New. Откроется окно для выбора параметров проекта:
Здесь у нас есть выбор:
  • Создать полностью пустой шаблон файла разметки
  • Создать шаблон уже содержащий команды, аналогичные командам в WordPad.
Для примера, выберем второй вариант (с командами WordPad’а) и укажем путь для сохранения необходимых файлов. Жмем «Ok» и дизайнер создаст нам необходимый файл разметки, который будет уже практически готов к использованию. Сам дизайнер пример следующий вид:
В списке слева содержится весь перечень команд для интерфейса «а-ля WordPad». Можете выбрать в списке любую команду и увидите справа всю информацию по ней, а именно:
  1. Внутреннее имя команды (Name)
  2. Подпись (Caption)
  3. Информацию по ToolTip’у для команды
  4. Изображения для команды и т.д.
На вкладке «Views» содержится вся информация по вкладкам, группам и меню нашего интерфейса:
На последней вкладке «XML Source» находится содержимое того самого файла Ribbon Markup, который мы должны бы писать ручками:
Теперь посмотрим, что нам создал дизайнер. В главном меню выбираем Project -> Preview или просто жмем F9. Перед вами появится вот такое окно с просмотром только что созданного интерфейса:
После того, как интерфейс доведен до ума и содержит всё, что нам необходимо, жмем Ctrl+F9 и дизайнер, используя компилятор UICC.EXE и компилятор Delphi соберет нам необходимые для дальнейшей работы файлы. А именно:
  • RibbonMarkup.rc — файл с ресурсами
  • Два бинарника — RibbonMarkup.bml и RibbonMarkup.dll
  • RibbonMarkup.pas — файл содержащий константы команд
  • RibbonMarkup.h — заголовочный файл
  • RibbonMarkup.xml — исходник Ribbon Markup, который впоследствии можно будет доработать, используя тот же дизайнер или ручками, если дизайнер не сможет что-то сделать.
У неподготовленного читателя сейчас может возникнуть резонный вопрос — «И чо дальше?!«. Я тоже себе подобный вопрос задавал. Куда теперь эти файлы девать? А вот дальше нам и пригодится содержимое директории Lib.
  1. Запускаем Delphi и создаем новый проект «VCL Application«.
  2. В настройках проекта указываем в Search Path путь к директории Lib
  3. Выбираем в меню «Project->Add To Project» и добавляем в проект только что собранный rc-файл. У меня этот файл носит название RibbonMarkup.rc;
Теперь нам необходимо подключить в uses следующие модули библиотеки: UIRibbon, UIRibbonForm и UIRibbonCommands. Если всё было сделано как описано выше, то при компиляции проекта никаких ошибок не возникнет. Остается последнее — указать вместо у TForm у главной формы родителя TUIRibbonForm, т.е. исходник главного модкля программы примет следующий вид:
unit uMain;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, UIRibbon, UIRibbonForm, UIRibbonCommands;
 
type
  TForm10 = class(TUIRibbonForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form10: TForm10;
 
implementation
 
{$R *.dfm}
 
end.

Теперь жмем F9 и смотрим, что получилось:

Красота. Тут вам и плавная смена цвета группы при наведении мыши и красивые разделители групп и даже смену цветовой палитры можно организовать. Короче все 33 удовольствия. Что ещё для счастья надо? Ах да, не хватает самого главного — обработчиков команд. Выглядит программка красиво, а вот полезного ничего не делает — мы ведь только «навесили» ленту и все.

Для примера, создадим какой-нибудь простенький обработчик для команды. Доступ к команде на ленте Ribbon осуществляется по её ID. ID команд содержаться в pas-файле, который сгенерировал нам дизайнер интерфейса. Подключаем модуль c ID всех команд в uses.

Для того, чтобы инициализировать какую-либо команды нам необходимо переопределить метод CommandCreated класса TUIRibbonForm. Этот метод будет выполняться сразу после того как команда будет создана на ленте Ribbon. Например, инициализируем самую первую на ленте команду «Paste». Приведу весь исходник модуля:

unit uMain;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, UIRibbon, UIRibbonForm, UIRibbonCommands;
 
type
  TForm10 = class(TUIRibbonForm)
  private
     //Action команды
     FCmdPaste: TUICommandAction;
     //переопределенный метод класса TUIRibbonForm
     procedure CommandCreated(const Sender: TUIRibbon;
      const Command: TUICommand);override;
    //обработчик события OnExecute команды
    procedure PasteExecute(const Args: TUICommandActionEventArgs);
  public
    { Public declarations }
  end;
 
var
  Form10: TForm10;
 
implementation
 
uses RibbonMarkup;
 
{$R *.dfm}
 
{ TForm10 }
 
procedure TForm10.CommandCreated(const Sender: TUIRibbon;
  const Command: TUICommand);
begin
   case Command.CommandId of
     //ID команды Paste
     CmdPaste:begin
                FCmdPaste:=Command as TUICommandAction;
                FCmdPaste.OnExecute:=PasteExecute;
              end;
   end;
end;
 
procedure TForm10.PasteExecute(const Args: TUICommandActionEventArgs);
begin
  ShowMessage('Hello World');
end;
 
end.

Теперь посмотрим, что мы здесь сделали. Начнем с переменных. Вначале мы определили переменную для действия (Action) команды:

FCmdPaste: TUICommandAction;

Не улавливаете аналогию со стандартным ActionManager в Delphi? Кстати, стандартный Action’ы эта библиотека тоже «понимает». Далее мы создали обработчик события OnExecute команды:

procedure TForm10.PasteExecute(const Args: TUICommandActionEventArgs);
begin
  ShowMessage('Hello World');
end;

И в конце переопределили метод CommandCreated в котором по CommndID «поймали» необходимую нам команду на ленте Ribbon и присвоили ей необходимый обработчик:

procedure TForm10.CommandCreated(const Sender: TUIRibbon;
  const Command: TUICommand);
begin
   case Command.CommandId of
     //ID команды Paste
     CmdPaste:begin
                FCmdPaste:=Command as TUICommandAction;
                FCmdPaste.OnExecute:=PasteExecute;
              end;
   end;
end;

Теперь запускаем программку и радуемся полученному результату:

Вот очень кратко о том, что такое Ribbon UI без Ribbon Controls. Можете скачать библиотеку и попробовать поработать с ней самостоятельно. Пока могу сказать по работе с библиотекой следующее — не нашел каким образом создавать через дизайнер DialogAction для группы и встраивать в ToolTip картинки. Может плохо смотрел. Но, при знании того как устроен Windows Ribbon Framework можно просто подредактировать XML-разметку и получить необходимый результат.

Теперь у нас на выбор есть следующие варианты работы с Ribbon в Delphi:

  1. Использовать стандартные Ribbon Controls — достаточно просто, но не лишено некоторых проблем и недоработок
  2. Использовать контролы DevExpress — намного сложнее, чем Ribbon Controls, но и качественнее и функциональнее. Плюс ко всему — дорого.
  3. Использовать только что представленную библиотеку Windows Ribbon Framework for Delphi. Бесплатно, но и без особых удобств — практически чистый API. Для полноценной работы надо будет очень плотно изучать документацию фреймворка.
Какой вариант будет вам по душе — не знаю. Я пока решил немного приостановить изучение Ribbon, но эту библиотеку на будущее запомню.

На этом всё. Спасибо за внимание. Будут вопросы — пишите комменты или задавайте вопросы через новый форум.


Если Вы вдруг решите создать свой собственный сайт про Delphi или на другую тему, то за создание сайтов Благовещенск может быть спокоен, так как специально для жителей Благовещенска работает blagoveschensk.irr.ru — создадут сайт не дорого и качественно. Ну, а я свой блог делал самостоятельно на WordPress :).

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
19 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Георгий
Георгий
23/11/2011 23:03

>В Windows XP не пойдет.
Что за прикол? Смысл её использования если есть такое ограничение?…

Георгий
Георгий
24/11/2011 14:59

Просто странно, ни DevExpress, ни TMS, ни другие Ribbon-ны для Delphi не накладывают такие ограничения (работают на любом Win, ну наверно начиная с 95)

ter
ter
24/11/2011 15:07

хех. сам недавно задумывался как сделать новый вид риббона (: тоже заходил на страничку указанного автора, и даже забегал в МСДН (: но что то как то дальше мысли о том «как?» это не ушло (:
(зы: не не, ты меня не опередил опять (: я не думал писать статей по этому поводу (: )
у указанного автора кстати вроде была как раз хорошая демка по Windows animation library с соответствующими хэдерами.

opafrost
opafrost
24/11/2011 15:20

Спасибо за находку!
А такую ленту как у офиса 2010 через этот фреймворк сделать можно? (имеется в виду прозрачные заголовки неактивных табов и т.п.)

Олег
Олег
24/11/2011 15:51

Как быть, если Ribbon нужно построить в runtime? Например, в какой-нибудь модульной системе, где каждый модуль, это вкладка, а формы модуля, это команды на вкладке. Тогда стоит задача загрузить bpl из папки, построить нужное количество вкладок с нужными названиями. Создать нужные команды на каждой вкладке. Есть ли какое-то решение используя Framework?

В TMS тоже есть Ribbon. На вид как Office 2010, не такой прожорливый как DevExpress. На счет глючности сказать ничего не могу :)

Олег
Олег
24/11/2011 16:14

«например, навесить событие BeforeRibbonConstruction (типа перед размещением команды на ленте) и уже в обработчике смотреть – строить или не строить что-то на ленте.»

:) Так не пойдет. Это мы прячем то, что есть. А нужно наоборот, добавлять, причем не известно еще что :)

Попробую поковырять…

Олег
Олег
24/11/2011 16:33

«Как быть, если Ribbon нужно построить в runtime?»

Ну вот, можно сказать в первых строках на сайте автора библиотеки:
There is no way to create ribbon controls at run-time, which also means that there is no way to design a ribbon visually in Delphi.

sw
sw
13/12/2011 23:26

(оффтоп) сдались вам эти риббон-контролы… меня от них до сих пор выворачивает :) ИМХО: мелкомягкие придумали очередную маркетинговую фишку (упор сделан на красоту, нежели на юзабельность) чтобы получать за это денюжку. А я вот до сих пор помню, как можно было ещё в старом офисе 97 года (и даже раньше) создать свою тулбару, вынести на неё ряд необходимых в данный момент функций (штуки три-четыре), и расположить тулбару как мне удобно. Скорость форматирования текста и объектов была максимальной (да-да, не для всех команд тогда были сочетания клавиш). А теперь — это просто жесть. И места в окне лента занимает гораздо больше,… Подробнее »

Русик
Русик
19/01/2012 22:53

У меня такая проблема: подключаю в delphi xe2 ribbons, на форме спокойно размещаются компоненты:Ribbon, ScreenTipsManager1, ScreenTipsPopup1. при вставке остального вылетает ошибка, которая показана на скрине. Подскажите пожалуйста в чём проблема? ОС Windows XP, но при использовании Delphi 2010 подобной ошибки не было.

Русик
Русик
21/01/2012 14:18

comment image.html
вот.

Русич Мышкин
23/01/2012 22:57

большое спасибо, а есть ли возможность что редактор скинов будет работать под  XP? если да подскажите как это сделать?

dasha
dasha
16/10/2013 14:11

При попытке компиляции проекта (и моего и Samples/Medium Level) возникает ошибка в модуле UIRibbonActions.

Грабер Граберович

Здравствуйте. Хочу сделать поисковую панель в Ribbon. Необходимо добавить контрол типа DateTimePicker. Ни за что не поверю, что нельзя разместить свой кастомный контрол на панели Ribbon. Может у кого-то есть идеи?

Также не нашёл среди стандартных контролов RadioButton (зависимый переключатель). Спасибо за любую помощь!