tags:

views:

168

answers:

2

Hi,

I get SOMETIMES error message: EReadError with message 'Property PageNr does Not exist', when I try to run my own project. I am really desperate, because I see simply nothing what is the cause. The devilish is that it comes up sometimes but often. It concerns of my own component TPage. Here is declaration>

TPage = class(TCustomControl)   //
   private
      FPaperHeight, FPaperWidth:Integer;
      FPaperBrush:TBrush;
      FPaperSize:TPaperSize;
      FPaperOrientation:TPaperOrientation;
      FPDFDocument: TPDFDocument;
      FPageNr:integer;

      procedure PaintBasicLayout;
      procedure PaintInterior;
      procedure SetPapersize(Value: TPapersize);
      procedure SetPaperHeight(Value: Integer);
      procedure SetPaperWidth(Value: Integer);
      procedure SetPaperOrientation(value:TPaperOrientation);
      procedure SetPaperBrush(Value:TBrush);
      procedure SetPageNr(Value:Integer);
   protected
      procedure CreateParams(var Params:TCreateParams); override;
      procedure AdjustClientRect(var Rect: TRect); override;
   public
      constructor Create(AOwner: TComponent);override;
      destructor Destroy;override;
//      function GetChildOwner:TComponent; override;
      procedure DrawControl(X,Y :integer; Dx,Dy:Double; Ctrl:TControl;NewCanvas:TCanvas);
//      procedure GetChildren(Proc:TGetChildProc; Root:TComponent); override;
      procedure Loaded; override;
      procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);  override;
      procedure Paint; override;
      procedure PrintOnCanvas(X,Y:integer; rX,rY:Double; ACanvas:TCanvas);
      procedure PrintOnPDFCanvas(X,Y:integer);
      procedure PrintOnPrinterCanvas(X,Y:integer);
      procedure Resize; override;
      procedure SetPrintKind(APrintKind:TPrintKind; APrintGroupindex:Integer);
   published
      property PageNr:integer read FPageNr write SetPageNr;
      property PaperBrush: TBrush read FPaperBrush  write SetPaperBrush;
      property PaperHeight: integer read FPaperHeight write SetPaperHeight;
      property PaperWidth: integer read FPaperWidth write SetPaperWidth;
      property PaperSize: TPaperSize read FPaperSize write SetPaperSize;
      property PaperOrientation:TPaperOrientation read FPaperOrientation write SetPaperOrientation;
      property PDFDocument:TPDFDocument read FPDFDocument write FPDFDocument;
      property TabOrder;
   end;

I thoroughly read the similar topic depicted here:

Delphi: EReadError with message 'Property Persistence does Not exist'

But here it is my own source code. No third party. Interesting: when I delete PageNr property in my dfm file (unit1.dfm), then pops up : EReadError with message 'Property PaperHeight does Not exist'. when I delete PaperHeight then it will claim PaperWidth and so on...

Here is piece of dfm file:

 object pg1: TPage
    Left = 128
    Top = 144
    Width = 798
    Height = 1127
    PageNr = 0
    PaperHeight = 1123
    PaperWidth = 794
    PaperSize = psA4
    PaperOrientation = poPortrait
    TabOrder = 0
    object bscshp4: TBasicShape
      Left = 112
      Top = 64
      Width = 105
      Height = 105
      PrintKind = pkNormal
      PrintGroupIndex = 0
      Zooming = 100
      Transparent = False
      Repeating = False
      PageRepeatOffset = 1
      ShapeStyle = ssVertical
      LinePosition = 2
    end
    object bscshp5: TBasicShape
      Left = 288
      Top = 24
      Width = 105
      Height = 105
      PrintKind = pkNormal
      PrintGroupIndex = 0
      Zooming = 100
      Transparent = False

What the hell happens ??????? I have never seen that. I compiled the unit several times... Encoutered no problem. Maybe the cause is beyond this. I feel completely powerless.

A: 

Check for multiple copies of the .DFM file on your hard disk. This usually happens when the .DFM that's actually being linked into your executable isn't the one you're seeing in the IDE.

Also, are you building with runtime packages? It could also be the case that your application is being built with a different version of a package than the one loaded at runtime, as well. The error loading the .DFM's properties could come from the package looking for something not in the app (or more likely, vice versa - the app's expecting something that doesn't exist in the package when the .DFM is loaded from it).

Ken White
That over is my own component wrote 2 days ago. In the interface I have references to various units, which are part of other packages. I compile project in the default directory. Unit1.pas, Unit1.dfm. There is no other Unit1.dfm. But PageNr property normal exists and is declared. I see it in Objectinspector too... It happens sometimes, the best practice seems to restart Windows... Now I deregistered TPage and registered TBookPage instead. It looks like it works so far. I will se later, what will happen...
lyborko
+1  A: 

What you are experiencing here is a type name clash.

There is a class called TPage in ExtCtrls. If ExtCtrls is listed in the uses clause in the interface section of your unit, Delphi will "assume" that you are referring to the last declared TPage - which will have totally different properties.

If you were to add some code that to interact with a TPage object, class completion would show the methods and properties for ExtCtrls.TPage, rather than your TPage. This is why renaming to TBookPage has solved the problem.

It is can be a good practice to use a short prefix on your own controls to avoid this (e.g. use TLyPage). This is why most 3rd party controls use a similar scheme.

This can be used as quick-and-dirty way to re-implement a control - see Deltics Blog entry for an example.

Gerry
It's a Name Clash, but it's not related to the order of units in the uses clause. Every component that's available in the form editor had been register using RegisterClass(TComponentName). That allows the IDE to find the class _by name_ and then call it's virtual constructor (Create). Unfortunately (and shockingly unbelievable) Delphi doesn't throw an error when you try to RegisterClass(TComponentName) again with a different class! Because of the name clash the IDE is loading the wrong TPage and then it tries using RTTI to find the PageNr prop to set it- and obviously fails.
Cosmin Prund
My God, thank you very very much for throwing a ray of enlightenment. Really, I inspected ExtCtrls and yes - there is TPage. I was thinking in the same manner, so I tried to find TPage in Delphi's help. But there is no such class described, so I ceased to search further... Nevertheless I still feel itching in my neck, when I run apps with TBookPage. SUrely next time I will name my components with prefix... I will accept you answer a couple days later, if everything will be OK... Thanx a lot anyway... :-)
lyborko
Furthermore I have found out, that TPage introduced in ExtCtrls is TCustomControl - exactly as mine. So that probably caused the mess. (No error throw, ect... ) !
lyborko
@Cosmin, I suspect you are right here. I had forgotten the details of this. It would be good if RegisterClass threw an exception in this case.
Gerry
@Lyborko - it seems that TPage had been left out of the Delphi help for a long time - see http://www.esanu.name/delphi/Components/How%20to%20Add%20Controls%20to%20TTabbedNotebook%20and%20TNotebook.html for example. It is in http://docwiki.embarcadero.com/VCL/en/ExtCtrls.TPage_Members
Gerry