8

私は別の投稿の最後にこの質問をしましたが、このトピックには独自の質問が必要だと感じています...

独自の.styleを使用して独自のコンポーネントを作成した場合、デフォルトを変更せずにDelphiで提供される定義済みのスタイルとそれをマージする正しい手順は何ですか?

作成したコンポーネントにデフォルトのスタイルを埋め込むことはできますか?また、その埋め込まれたスタイルは、親コントロールのスタイルのほとんどを継承できますか?

説明するのに苦労しているリンクが欠けているように感じます。私のアプリケーションには、(たとえば)デフォルトで「dark.style」がロードされているTStyleBookがあります。私のコンポーネントには、独自の「MyComponent.style」ファイルがあります。TStyleBookは、「dark.style」または「MyComponent.style」のいずれかをロードできますが、両方をロードすることはできません。また、アプリケーションが「MyComponent.style」をロードする必要があるのは正しくないようです。これは、コンポーネントによって何らかの形で参照される必要があるためです。アプリケーションで使用するたびに別のスタイルファイルも必要になる場合は、コンポーネントの移植性が高くなりません。

自分の「MyDark.style」を編集してMyComponentを追加することもできますが、Embarcaderoによって行われた変更で最新の状態に保つための問題が発生するため、これも正しくないようです。

これを明確に説明できたと思います。マーティン

4

2 に答える 2

5

CodeRage について素晴らしい講演をしてくれた Ray Konopka に感謝し、これらの質問に答える正しい道を示してくれました。

質問 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, Style, 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, Style, RT_RCDATA);
      try
        obj := TLayout( CreateObjectFromStream(nil, S) );
        Result.AddObject(obj);
        Exit;
      finally
        S.Free;
      end;
    end;
  end;
end;

これが他の誰かの役に立てば幸いです。情報を入手するのは非常に難しいと思いました。

マーティン

于 2011-10-21T01:36:40.780 に答える
2

使用法:MergeStyle('MyComponent.Style'、StyleBook1);

procedure MergeStyle(const aFilename: string; aStyleBook: TStyleBook);
var
  sb: TStyleBook;
  I: Integer;
begin
  sb := TStyleBook.Create(nil);
  try
    sb.FileName := aFilename;

    for I := 0 to sb.Root.ChildrenCount - 1 do
      // Prevent duplicates
      if aStyleBook.Root.FindStyleResource(sb.Root.Children[I].StyleName) = nil then
        aStyleBook.Root.AddObject(sb.Root.Children[I].Clone(aStyleBook.Root));

    aStyleBook.UpdateScenes;
  finally
    sb.Free;
  end;
end;
于 2011-10-18T17:21:57.260 に答える