Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancel / abort creating a new form in Delphi / C++Builder?

Is there any way to cancel or abort form creation from within the form's OnCreate event handler or C++Builder constructor?

Basically, I'd like to be able to call Close() from OnCreate or from the constructor and have it skip showing the form altogether. I have several forms that as part of their initialization may determine that they shouldn't be shown at all. (I realize that I could split apart this portion of the initialization or add extra checks from the calling form or similar, but if there's a way to cleanly do all of this from within OnCreate or the constructor, that seems simplest.)

Edit: In response to a few comments, some of the don't-show-at-all logic is UI logic and not business logic; the form might display a confirmation before showing, or it might use a common dialog box to get input for the form then abort if the user cancels that dialog. (Some of it is business logic and needs to be refactored, but it's often hard to find the time to refactor everything that needs it.)

like image 866
Josh Kelley Avatar asked Aug 31 '09 15:08

Josh Kelley


3 Answers

You can always call Release in the OnCreate handler, but that will lead to the form quickly appearing and then being closed. Not a very professional thing.

So here's another idea. Let the forms have a public function or property to return whether they are in fact to be shown. Then where you would usually have

TheForm := TSomeForm.Create(Self);
TheForm.Show;

you would have

TheForm := TSomeForm.Create(Self);
if TheForm.ShouldAppear then
  TheForm.Show
else
  TheForm.Release;

Having said that - any other way of coding this (so you don't create a form that will be immediately destroyed) is surely better. Especially if you want to maintain a clear separation between UI and business layer it would be much better to have the code that decides whether the form is to be shown outside of the form. Create the form only after you have made the decision.

like image 104
mghie Avatar answered Sep 30 '22 05:09

mghie


I would think it is much better to not even have to create the form in the first place. IF you're performing some logic which determines that the form is not even necessary, and that logic contains state which is important to the form, then re-factor the logic into a separate object (or even a data module) and pass the object to the form as a property. Here is a simple example (using the object approach):

UNIT1

type
  TOFormTests = class
    fStateData : string;
  public
    function IsForm1Needed( someparam : string) : boolean;
    property StateData : string read fStateData write fStateData;
  end;

UNIT2

uses
  : 
  UNIT1;

type
  TForm1 = class(tForm)
  :
  procedure SetFormTests(value : tOFormTests);
  property FormTests : TOFormTests read fFormTests write SetFormTests;
end;

procedure SetFormTest(Value:TOFOrmTests);
begin
  fFormTests := Value;
  // perform gui setup logic here.
end;

then someplace in your code, where you are wanting to determine if you should show your gui or not use something like the following:

var
  Tests : TOFormTests;
begin
  tests := tOFormTests.create;
  try
    if Tests.IsForm1Needed('state data goes here') then
      begin
        Form1 := tForm1.create(nil);
        try
          Form1.FormTests := Tests;
          if Form1.ShowModal = mrOk then
            // handle any save state logic here.
          ;
        finally
          FreeAndNil(Form1);
        end;
      end;
  finally
    freeAndNil(Tests);
  end;
end;

This also assumes that the form is NOT in the auto-create list and needs to be shown modal.

like image 24
skamradt Avatar answered Sep 30 '22 03:09

skamradt


Use Abort in the constructor. It raises a silent exception. If an object has an exception in the constructor, then the destructor is called and the memory released. The advantage of Abort is then you don't need to worry about an exception dialog being displayed if you don't add exception handling code.

like image 30
Jim McKeeth Avatar answered Sep 30 '22 05:09

Jim McKeeth