我觉得叫 "皮肤" 不如叫 "样式" 或 "风格", 因为它可以包含和动作关联的动画.

在 FMX 下, 控件可以任意绘制, 各部件个性化的属性可以统一保存成一个 *.style 文件.
XE2 在 "...\Program Files\Embarcadero\RAD Studio\9.0\Redist\styles\Fmx\" 下提供了如下样式文件:


Air.Style
Amakrits.Style
AquaGraphite.style
Blend.Style
dark.style
FMX.Platform.iOS.style
FMX.Platform.Mac.style
FMX.Platform.Win.style
GoldenGraphite.Style
iOS.Style
MacBlue.Style
MacGraphite.Style
RubyGraphite.style
Windows7.Style

文件是文本格式, 类似窗体文件, 可用 TStyleBook 读入并管理.
不过要给程序套用样式, 确简单得很:


procedure TForm1.Button1Click(Sender: TObject);
begin
  Application.StyleFileName := '样式文件名'; //如果样式文件和 exe 同目录, 还可以省略路径
end;

在窗体上添加一个 TStyleBook(StyleBook1), 可以载入、编辑、另存这些样式.
编辑 StyleBook1 后, 可以把它直接赋给窗体的 StyleBook 属性:


procedure TForm1.Button1Click(Sender: TObject);
begin
  Self.StyleBook := StyleBook1; //只作用于当前窗体
end;

窗体的 StyleBook 属性既然也是 TStyleBook 对象, 可以直接使用它:


procedure TForm1.Button1Click(Sender: TObject);
begin
  StyleBook := TStyleBook.Create(Self); //默认情况下, 窗体的 StyleBook 还没有建立
  StyleBook.FileName := '样式文件';    //或者用下一行
  //StyleBook.Resource.LoadFromFile('样式文件'); //TStyleBook 是用 Resource(TStrings) 储存数据的
end;

单独修改控件样式可以使用 StyleLookup 属性, 如:


procedure TForm1.Button1Click(Sender: TObject);
begin
  Button1.StyleLookup := 'checkbox';
end;
//在设计时可从控件的右键菜单

*.style 文件中 StyleName 命名有约定(这是我猜的):

、类名(去掉前面的T) + 'style' //这是独立控件的样式名称
、类名(去掉前面的T)          //这是控件子部件的样式名称
、既然有了命名约定, 控件可以根据自己的类名去套用, 所以会发现大多数控件的 StyleLookup 属性并无赋值
、修改控件或子部件的样式都应该通过 StyleLookup 属性, 而不是 StyleName(我都觉得 StyleName 这个属性有点多余).

我倒是发现控件子部件的 StyleName 都可以读的出来:


procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(Memo1.HScrollBar.StyleName);
  ShowMessage(Memo1.VScrollBar.StyleName);
end;

其它诸如 ApplyStyleLookup()、UpdateStyle()、FindStyleResource() 等相关方法, 一般都是被自动调用的.

程序会把默认样式嵌入到资源中(名称: defaultstyle, 格式: RT_RCDATA), 恢复程序的默认样式时只需:


procedure TForm1.Button1Click(Sender: TObject);
begin
  Application.StyleFileName := ''; //程序会自动套用默认样式
  Form1.StyleBook := nil;          //如果窗体单独设置了样式, 这样恢复
end;

之前有同学问到, 怎么修改窗体标题栏的样式?
学习过程中, 我没有发现很直接的办法;
暂时要我做, 只能是隐藏标题栏, 重新绘制;
等了解的窗体的更多机制以后, 或许也能从 *.style 文件中找到办法.

很肤浅, 谁知道更多, 愿能告诉我.


