Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DoubleBuffered property being added in the dfm in Delphi 2009 does not exist in Delphi 2007

Does that mean that I can't share a Form between delphi 2007 and 2009?

like image 263
Fabio Gomes Avatar asked Nov 07 '08 11:11

Fabio Gomes


5 Answers

DoubleBuffered has been in TWinControl for some time now. The difference in Delphi 2009 is that it's published now. If you can live with only ignoring the errors (and not making the properties work instead), here is a possible solution:

unit Delphi2009Form;

interface

uses
  Windows, Classes, SysUtils, Controls, Forms;

type
{$IFDEF VER200}
  TDelphi2009Form = class(TForm);
{$ELSE}
  TDelphi2009Form = class(TForm)
  private
    procedure ReaderError(Reader: TReader; const Message: string; var Handled: Boolean);
  protected
    procedure ReadState(Reader: TReader); override;
  end;

  TReaderErrorProc = procedure(const Message: string);

var
  ReaderErrorProc: TReaderErrorProc = nil;
{$ENDIF}

implementation

{$IFNDEF VER200}
type
  THackReader = class(TReader);

procedure TDelphi2009Form.ReaderError(Reader: TReader; const Message: string; var Handled: Boolean);
begin
  with THackReader(Reader) do
    Handled := AnsiSameText(PropName, 'DoubleBuffered') or AnsiSameText(PropName, 'ParentDoubleBuffered');
  if Handled and Assigned(ReaderErrorProc) then
    ReaderErrorProc(Message);
end;

procedure TDelphi2009Form.ReadState(Reader: TReader);
begin
  Reader.OnError := ReaderError;
  inherited ReadState(Reader);
end;
{$ENDIF}

end.

Then change the declarations of the forms in your project to inherit from TDelphi2009Form, e.g.:

type
  TFormMain = class(TDelphi2009Form)
  ...

This will work at runtime - the property errors will be ignored. To make it work at design time, too, create a design-only package, add designide.dcp to its requires clause, and add the following unit to it:

unit Delphi2009FormReg;

interface

uses
  Delphi2009Form;

procedure Register;

implementation

uses
  DesignIntf, DesignEditors, ToolsAPI;

procedure ShowReaderError(const Message: string);
begin
  with BorlandIDEServices as IOTAMessageServices do
    AddTitleMessage(Message);
end;

procedure Register;
begin
  RegisterCustomModule(TDelphi2009Form, TCustomModule);
  ReaderErrorProc := ShowReaderError;
end;

initialization

finalization
  ReaderErrorProc := nil;

end.

Install the package in Delphi 2007 IDE and property errors for DoubleBuffered and ParentDoubleBuffered properties will be ignored automatically when opening your forms in the IDE. The values of the properties will be lost when you save the form in Delphi 2007 so you should initialize them in code instead.

EDIT: I've added code to output the reader error messages to the IDE Messages window:

IDE error messages

like image 150
Ondrej Kelle Avatar answered Oct 23 '22 22:10

Ondrej Kelle


Yes. It is not possible unless you remove the properties that are not published in Delphi 2007 from the DFM.

like image 6
Lars Truijens Avatar answered Oct 24 '22 00:10

Lars Truijens


Delphi projects have always been extremely easy to port forward to new versions. You have to be more careful, but using current code with older compilers is pretty straight forward, too. I maintained code in Delphi 2005/2006/2007 that other people still needed to use in Delphi 6 and 7.

If you remove the incompatible properties from the DFMs, they should work properly in older versions without messing them up for Delphi 2009. The biggest example is the explicit* properties introduced in Delphi 2006. I have a home brewed "DFM scrubber" that strips these out. Remember, these properties exist for a reason, so you should only scrub ones that you intend to be backward compatible.

You might also consider investing in static code analysis tools like CodeHealer or Pascal Analyzer. On top of pointing out problems (especially CodeHealer) and helping you clean up your code, you can choose which version of Delphi to analyze against, making it easier to find incompatibilities aside from DFM properties. And they can be automated as part of your build process.

Just a note. Share the source code, but keep separate projects for each version. This is especially important between Delphi 2007 and Delphi 2009. The more recent .dproj file uses the same extension, but isn't compatible with Delphi 2007. You could run in to some problame with incompatible resources, too.

like image 4
Bruce McGee Avatar answered Oct 24 '22 00:10

Bruce McGee


Each form has a dfm file which contains the property settings of the form and its components. Some property values have defaults so they are not stored if the default value is kept. Is just did a small test:

  • Create a form in 2009
  • Add a couple of standard controls
  • Save it
  • Open it in 2006 (sorry no 2007 on this pc)

And it worked without messages. But maybe you are not so lucky.

With Delphi, it is often a bit troublesome to share data between versions. Upgrading posibilities are great, but downgrading is troublesome. So I advise against sharing form files between different versions.

As far as I know, it is not possible to add conditional defines in the dfm file. But then again, do we really want that... I would prefer a mechanism that ignores unknown properties.

like image 2
Toon Krijthe Avatar answered Oct 23 '22 23:10

Toon Krijthe


You can safely add the properties in code in your OnCreate method for the form, and wrap an {$IFDEF VER200} // NEW PROPERTIES {$ENDIF} around them. You can leave DoubleBuffered outside the ifdefs, as it was present in Delphi 2007, just not available to the property inspector.

You will ONLY have to worry about the properties which you set different from the default. For doublebuffered, you only need to worry about this if it is set to true.

When loading the Delphi 2009 form in Delphi 2007, you will get a warning that a property is going to get destroyed, just make note of those properties, as those are the ones that you will need to deal with.

I am using just such a method to migrate my code to Delphi 2009 from Delphi 2006. Most of my projects contain several shared units and must compile in Delphi 2006 for the shipping version and Delphi 2009 for the "next" release. I also make lots of use of the {$IFDEF UNICODE} define where I need to insure a string is widestring, or ansistring depending on the routine.

like image 2
skamradt Avatar answered Oct 23 '22 22:10

skamradt