Solved

Problem with frames: Error reading form: "Class TFrameBalance not found"

Posted on 2010-09-07
12
1,350 Views
Last Modified: 2012-05-10
I'm maintaining an existing application and the developer has made almost all of the forms 'dynamic', in other words they are not declared in the DPR file, they are not 'Auto-Create' forms and they are not 'Available forms'.

So now my problem with frames:
I have a form e.g.
  ..\Balance\Forms\BalanceForm.pas
  ..\Balance\Forms\BalanceForm.dfm
It uses a frame:
  ..\Balance\Forms\BalanceFrame.pas
  ..\Balance\Forms\BalanceFrame.dfm

If I open the frame into the IDE *first*, and *then* open the form *second* I get no problem.
But if I open the form *first* I get error:
=================
Error Reading Form
Class TFrameBalance not found. Ignore the error and continue?
=================

This same problem exists throughout the application every time there is a form that uses frames.

Please help :S

Here is some code that will hopefully help:

  ..\Balance\Forms\BalanceForm.pas
unit BalanceForm;

interface

uses
 ...
  AuthResultFrame,
  BalanceFrame;

type
  TFormBalance = class(TFormWizard)
    FrameAuthResult: TFrameAuthResult;
    FrameBalance: TFrameBalance;
    ...
  private
    ...
  public
  end;

var
  FormBalance: TFormBalance;

Open in new window


  ..\Balance\Forms\BalanceForm.pas
inherited FormBalance: TFormBalance
  ...
  inherited PanelMain: TPanel
    inherited Wizard: TbsWizard
      ...
        inline FrameBalance: TFrameBalance
          ...
        end
      object WizardPageResults: TbsWizardPage
        object GroupBoxAuthResults: TRzGroupBox
          object PanelAuthResults: TRzPanel
            inline FrameAuthResult: TFrameAuthResult
            end
          end
        end
      end
  end

Open in new window


==========================================================================

 ..\Balance\Forms\BalanceFrame.pas
unit BalanceFrame;

interface

uses
 ...
  CardListFrame;

type

  TFrameBalance = class(TFrame)
    ...
  private
    ...
    FFrameCardList: TFrameCardList;
  public
    ... 
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

implementation

constructor TFrameBalance.Create(AOwner: TComponent);
begin
  inherited;
  FFrameCardList := TFrameCardList.Create(Self,GroupBoxCardNumbers,cstBalance);
  with FFrameCardList do
  begin
    Top := 17;
    Left := 2;
    OnUpdateMessage := DoUpdateMessage;
  end;
end;

destructor TFrameBalance.Destroy;
begin
  FFrameCardList.Free;
  inherited;
end;

Open in new window


 ..\Balance\Forms\BalanceFrame.dfm
object FrameBalance: TFrameBalance
  ...
  object GroupBoxCardNumbers: TRzGroupBox
    Left = 0
    Top = 65
    Width = 495
    Height = 283
    Align = alTop
    GroupStyle = gsStandard
  end
  ...
end

Open in new window


=====================================================================

  ..\Common\Forms\CardListFrame.pas
unit CardListFrame;

uses
  ...
  CardEditBoxFrame;

type
  TFrameCardList = class(TFrame)
  private
    ...
  public
    ...
    constructor Create(AOwner: TComponent; AParent: TWinControl; AScanType: TCardScanType); reintroduce;
    destructor Destroy; override;
  end;

implementation

constructor TFrameCardList.Create(AOwner: TComponent; AParent: TWinControl; AScanType: TCardScanType);
begin
  ...
  CreateEditBoxes(AOwner);
  ...
end;

destructor TFrameCardList.Destroy;
begin
  FListEditBoxes.Free;
  inherited;
end;

procedure TFrameCardList.CreateEditBoxes(AOwner: TComponent);
var
  ...
  CardEditBoxFrame: TFrameCardEditBox;
begin
  for i := 1 to (FMaxRows * FMaxColumns) do
  begin
    ColumnNumber := ((i-1) div FMaxRows) + 1;
    CardEditBoxFrame := TFrameCardEditBox.Create(AOwner);
    with CardEditBoxFrame do
    begin
      Parent := TWinControl(Self.FindComponent(Format('PanelBox%d',[ColumnNumber])));
      ...
    end;
    FListEditBoxes.Add(CardEditBoxFrame);
  end;
end;

Open in new window


  ..\Common\Forms\CardListFrame.dfm
object FrameCardList: TFrameCardList
  Left = 0
  Top = 0
  Width = 501
  Height = 170
  TabOrder = 0
end

Open in new window

0
Comment
Question by:rfwoolf
  • 6
  • 3
  • 3
12 Comments
 
LVL 36

Assisted Solution

by:Geert Gruwez
Geert Gruwez earned 125 total points
ID: 33618401
the delphi project is missing some search directories
and the directories for all the different locations of the forms/frames to the project options
that should solve the problem of opening forms in a certain order
0
 
LVL 36

Expert Comment

by:Geert Gruwez
ID: 33618406
*add* the directories ...
0
 
LVL 13

Author Comment

by:rfwoolf
ID: 33618428
Hi Geert