Delphi XE2 之 FireMonkey 入门(20) - TStyleBook(皮肤、样式相关)的更多相关文章

  1. Delphi XE2 之 FireMonkey 入门(36) - 控件基础: TForm

    Delphi XE2 之 FireMonkey 入门(36) - 控件基础: TForm 当我第一次读取 Form1.StyleLookup 并期待出现 "formstyle" 时 ...

  2. Delphi XE2 之 FireMonkey 入门(45Finally) - 结题与问题

    Delphi XE2 之 FireMonkey 入门(45Finally) - 结题与问题 很喜欢 FMX 的一些新控件, 如: TExpander.TArcDial.TComboTrackBar.T ...

  3. Delphi XE2 之 FireMonkey 入门(44) - 控件基础: TTreeView、TTreeViewItem

    Delphi XE2 之 FireMonkey 入门(44) - 控件基础: TTreeView.TTreeViewItem TScrollBox -> TCustomTreeView -> ...

  4. Delphi XE2 之 FireMonkey 入门(43) - 控件基础: TStringGrid、TGrid

    Delphi XE2 之 FireMonkey 入门(43) - 控件基础: TStringGrid.TGrid TStringGrid.TGrid 都是从 TCustomGrid 继承; 区别有:1 ...

  5. Delphi XE2 之 FireMonkey 入门(42) - 控件基础: TComboBox、TComboEdit

    Delphi XE2 之 FireMonkey 入门(42) - 控件基础: TComboBox.TComboEdit TListBox 有两个兄弟 TComboListBox.TComboEditL ...

  6. Delphi XE2 之 FireMonkey 入门(41) - 控件基础: TListBox

    Delphi XE2 之 FireMonkey 入门(41) - 控件基础: TListBox TScrollBox -> TCustomListBox -> TListBox; 其元素项 ...

  7. Delphi XE2 之 FireMonkey 入门(40) - 控件基础: TMemo

    Delphi XE2 之 FireMonkey 入门(40) - 控件基础: TMemo 值得注意的变化: 1.其父类 TScrollBox 的许多特性也很有用处, 如:   Memo1.UseSma ...

  8. Delphi XE2 之 FireMonkey 入门(39) - 控件基础: TScrollBox、TVertScrollBox、TFramedScrollBox、TFramedVertScrollBox

    Delphi XE2 之 FireMonkey 入门(39) - 控件基础: TScrollBox.TVertScrollBox.TFramedScrollBox.TFramedVertScrollB ...

  9. Delphi XE2 之 FireMonkey 入门(38) - 控件基础: TPopupMenu、TMenuItem、TMenuBar、TMainMenu

    Delphi XE2 之 FireMonkey 入门(38) - 控件基础: TPopupMenu.TMenuItem.TMenuBar.TMainMenu 相关控件: TMenuBar.TPopup ...

随机推荐

  1. P2516 [HAOI2010]最长公共子序列

    传送门 看到数据范围,显然 $n^2$ 的 $dp$... 设 $f[i][j]$ 表示 $A$ 串考虑了前 $i$ 位,$B$ 串考虑了前 $j$ 位,最优情况下的方案数 但是好像没法判断转移来的是 ...

  2. 使用mysql的source批量导入多个sql文件

    需求: 有一个文件,文件里面包含100多个sql文件,想要把这些sql文件都导入到mysql中 做法: 使用 mysql 的 source 可以将文件导入到 mysql 中,但是一次只能导入一个 sq ...

  3. ubuntu下安装/升级软件

    参考博客:https://blog.csdn.net/yjk13703623757/article/details/78945576 1.查看软件所有来源 ①.使用apt-cache madison列 ...

  4. 用doxygen+graphviz生成函数调用流程图

    https://www.jianshu.com/p/fe4b6b95dca5 注意点:由于使用到了Graphviz,所以要设置Dot选项,勾选HAVE_DOT,并设置DOT_PATH为Graphviz ...

  5. 【串线篇】spring boot嵌入式Servlet容器启动原理;

    什么时候创建嵌入式的Servlet容器工厂?什么时候获取嵌入式的Servlet容器并启动Tomcat: 获取嵌入式的Servlet容器工厂: 1).SpringBoot应用启动运行run方法 2).r ...

  6. bzoj3091 城市旅行 LCT + 区间合并

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3091 题解 调了整个晚自习才调出来的问题. 乍一看是个 LCT 板子题. 再看一眼还是个 LC ...

  7. CF506E Mr. Kitayuta's Gift

    这道题神仙到让我面临着买不到冰皮月亮蛋糕的风险来写题解 (蛋糕真好吃呜呜呜) 这篇题解参考了CQzhangyu神仙的做法. (目测比标程科学好写) 限制是要回文,根据我们做字符串计数的常识,一定是尽量 ...

  8. 【SaltStack官方版】—— job management

    JOB MANAGEMENT New in version 0.9.7. Since Salt executes jobs running on many systems, Salt needs to ...

  9. javaScript中的 call 和 apply

    call 和apply都可以实现函数的调用 // 普通函数的调用 function foo() { console.log('foo'); } foo(); // foo foo.call(); // ...

  10. List中的Map

    List中的Map import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.u ...