Writing C++ Builder/Delphi component and save a binary property to DFM files
Asked Answered
M

1

5

I wrote a C++ builder component to display SVG files perform some stuff on them.

For now, I published a property named SvgFile (UnicodeString) which can be initialized in the IDE with the file name of the SVG file. This works fine. This property is saved into the DFM file and can be reloaded from it.

But I have to provide the SVG file with the application so I would like to save the SVG into the DFM file, as it is done with a TImage component.

I guess I have to write a TPropertyEditor and maybe a TPersistent class but I don't know what to do.

Does anyone could help me to do so ?

Edit 2013/01/17: here's a solution http://www.informit.com/articles/article.aspx?p=28278&seqNum=5

Thanks for your help.

Maidinwaiting answered 16/1, 2013 at 11:35 Comment(0)
H
7

You can create your own methods to read and write the properties by writing your own methods to perform the streaming of the binary data to and from a stream, and register them with the VCL/RTL streaming system using DefineProperties and DefineBinaryProperty. There's an easy to follow example in the JEDI JVCL unit JVXSlider.pas:

// interface
type
  TJvCustomSlider=class(TJvCustomControl)
  private
    procedure ReadUserImages(Stream: TStream);
    procedure WriteUserImages(Stream: TStream);
    ...
  protected
    procedure DefineProperties(Filer: TFiler); override;


// implementation
procedure TJvCustomSlider.DefineProperties(Filer: TFiler);

  function DoWrite: Boolean;
  begin
    if Assigned(Filer.Ancestor) then
      Result := FUserImages <> TJvCustomSlider(Filer.Ancestor).FUserImages
    else
      Result := FUserImages <> [];
  end;

begin
  // @RemyLebeau points out that the next line is apparently a bug
  // in the JVCL code, and that inherited DefineProperties should always
  // be called regardless of the type of Filer. Commented it out, but
  // didn't delete it because it *is* in the JVCL code I cited.

  //if Filer is TReader then
    inherited DefineProperties(Filer);
  Filer.DefineBinaryProperty('UserImages', ReadUserImages, WriteUserImages, DoWrite);
end;

procedure TJvCustomSlider.ReadUserImages(Stream: TStream);
begin
  Stream.ReadBuffer(FUserImages, SizeOf(FUserImages));
end;

procedure TJvCustomSlider.WriteUserImages(Stream: TStream);
begin
  Stream.WriteBuffer(FUserImages, SizeOf(FUserImages));
end;

The Delphi streaming system will automatically call the appropriate methods for the defined property (in the example above, property UserImages) as needed to save to or read from the dfm file automatically; you never have the need to call them yourself.

Hallam answered 16/1, 2013 at 15:23 Comment(3)
The DefineProperties() override needs to call the inherited method regardless of whether the Filer is a TReader or not. That looks like a possible JEDI bug.Kozak
@Remy: I hadn't spotted that when I did the quick copy/paste. Thanks - I'll update the answer to comment it out with a note for clarity.Hallam
Yes I figured it out after having a look at informit.com/articles/article.aspx?p=28278&seqNum=5Maidinwaiting

© 2022 - 2024 — McMap. All rights reserved.