I did try that... once.. and the problem persisted,
but in theory that solution makes sense.
Let me try it again.
To be clear, everything is in one big folder, however there are a lot of 'subfolders', so I am going to add each and every subfolder (there are probably about 40) to the library path and try again
0
 
LVL 13

Author Comment

by:rfwoolf
ID: 33618450
Silly me, in this example I just need to add the folders for this FormBalance,
but the problem is persisting :S
0
 
LVL 13

Author Comment

by:rfwoolf
ID: 33618507
Okay sure if i add them to the project, and therefore make them an 'available' form, the problem will go away, but the developer never did this and maybe this was for a good reason?
My boss wants me to get this application compiling on my laptop, preferably exactly like the developer had it - if I add all these frames (and there are probably quite a few) to the project, perhaps there will be a difference in memory or something like that?
0
 
LVL 25

Accepted Solution

by:
epasquier earned 375 total points
ID: 33622225
I know this problem. I have experienced it many times with Delphi 5 & 7, not always, but once a project went crazy, I couldn't fix it. The "funny" thing is that I've just lost 2 hours yesterday trying *again* to solve this in my Delphi 7 project, with no success.
I believe there is a bug in Delphi, something *that is not right*. I have tried to put the frames in BPL loaded by the IDE, made sure that the units are in the search path, tried about everything I thought about, but only one thing really works : Adding the units to the project.

That is too bad because I was just reorganizing some loads of units into packages, but for the frames, that just won't do... Note that it's not a problem when compiling a form using a frame not in the project as it is in the search path, but if you open the form in the IDE, and inadvertently click OK on its error/question message about removing the component, you are screwed and will loose everything you might have changed in this frame components properties, and need to find a backup or redo it...
It happens to me a few times, and now I'm very cautious with these messages.

So, yesterday I officially stopped trying and decided to systematically add all frames units in all my projects that use them.

Just for the record, which Delphi version are you using ??
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 13

Author Comment

by:rfwoolf
ID: 33622440
epasquier>
It's so great to have your input on this one - I've done quite a bit of googling and saw different workarounds for this problem but they didn't seem to work and I had to wonder if I was doing something wrong.
One work around for example spoke about checking that in the DFM of the frame, you say *inherited* instead of *object* except for the 'base clase' ('base frame'). That's why I tried to paste all the 'original' source-code from the developer in case there's something amiss.

But like you say, the problem does appear to go away if you add the units to the project.

Yes, I'm using Delphi 7.

>>"if you open the form in the IDE, and inadvertently click OK on its error/question message about removing the component, you are screwed and will loose everything you might have changed in this frame components properties, and need to find a backup or redo it..."
--I'm not certain about this - I simply close the unit and choose not to save. This goes for any error you may get when opening a form and a class is missing, simply ignore / cancel and then close without saving.

Thanks for the helpful answer.
0
 
LVL 25

Expert Comment

by:epasquier
ID: 33622506
> --I'm not certain about this - I simply close the unit and choose not to save.
> This goes for any error you may get when opening a form and a class is missing,
> simply ignore / cancel and then close without saving.

Yes, I concur, I made a shortcut in my mind. If you don't save, then you have no problems.
But since a while back I've been able to find a "temporary" workaround by opening the frame unit, then the form, and it works even without adding the frame to the project, there have been a time when I worked unsafely.
I have a few time forgot to open all the frames before the form, and clicked OK on the error, made changes in the code just because I needed to do it quickly, then leaved it at that, and forgot about the error and dfm modifications when the time came to save the project.... Not funny when the next day you reopen the project...
0
 
LVL 13

Author Comment

by:rfwoolf
ID: 33622534
Oh and just FYI for anybody that reads this, its the updated Delphi 7, albeit it may be an 'old' update, I'm not sure if they released more than one
0
 
LVL 25

Expert Comment

by:epasquier
ID: 33622537
And I think there is 95% chance that this problem is specific to Delphi 7 IDE.
I use also 5 and 2007, but less, for very specific reasons.
I am just not sure (5%) that this problem did not occurred with one of them.
0
 
LVL 36

Assisted Solution

by:Geert Gruwez
Geert Gruwez earned 125 total points
ID: 33624346
i had the same problem in D4, D5, and D7 (can't remember using D6)
a solution was indeed to open the dependant forms/frames first and to open the container

using some versioning systems (like FreeVCL) also requires adding all units to the project
FreeVCL also has a feature to find all the units of the project
I usually do that to find all dependant units in a project i inherit
And it's easier to go back to a old (buggy) version after changes

i haven't come across this child/parent issue in D2010 yet
but i'm not using that as intensive as i used the others

indeed a check in the dfm is a good way to see if there is a child/parent relationship
the delphi IDE will sometimes mess this up.
When the needed arises to change the parent type of a class for a form or frame
then *DO NOT USE THE D7 IDE*
use notepad instead and set the interface uses unit
and then manually change the text dfm of the unit
0
 
LVL 13

Author Closing Comment

by:rfwoolf
ID: 33779094
Thanks guys. this helped.
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This video discusses moving either the default database or any database to a new volume.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now