3
votes

I have a D2006 app in which the DPR file has had numerous edits (yes, I know - you shouldn't mess with the DPR file) to accommodate such things as a splash screen, preventing a second instance of the app being started, handling of command line options that need to be processed before any forms are created, etc.

One day, I noticed that the auto-create forms list in the project options is empty - but the DPR file still has the code in there to create some of the forms.

If I try to restore all the forms that should be auto-created from the dialog, it complains Error - Call to Application->CreateForm is missing or incorrect and doesn't do anything.

  • How can I restore this connection - apart from rebuilding the DPR from scratch?
  • is it safe to manually add the CreateForm calls?
  • are there any documented rules as to what you can do in the DPR file?
  • I have a suspicion that try..except and if..else clauses in the DPR upset Delphi. Will moving as many functions as possible to a separate unit and calling them be helpful?
3
I think the code in the .dpr file is a total nightmare because the IDE makes a mess of it. I'd just make a function named Main and call it from the .dpr begin/end. Then you can gain control.David Heffernan
OK, say I do that - effectively hiding all of my functionality from the IDE - surely Delphi will still try to add all of the form creation stuff in front of my call to Main()? I'm beginning to wonder if the best way isn't to do as you suggest - put everything in a separate Main unit, remove all forms from the auto-create list dialog (and hope Delphi respects my wishes), and explicitly create what I want to be created at startup inside the Main unit.rossmcm
The solution here is to remove all the auto-creation code, remove the global variables that the IDE creates for each form, and create and destroy your forms as needed.Nick Hodges
One of the lovely things about having version control is that it's easy to revert changes you don't want. You can never get Delphi to stop modifying the code in the .dpr when you add forms, but like Nick says, you do get to change it all back again, and if you want to go with a completely self-contained memory management system you can.Warren P
@ross Yes, I would do that. And remove all those horrible global variables.David Heffernan

3 Answers

4
votes

I haven't really seen any documented rules as to what you can do in the DPR file, because I guess there are no strict rules.

The problem begins when you create a "Forms" application. (No problems with console or non-GUI applications I've noticed).
The IDE will automatically change the DPR any time you add a new Form or a DataModule to it, by assuming you want to auto-create them.

This can mess up your DPR, if it has a lot of code/compiler-directives/if-blocks/try-catch blocks etc...

So I'll tell you what my rules are, and in a short line: Keep it as simple as you can.

My DPR contains only a call to some init code and auto creates the main form only:

MyAppInit; // in AppInit unit
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;

However in the uses section I add (or keep what the IDE added) all the forms my application uses (and also application related units) - this is useful when I want to view->forms or view-units.
In-fact when I add a new form to the application, the first thing I do is go the DPR and remove the line:

Application.CreateForm(TMyNewForm, MyNewForm);

NOTE (EDIT): The IDE can be configured to NOT auto create forms (No Application.CreateForm entry will be created in the DPR). In older version of Delphi this option is under: Tools/Environment Options/Preferences -> Auto create forms. In newer versions: Tools/Options/VCL Designer/Module creation options -> Auto create forms & data modules.

At run-time, I create all my forms dynamically when I need them, and destroy them when they no longer needed. DataModules/Splash (etc...) are created on the MainForm.OnCreate event.

This method has worked for me nicely for the past few years maintaining a large scale DB application. This will probably not cover all cases, but it worked fine for my needs.


P.S: "Is it safe to manually add the CreateForm calls" - Yes. But think twice if you really need them to be auto-create by the application.

1
votes

IMHO You don't really need that AutoCreate forms from Delphi, but maybe in the casual test project.

And the dpr is just another source code file, where you're meant to write code to make things happen (or prevent it to happen), so don't worry if you lost that sincronization, which IMHO is buggy if can't read your pascal code to work properly.

If you still want to create some forms from the DPR, add the Application.CreateForm or TMyForm.Create calls manually to the file, AFAIK there's no rules against doing it that way.

1
votes

Since Delphi owns the .DPR, I put my startup logic into a separate unit for each project.

That works really well, only very few entries need to be in the .DPR.

Since that unit controls the Application.CreateForm logic too, the IDE has an empty list for that: I'm fine with that.

The only things left in the .DPR are:

  • the big uses that indicates which modules are part of your project
  • a call to Main in the startup logic unit