Watch, Follow, &
Connect with Us

Fire Monkey - Yaroslav Brovin

Создание нативных представлений для iOS. TSpinBox и UIStepper. Часть 3

Продолжим рассмотрение нового подхода разработки (1 часть, 2 часть) и в этой статье рассмотрим использование нативных контролов на базе механизма презентаций для iOS. В качестве примера мы превратим TSpinBox в нативный для iOS.

Полная статья доступна здесь

Posted by Yaroslav Brovin on April 15th, 2015 under Firemonkey (RUS) | Comment now »


New approach of development of FireMonkey control "Control — Model — Presentation". Part 2. TEdit with autocomplete

We will continue a subject of the review of new approach on division of a control into the model and presentation described here. And in this article we will consider practical uses of this approach on the example autocompletion of input in TEdit.

Full article is available here

Posted by Yaroslav Brovin on April 9th, 2015 under Uncategorized | 2 Comments »


[XE6, XE7] New approach of development of FireMonkey control “Control – Model – Presentation”. Part 1

I would like to tell you about new approach in components development in Firemonkey,  which is used for visual component, which support several implementation in one platform. We are gonna talk about advantages and opportunities of new approach for creating visual component.

Full article is available here

Posted by Yaroslav Brovin on April 3rd, 2015 under Firemonkey (ENG) | Comment now »


Все о новом подходе разработки компонентов FireMonkey “Контрол – Модель – Презентация”. Часть 2. TEdit с автозавершением

Продолжим тему обзора нового подхода по разделению контрола на модель и презентацию, описанную здесь. И в этой статье рассмотрим практическое применение этого подхода на примере добавления функции авто завершения ввода в TEdit.

Read the rest of this entry »

Posted by Yaroslav Brovin on March 27th, 2015 under Firemonkey (RUS) | 6 Comments »


Все о новом подходе разработки компонентов FireMonkey “Контрол – Модель – Презентация”. Часть 1

В этой статье я хочу рассказать вам о новом подходе к разработке компонентов в FireMonkey, используемом для контролов, поддерживающих несколько вариантов реализаций в рамках одной платформы. Поговорим о достоинствах и возможностях нового подхода, открывающихся для разработчиков.

Read the rest of this entry »

Posted by Yaroslav Brovin on March 25th, 2015 under Firemonkey (RUS) | 1 Comment »


#1. Tips and tricks in FireMonkey

I would like to suggest your set of links about frequent firemonkey questions

1. Logging in Firemonkey on all mobile platforms

Detail reviewing of all methods of logging in FireMonkey for iOS and Android.

2. How to delete control in runtime in mobile platforms with ARC

The method description as it is necessary to delete controls in a run mode taking into account operation of the mechanism of automatic reference counting.

3. Making multi forms for Phone and Pad in FireMonkey

How to make different forms for Phone and tablet devices in Firemonkey.

4. Deploy our resources in mobile application in FireMonkey

All way to include your data files into mobile application (Deployment manager and Project Resources)

5. How to close form on mobile application?

Posted by Yaroslav Brovin on January 28th, 2014 under Firemonkey (ENG) | Comment now »


#1. Подборка ссылок по FireMonkey

Вашему вниманию я хочу предоставить подборку полезных ссылок на часто задаваемые вопросы:

1. Средства логирования в FireMonkey

Детальное рассмотрение всех способов логирования в FIreMonkey под Андроид и iOS.

2. Как правильно удалять контролы в RunTime в мобильных платформах под ARC

Описание как нужно удалять контролы в режиме выполнения с учетом работы механизма автоматического подсчета ссылок.

3. Делаем в FireMonkey несколько разных форм отдельно для телефона отдельно для планшетов

Рассматриваем способ использования стандартного механизма выбора форм для разных устройств.

4. Включаем свои файлы и ресурсы в мобильное приложение

Рассматриваются все варианты включения в приложения своих файлов (картинки, графика, медиа и тд) используя менеджер развертывания и встраивание ресурсов через Project Resources.

5. Как правильно закрыть форму на мобильной платформе?

Описание приема корректного закрытия формы на мобильных платформах под ARC.

Posted by Yaroslav Brovin on January 28th, 2014 under Firemonkey (RUS) | 4 Comments »


FireMonkey. Доступ к пикселям TBitmap. Аналог Scanline из VCL.

Добрый день. По скольку одним из частых вопросов по использованию TBitmap в FireMonkey является: "Как мне получить доступ к пикселям TBitmap?". То стоит рассказать про это один раз и помочь разработчикам. А так же ответить на вопрос: "Почему в FMX у TBitmap нету метода SсanLine и причины перехода на Map и UnMap?"

