admin管理员组

文章数量:1125318

I am trying to write a multi-view application using VCL and Frames. My idea is to have a client area in the main form and, depending on the state of the application, create a different frame in its Client Area.

To achieve this goal I created the main form, set its base structure and left the middle area for the frame (with the assumption that the .Align property set to alClient will take care of filling it). After that I created a base frame class TAppFrame to hold a constructor and a set of methods that are common to all views in the application. Then I created the TFrameMain = class(TFrame) initially (via the IDE option to create a frame). It loaded fine the first time, then the problem started:

After designing the Frame I included the necessary unit (namely App.FrameUtils) and changed ancestor of TFrameMain to TAppFrame. After saving and closing it, on the next opening I get a popup raised during the load of the DFM view:

The frame started looking like a form (with borders and so) during design time:

And this error started when running the application:


Now the curious part is: I'm able to get it set and running if I follow these steps:

  1. Change the ancestor of the TFrameMain back to TFrame again.
  2. Save and close the Unit tab in the editor.
  3. Reopen the tab and face this error, now complaining about TabOrder: (Must do to get it working fine again).
  4. Change the ancestor of TFrameMain back to TAppFrame and Save it. It doesn't matter if I close it or not, in any circumstance reopen it (or I get back to the third paragraph of this question).
  5. Compile and the application displays as it should:

Following I attached the declaration of both Frame classes and the definition of its constructors aswell, so it can be of some help for clarification.

TFrameMain (On the 5th step state)

  TframeMain = class(TAppFrame)
    scGPPanel1: TscGPPanel;
    btnDownloadMostRecent: TscGPGlyphButton;
    scGPPanel2: TscGPPanel;
    lblLastUpdate: TscGPLabel;
    lblCurrentVersion: TscGPLabel;
    lvVersions: TscAdvancedListBox;
    procedure btnDownloadMostRecentClick(Sender: TObject);
  private
    { Private declarations }
    FApplicationProgressBar: TscGPProgressBar;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent; AProgressBar: TscGPProgressBar);// override;
    procedure UpdateScreenInfo();// override;
  end;

implementation

constructor TframeMain.Create(AOwner: TComponent;
  AProgressBar: TscGPProgressBar);
begin
  FApplicationProgressBar := AProgressBar;
  inherited Create(AOwner);
end;

TAppFrame

  TAppFrame = class(TFrame)
  public
    constructor Create(AOwner: TComponent); overload; // Just to get rid of the hiding warning.
    constructor Create(AOwner: TComponent; AProgressBar: TscGPProgressBar); overload; virtual; abstract;
    procedure UpdateScreenInfo(); virtual; abstract;
  end;

implementation

constructor TAppFrame.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
end;

I can't really write a TL;DR for this because I have no clue on what's happening at all.

Thanks for your time!


Edit (via mobile, sorry for the bad formatting).

The following question has the path to solving this issue which is changing the inheritance in the DFM file:

How to make an old form inherit from another?

The point of my question is the reason why it happens at all, given that:

  1. The IDE changes the properties in the DFM file, so why doesn’t it change the inheritance too? After all, it does check the .pas file.
  2. The TAppFrame inherits TFrame and does not change the access modifier of any. How does it fail to find given property?

Edit 2:

First, the item 1. above has proven to be false. What the IDE does is remove the properties it could not find from the DFM, so it does not change the complete set of properties, only removes the ones it couldn't find.

These two answers bring insightful details to this issue:

  1. How to properly define a TCustomFrame's child class?
  2. Delphi Frame inherited property does not exist

It's clear that there are some rules to the correct creation of inherited frames, but not why they are needed. Worth of note is that the base frame TAppFrame adds functionality only, it doesn't touch the visual elements.

本文标签: