加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 为自定义组件创建样式的正确方法

发布时间:2020-12-15 04:19:37 所属栏目:大数据 来源:网络整理
导读:我在另一篇文章的末尾有点问这个问题,但觉得这个话题需要一个自己的问题…… 如果我用自己的.style创建了我自己的组件,那么将它与Delphi提供的已定义样式合并而不修改默认值的正确程序是什么? 我可以将默认样式嵌入到我创建的组件中吗?嵌入式样式是否可以
我在另一篇文章的末尾有点问这个问题,但觉得这个话题需要一个自己的问题……

如果我用自己的.style创建了我自己的组件,那么将它与Delphi提供的已定义样式合并而不修改默认值的正确程序是什么?

我可以将默认样式嵌入到我创建的组件中吗?嵌入式样式是否可以继承其父控件的大部分样式?

我觉得我错过了一个我正在努力描述的链接.
我的应用程序有一个TStyleBook,默认情况下加载(例如)“dark.style”.
我的组件有自己的“MyComponent.style”文件.
TStyleBook可以加载“dark.style”或“MyComponent.style”,但不能同时加载两者.
并且应用程序需要加载“MyComponent.style”似乎不对,因为这应该以某种方式由组件引用.如果每次在应用程序中使用单独的样式文件时,它也不会使组件非常便携.

我可以编辑自己的“MyDark.style”并将MyComponent添加到其中但这似乎也不正确,因为它会产生一个问题,以使其与Embarcadero所做的更改保持同步.

我希望我已经清楚地解释了这一点.
马丁

解决方法

感谢Ray Konopka,他对CodeRage进行了精彩的演讲,并让我走上正确的轨道来回答这些问题.

问题1.我可以在组件中嵌入默认样式吗?

是的,您将要与组件一起分发的默认样式嵌入到RT_RCDATA类型的资源中.然后只需将该资源包含在源中:

{$R *.res}

注意:如果在布局编辑器中创建外部对象(TLayout)之前将其放入res中,则需要将其删除.

然后重写GetStyleObject方法以从资源加载样式.

function TLFButton.GetStyleObject: TControl;
var
  S: TResourceStream;
  obj: TLayout;
const
  Style = 'LFButtonStyle';
begin
  result := inherited GetStyleObject;
  if FStyleLookup = 'cornerbuttonstyle' then
  begin
    if FindResource(HInstance,PChar(Style),RT_RCDATA) <> 0 then
    begin
      S := TResourceStream.Create(HInstance,Style,RT_RCDATA);
      try
        obj := TLayout(TStyleManager.LoadFromResource(HInstance,RT_RCDATA));
        //obj := TLayout( CreateObjectFromStream(nil,S) ); << XE2 version
        Result.AddObject(obj);
        Exit;
      finally
        S.Free;
      end;
    end;
  end;
end;

问题2:如何将其与默认样式合并.

在我的例子中,我的组件的基础是TCornerButton.我修剪了我的.style文件,以便它只有我想要的额外位的代码.在这种情况下,一个小三角形表示一个下拉按钮,一行用于分割按钮:

object TLayout
  Align = alRight
  Position.Point = '(76,0)'
  Locked = True
  Width = 15.000000000000000000
  Height = 24.000000000000000000
  object TPath
    StyleName = 'dropdownbutton'
    Align = alCenter
    Position.Point = '(4,9)'
    Width = 8.000000000000000000
    Height = 5.000000000000000000
    HitTest = False
    Fill.Color = claBlack
    Stroke.Kind = bkNone
    Data.Path = {
      04000000000000000000000000000000010000000000803F0000000001000000
      0000003F0000803F030000000000000000000000}
  end
  object TLine
    StyleName = 'dropdownsplit'
    Align = alLeft
    Width = 1.000000000000000000
    Height = 24.000000000000000000
    HitTest = False
    LineType = ltLeft
  end
end

我以完全相同的方式将它放入资源中.

在我的构造函数中,我将StyleLookup设置为“cornerbuttonstyle”

constructor TLFButton.Create(AOwner: TComponent);
begin
  FStyleLookup := 'cornerbuttonstyle';
  FDropDownButton := false;
  inherited;
end;

然后我更改GetStyleObject,以便它加载新的东西并将其添加到现有样式.

function TLFButton.GetStyleObject: TControl;
var
  S: TResourceStream;
  obj: TLayout;
const
  Style = 'LFButtonStyle';
begin
  result := inherited GetStyleObject;
  if FStyleLookup = 'cornerbuttonstyle' then
  begin
    if FindRCData(HInstance,Style) then
    begin
      S := TResourceStream.Create(HInstance,RT_RCDATA);
      try
        obj := TLayout( CreateObjectFromStream(nil,S) );
        Result.AddObject(obj);
        Exit;
      finally
        S.Free;
      end;
    end;
  end;
end;

我希望这有助于其他人,我发现这一切都非常难以获得信息.

马丁

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读