Вопрос: Как мне получить доступ на чтение/изменение пикселей в TBitmap?

Ответ: Для манипуляции с содержимым (точками) в TBitmpa есть два метода: TBitmap.Map и TBitmap.Unmap.

    { Direct access  }
    function Map(const Access: TMapAccess; var Data: TBitmapData): Boolean;
    procedure Unmap(var Data: TBitmapData);

Map - возвращает объект для работы напрямую с точками, информацию о формате пикселей (TBitmapData.PixelFormat), размер изображения в точках (TBitmapData.Width, TBitmapData.Height), размер одного пикселя в текущем представлении точек (TBitmapData.BytesPerPixel).

В качестве параметров функция принимает:

  1. Вид доступа (Чтение - TMapAccess.maRead, запись - TMapAccess.maWrite, чтение и запись  - TMapAccess.maReadWrite). Если вы хотите только прочитать информацию о точках, то используйте вид доступа - TMapAccess.maRead. Это позволит избежать накладных расходов на манипуляцию с данными TBitmap.
И возвращает:
  1. Объект (Data: TBitmapData) содержащий буфер TBitmap и простые методы по манипуляции с буфером.

Получив TBitmapData в вашем распоряжении арсенал по работе с точками, работа непосредственно с буфером памяти TBitmap и мета информация о формате хранения данных TBitmap.

После окончания работы с данными, НЕОБХОДИМО!!! закрыть доступ к данным применив метод TBitmap.Unmap. Иначе результат изменения не отобразится. Вот в принципе и все.

Пример:

var
  M: TBitmapData;
...
  if FBitmap.Map(TMapAccess.maWrite, M) then
    try
      for i := 0 to FColorBitmap.Width - 1 do
        for j := 0 to FColorBitmap.Height - 1 do
          M.SetPixel(i, j, TAlphaColorRec.Red);
    finally
      FColorBitmap.Unmap(M);
    end;
...

Вопрос: Зачем это сделано? Почему нельзя было оставить Scanline в TBitmap, как это сделано в VCL?

Это самый важный вопрос. VCL для хранения и работы с  bitmap изображением использует оболочку над Winapi. В FMX TBitmap это более сложный объект. Так как он должен работать как на всех платформах, так и в разных графических библиотеках. Поэтому прямого доступа к памяти нет, из-за особенностей хранения изображений в разных системах. Где-то мы можем напрямую производить изменение буфера, а где-то нет

Например: в канве GPU работа с битмапом идет через текстуры. Поэтому при вызове метода Map, создается копия буфера. Затем пользователь производит ее модификацию и по методу unmap происходит обновление текстуры новым изображением. Такая же ситуация происходит с использованием канвы D2D под Windows

Надеюсь я пролил свет на работу с буфером битмапа. Если буду вопросы, задавайте. По мере возможности напишу пару статей в формате Вопрос-Ответ.

Posted by Yaroslav Brovin on June 17th, 2013 under Firemonkey (RUS) | 7 Comments »


Часть 3. Разработка компонентов под FMX 2.0. Кликабельная метка

Наконец-то закончилось предрелизное время и теперь можно, отложив все дела, сдать должок - "Кликабельная метка". Здесь можно посмотреть запись с вебинара. Перейдем сразу к делу.

Постановка задачи

Необходимо расширить стандартную метку, известную как "TLabel", добавив возможность открытия ссылки в штатном браузере.

Проблема

Задача довольно классическая и простая с использованием FireMonkey, но имеет один нюанс. В нашем случае мы обязаны мыслить в условиях кроссплатформенности (только для компонентов, имеющих спецефичную функциональность, зависящую от операционных систем - запуск процесса, открытие ссылки и тд.). Метка должна уметь открывать ссылку в любом браузере и под любой, поддерживаемой операционной системе (Win32, Win64, OSX).

Решение

Решение будет состоять из двух частей:

  1. Реализация части компонента не зависящей от операционных систем (вывод текста, настройки, шрифты и тд)
  2. Реализация платформозависимой части (запуск системного процесса на открытие ссылки в браузере)

Общая часть

По сути наш компонент является функциональным расширением существующего компонента TLabel. Поэтому не будем реализовывать метку с нуля, а всего лишь отнаследуемся от TLabel. Назовем наш класс TCustomLinkedLabel.

Дополнительно в наш класс нужно добавить поля для хранения:

  1. Строку с URL - FUrl
  2. Цвет метки, когда ссылка не посещена - FColor
  3. Цвет метки, когда ссылка выделена - FHoverColor
  4. Цвет метки, когда ссылка посещена - FVisitedColor
  5. Флаг, Была ли ссылка посещена? - FVisited

В нашем случае наша метка не требует изменения стиля, поэтому за основу будет взят стандартный стиль. Для этого не забываем переопределить метод TCustomLinkedLabel.GetDefaultStyleLookupName и вернуть название стиля по умолчанию:

function TCustomLinkedLabel.GetDefaultStyleLookupName: string;
begin
  Result := 'labelstyle';
end;

Как и в браузере, будем менять курсор изображение руки при наведении курсора мышки на компонент. Для этого перекроем стандартные методы по попаданию и покиданию курсора мыши в/из область контрола. Поскольку наш компонент будет менять цвет при наведении мыши, то мы не забываем о необходимости перерисовки контрола.

procedure TCustomLinkedLabel.DoMouseEnter;
begin
  inherited;
  Cursor := crHandPoint;
  Repaint;
end;
procedure TCustomLinkedLabel.DoMouseLeave;
begin
  inherited DoMouseLeave;
  Cursor := crDefault;
  Repaint;
end;

Теперь перейдем к непосредственно самой отрисовки метки. На не нужно ее рисовать, по скольку это делегируется компоненту TLabel. Но нам необходимо выполнить только задание нужно цвета перед отрисовкой. Для этого в перекрытом методе TCustomLinkedLabel.Paint выполняем задание цвета через TextSettings.FontColor. Это новая структура для задания настроек выводимого текста:

procedure TCustomLinkedLabel.Paint;
begin
  if IsMouseOver then
    TextSettings.FontColor := FHoverColor
  else
  if FVisited then
    TextSettings.FontColor := FVisitedColor
  else
    TextSettings.FontColor := Color;
  inherited Paint;
end;

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

procedure TCustomLinkedLabel.Click;
begin
  if Assigned(FLaunchService) then
  begin
    FLaunchService.OpenURL(Url);
    FVisited := True;
  end;
end;

Вот и все. Теперь можно приступить к платформозависимой части.

Платформозависимая часть

Все платформозависимые части FireMonkey реализуются с использованием понятия сервис. Общую информацию о том, что такое сервисы, как они устроены и как их получить, можно прочитать тут в разделе "Сервисы". А я лишь коротко скажу, что для нас сервис - это интерфейс + несколько реализаций этого интерфейса под разные платформы. Поэтому необходимо все платформозависимые функции выделить в отдельный интерфейс. У нас такая функция всего одна: "Открыть ссылку в браузере по умолчанию". Не забываем задать GUID для нашего интерфейса сервиса. В RadStudio его можно сгенерировать автоматически, используя комбинацию клавиш Ctrl + Shift + G.

IFMXLaunchService = interface
  ['{3C0888FA-61DD-4B76-9F0E-1956E6E08E86}']
  function OpenURL(const AUrl: string): Boolean;
end;

Результатом этой функции будет - удалось ли передать ссылку браузеру или нет. Возвращаясь к концу предыдущей части, поясню последние строчки кода по открытию ссылки. В поля необходимо добавить ссылку на сервис. А при нажатии всего-лишь вызывать эту функцию.

FLaunchService: IFMXLaunchService;

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

if Assigned(FLaunchService) then
begin
  FLaunchService.OpenURL(Url);
  FVisited := True;
end;

Все сервисы FMX централизованно хранятся в хранилище TPlatformServices.Current. Каждый имеет право запросить реализацию любого сервиса и даже зарегистрировать там свой. Что мы и сделаем чуть позже. А пока, сервис запрашивается следующей строчкой кода:

TPlatformServices.Current.SupportsPlatformService(IFMXLaunchService, IInterface(FLaunchService));

Если реализации сервиса нет, то этот метод вернет нам nil. Если есть, то под интерфейсом FLaunchService будет скрываться реализация. Как видите, это позволяет полностью отделить наш компонент от нижнего уровня, зависимого от платформы.

Теперь можно перейти к реализации сервисов под разные платформы и посмотреть, как они регистрируются.

Реализация сервиса под Windows

Согласно правилу хорошего тона, основной компонент мы разместим в юните: FMX.LinkedLabel. Тогда как все реализации зависимые от платформы располагаются в файлах, полученных путем добавления суффикса платформы к окончанию названия базового юнита:

  1. Для Windows - FMX.LinkedLabel.Win
  2. Для OSX - FMX.LinkedLabel.OSX
Реализация сервиса под Windows довольно банальна:
type
TWinLaunchService = class (TInterfacedObject, IFMXLaunchService)
public
{ IFMXLaunchService }
function OpenURL(const AUrl: string): Boolean;
end;
{ TWinLaunchService }
function TWinLaunchService.OpenURL(const AUrl: string): Boolean;
begin
Result := ShellExecute(0, 'open', PChar(AUrl), nil, nil, SW_SHOWNORMAL) = NO_ERROR;
end;

Мы используя Winapi.ShellApi открываем ссылку.
Регистрацию нашего сервиса в системе осуществляется в секции инициализации следующим способом:

TPlatformServices.Current.AddPlatformService(IFMXLaunchService, TWinLaunchService.Create);

Реализация сервиса под OSX

Аналогично делается и для OSX

type
 TMacLaunchService = class (TInterfacedObject, IFMXLaunchService)
 public
   { IFMXLaunchService }
   function OpenURL(const AUrl: string): Boolean;
 end;
{ TWinLaunchService }
function TMacLaunchService.OpenURL(const AUrl: string): Boolean;
var
  Workspace: NSWorkspace;
  Url: NSURL;
begin
  Workspace := TNSWorkspace.Wrap(TNSWorkspace.OCClass.sharedWorkspace);
  Url := TNSUrl.Wrap(TNSUrl.OCClass.URLWithString(NSStr(AUrl)));
  Result := Workspace.openURL(Url);
end;
initialization
  TPlatformServices.Current.AddPlatformService(IFMXLaunchService, TMacLaunchService.Create);
end.

Подключение разных реализаций сервисов

Осталось рассмотреть только, как теперь нам совместить в одном проекте реализации сервиса под разные платформы. Это делается просто с использование директив условной компиляции, следующим образом:

uses
  FMX.Platform
{$IFDEF MSWINDOWS}
  , FMX.LinkedLabel.Win
{$ELSE}
  {$IFDEF MACOS}
  , FMX.LinkedLabel.Mac
  {$ENDIF}
{$ENDIF};

Заключение

Домашнее задание: Реализовать сервис под ios после релиза мобильной студии.

Posted by Yaroslav Brovin on April 16th, 2013 under Firemonkey (RUS) | 14 Comments »


Часть 2. Разработка компонентов под FMX 2.0. Кнопка с картинкой

Уже прошло почти два месяца с вэбинара на тему "Разработка компонентов на FireMonkey", а время летит быстро и незаметно. Скоро новый год, поэтому все не завершенные дела надо оставить в этом году, поэтому реабилитируюсь и пишу эту статью по теме вэбинара.  В этой статье я рассмотрю общие шаги по разработке своего компонента на FMX и в качестве примера рассмотрю разработку компонента TBitBtn - кнопка с картинкой. Этот компонент - аналог кнопки с картинкой взятой из VCL. Но в нашем случае он будет уметь:

  1. Осуществлять легкое переключение между вариантами отображения стандартных кнопок без стирания пользовательской картинки VCL.TBitBtn.Glyph
  2. Легко менять стандартные картинки на свои
  3. Работать со списком изображений, что не умеет делать VCL кнопка с картинкой.

И так приступим…

С чего начать

Будем считать, что в первом приближении вы уже познакомились с FireMonkey и обладаете первоначальными знаниями, как пользоваться библиотекой (как в дизайнере сделать небольшую форму и тд) и познакомились с моими предыдущими небольшими статьями на эту тему. А раз так, то для дальнейшего погружения в разработку своих компонентов нужно:

  1. Посмотреть как работают примитивные объекты (TLine, TRectangle, TCircle, TText и другие) - те, из которых строятся все остальные. Попробовать и потрогать их можно в среде IDE. Посмотреть как устроены, можно заглянув в исходный код.
  2. Перейти на простые стилизуемые объекты (TLabel, TCheckBox, TButton) - те, которые не являются объектами контейнерного типа (Меню, списки, выпадающие списки, группы, и тд). Источники вдохновение все те же, что и в пункте 1 + эта статья (как раз здесь будет рассмотрен компонент из этой группы).
  3. Сложные стилизуемые объекты контейнерного типа (TGroupBox, TPanel, TListBox, TTreeView, TComboBox и тд)
  4. Платформозависимые компоненты (TTimer, частично TComboBox, TMainMenu, TMediaPlayer и тд). В себе несут несколько реализаций для разных платформ через использование сервисов FMX

Шаги разработки

1 Шаг: Объектная декомпозиция

Вначале нужно провести объекту декомпозицию. Довольно известный прием проектирования. Вы берете ваш компонент и делите его на логические составляющие (сущности). Затем берете каждую сущность и опять ее делите до тех пор, пока не станет ясными общие детали реализации всех составляющих.

2 Шаг: Принимаем решение о написании компонента с нуля или берем за основу уже существующий компонент?

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

3 Шаг: Разработка представления компонента в терминах полученных сущностей (для визуальных компонентов)

На этом шаге, начать лучше с внешнего вида (стиля) каждой визуальной части компонента.

Почему это лучше сделать до написания самой бизнес логики?

Потому что визуальный компонент - это логика + представление. Логика тесно связана с представлением и составным частях представления. Поэтому не имея составных частей представления, начинать с логики будет тяжелее. Так как придется работать с еще не созданными объектами представления.

4 Шаг: Кодирование

Непосредственно уже написание логики и связывание ее с уже с продуманным стилей. На этом шаге возможно корректировка стиля.

Реализация

Мы хотим сделать, описанную выше, кнопку с картинкой.

1 Шаг: Объектная декомпозиция

Кнопка состоит из трех частей:

  1. Форма
  2. Текст
  3. Картинка


Форма может быть построена из прямоугольника и любой другой геометрической фигуры: будь то круглая кнопка или прямоугольная, или прямоугольная с закругленными углами.

2 Шаг: Принимаем решение о написании компонента с нуля или берем за основу уже существующий компонент?

Просматриваем существующие компоненты. Наша кнопка с картинкой является функциональным расширением обычной кнопки. Поскольку кнопке добавляет только картинку. Значит за основу возьмем существующий класс TButton

3 Шаг: Разработка представления компонента в терминах полученных сущностей (для визуальных компонентов)

Раз мы взяли за основу компонент TButton, то в основу стиля возьмем стиль кнопки. Чтобы его получить нужно кинуть кнопку на FireMonkey форму, нажать на нее правой кнопкой мышки и выбрать в контекстном меню "Edit Custom Style"

В результате дизайнер среды вытащит нам стиль по умолчанию для обычной кнопки. Мы видим, что обычная кнопка состоит из фона - он же в нашей терминологии "Форма" и текста. Значит нам остается только встроить в стиль контейнер для картинки. У меня получилось это вот так:

Вы могли бы просто доработать стиль button1style1: добавить в него картинку и переименовать стиль на bitbtnstyle. Обратите внимание, что каждая часть (сущность) в стиле должна иметь имя (stylename), для дальнейшего доступа к ней из кода. В нашем случае

glyph - название контейнера изображения

text - название контейнера текста

Фон у нас не имеет имя, поскольку нам не нужен к нему доступ.

4 Шаг: Кодирование

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

 TBitBtnKind = (bkStylizedGlyph, bkCustomGlyph, bkOK, bkCancel, bkHelp, bkYes,
bkNo, bkClose, bkRetry, bkIgnore);
  1. bkCustomGlyph - Картинка для кнопки берется из TBitBtn.Glyph
  2. bkStylizedGlyph - Картинка для кнопки берется из StyleBook по имени стиля
  3. Остальные - Картинка для кнопки берется из текущего стиля по заранее заданному имени стиля
Если первый вариант отображения, хорошо известен из VCL. То второй нужно пояснить.

В FireMonkey нет TImageList, однако, в качестве замены можно использовать TStyleBook. Потому что по сути TStyleBook умеет хранить в себе все что угодно по имени. А значит, что в TStyleBook мы можем помещать не только стили, но и именованные картинки. bkStylizedGlyph - как раз использует stylebook для получения картинок. Подробности использования будут дальше.

Чтобы не возиться с ресурсными файлами и извлечении из них стандартных картинок формы, мы будем хранить картинки в стиле. Для получении имени картинки в стиле будем использовать следующий ассоциативный массив - тип кнопки - название стиля:

const
  BITBTN_KIND_STYLES : array [TBitBtnKind] of string = ('', '', 'imgOk',
    'imgCancel', 'imgHelp', 'imgYes', 'imgNo', 'imgClose', 'imgRetry',
    'imgIgnore');
TCustomBitBtn = class (TButton)
strict private
  FImageBook: TStyleBook; // Хранение ссылки на внешний StyleBook с картинками 
  FKind: TBitBtnKind; // Способ отображения кнопки 
  FGlyph: TBitmap; // Внутренний контейнер для хранения пользовательской картинки
  FStyleImage: TImage; // Ссылка на элемент стиля, контейнер для вывода картинки
  FImageLookup: string; // Название картинки из StyleBook (Аналог ImageIndex)
  procedure SetGlyph(const Value: TBitmap);
  procedure SetKind(const Value: TBitBtnKind);
  procedure SetImageBook(const Value: TStyleBook);
  procedure SetGlyphStyle(const Value: string);
  protected
  // Перехватываем событие по загрузке стиля для получения ссылки на FStyleImage
  procedure ApplyStyle; override;
  // Перехватываем событие по освобождении стиля, для очищения ссылки FStyleImage
  procedure FreeStyle; override;
  // Возвращаем название стиля по умолчанию
  function GetDefaultStyleLookupName: string; override;
  // Процедура загрузки картинки в стиль
  procedure UpdateGlyph; virtual;
public
  constructor Create(AOwner: TComponent); override;
  destructor Destroy; override;
  property ImageBook: TStyleBook read FImageBook write SetImageBook;
  property Kind: TBitBtnKind read FKind write SetKind default TBitBtnKind.bkStylizedGlyph;
  property Glyph: TBitmap read FGlyph write SetGlyph;
  property GlyphStyle: string read FImageLookup write SetGlyphStyle;
end;

ApplyStyle и FreeStyle используется для получение ссылки на составные объекты стиля (картинку, текст и тд) Подробнее о механизме загрузки стиля и получении ссылок на составные объекты стиля есть тут.

procedure TCustomBitBtn.UpdateGlyph; 
  procedure FindAndSetGlyph(const AStyleName: string);
  var
    StyleObject: TFmxObject;
    Finded: Boolean;
  begin
    Finded := False;
    if Assigned(FImageBook) then
    begin
      StyleObject := FImageBook.Style.FindStyleResource(AStyleName);
      if Assigned(StyleObject) and (StyleObject is TImage) then
      begin
        FStyleImage.Bitmap.Assign(TImage(StyleObject).Bitmap);
        Finded := True;
      end
    end;
    FStyleImage.Visible := Finded;
  end;
  
  procedure FindAndSetStandartButtonKind(const AStyleName: string);
  var
    StyleObject: TFmxObject;
    Finded: Boolean;
    Style: TFmxObject;
  begin
    // Выбираем ветку стиля:
    //   - Если для формы указан StyleBook, то берем его.
    //   - Если для формы не задан StyleBook, то берем стиль по умолчанию
    if Assigned(Scene.StyleBook) then
      Style := Scene.StyleBook.Style
    else
      Style := TStyleManager.ActiveStyleForScene(Scene);
    // Ищем стиль по указанному имени в текущей ветки стиля
    StyleObject := Style.FindStyleResource(AStyleName);
    Finded := Assigned(StyleObject) and (StyleObject is TImage);
    if Finded then
      FStyleImage.Bitmap.Assign(TImage(StyleObject).Bitmap);
    FStyleImage.Visible := Finded;
  end;
begin
  if not Assigned(FStyleImage) then
    Exit;
  case Kind of
    bkStylizedGlyph: FindAndSetGlyph(FImageLookup);
    bkCustomGlyph: FStyleImage.Bitmap.Assign(FGlyph);
  else
    FindAndSetStandartButtonKind(BITBTN_KIND_STYLES[Kind]);
  end;
  FStyleImage.Visible := not FStyleImage.Bitmap.IsEmpty;
end;

Метод FindAndSetStandartButtonKind находит стандартную картинку (ok, yes, no, cancel и другие) в текущем стиле формы.

Метод FindAndSetGlyph ищет указанную по имени картинку в StyleBook с картинками (аналог TImageList)

Обратите внимание, что FindStyleResource позволяет вам по имени вытащить объект из иерархии объекта.

TStyleManager - это менеджер выдающий всю актуальную информацию о стилях. Подробнее читайте в документации.

Вот в принципе и все.

Исходники прилагаются. Качайте, смотрите, пробуйте, улучшайте :-)

Ссылки

Исходники: http://cc.embarcadero.com/item/29254

Запись вебинара: http://blogs.embarcadero.com/vsevolodleonov/2012/11/26/firemonkey20_componentdevelopment_brovin/

Posted by Yaroslav Brovin on December 27th, 2012 under Firemonkey (RUS) | 8 Comments »




Server Response from: BLOGS1