I've just had an epic derp moment...


I've just had an epic derp moment...

I inherited a form, add a few new controls and the related scaffolding.
Then I thought - wow - it would be nice to have a generic type property on that form - so I added to the declaration of the inherited form, and used the type in a couple of non visual related methods.  Saved, close the unit, instantiated the form elsewhere, using the appropriate T substitute.

The form shows up and goes BANG on the first new control reference in the code.  It was nil. All the new controls were nil.
I open the new form - or rather I try: Parent not found - so I can't open the form designer.

Turns out that adding a generic wasn't such a good idea after all.
Interesting that it compiled, really - considering the visual inheritance was totally broken.

Edit: But it would have been super neat! :P

Comments

  1. I'm not quite sure that's a derp moment - if you think of a form as a class, which it is, it makes absolute sense to be able to have it generic, just like any other. (Whether that's a good idea for a UI control or not...) What if you create it entirely in-code, without streaming via the DFM?

    ReplyDelete
  2. Obviously that will work. It's the streaming that cannot handle this.

    ReplyDelete
  3. Not sure if that would work as you are still breaking the visual inheritance which screws up the form initialization. Besides, creating controls in code is so 1992 :P

    ReplyDelete
  4. I've got several forms where I use generics, and they've been working fine in Delphi 2010 and Delphi XE5 (we haven't migrated further yet).

    Like this:
    TBaseForm = class(TForm)
    TMasterForm = class(TBaseForm);
    TMasterForm = class(TMasterForm)
    TForm1 = class(TMasterForm); // where TZone descends from TEpgBaseData

    ReplyDelete
  5. Martijn Coppoolse Do they use visual inheritance where you add new components in the designer?

    ReplyDelete
  6. We can't edit a TNewForm = class(TBaseForm), but I do see how I can take a "final" form and add a descendent with a generic type - and that may actually work for me - but that was not what I was trying.
    #derp

    ReplyDelete
  7. I've actually managed to make this work a few times.  You do it in two steps.

    type TMyForm = class(TForm)
    // controls and basic logic go here
    end; //has a corresponding DFM

    type TMyForm = class(TMyForm)
    //generic stuff goes here
    end;

    This should work for you.

    ReplyDelete
  8. Mason Wheeler Yes, that works - but that was not the approach I tried, hence the derp.

    ReplyDelete
  9. Wow.  A Generic Form.  Good GIF choice.

    ReplyDelete
  10. Warren Postma Forms are classes too. Why shouldn't they be able to take type parameters like any other class?

    ReplyDelete
  11. They are Classes, but they are not just regular Classes. They are Forms.  They have persistent data. How would DFM Loading in a generic Form work since the form class name is embedded in the DFM?

     Form inheritance is a sucky feature in Delphi, and shouldn't be used, even without Generics.    Now combine Form Inheritance's regular suckiness, with generic suckiness. That's why.

    Let's also ask how would Application.CreateForm work? You would construct a form and pass the generics and the Application would construct a generic form?  Ugly.

    ReplyDelete
  12. What happens if the form class name in the DFM is edited to include the ?

    ReplyDelete
  13. David Millington Most likely it fails to parse, because the form streaming system doesn't know anything about generics.

    ReplyDelete
  14. Mason Wheeler Yeah, I'd expect it to get to the < and fail with an unexpected token. But you never know...

    ReplyDelete
  15. Lars Fosdal Ah, no, they didn't use visual inheritance. We stopped using that a long time ago because of the many limitations associated with it.
    (Sorry for the late response, had to leave in a hurry).

    ReplyDelete
  16. Martijn Coppoolse We use visual inheritance in a very limited fashion - i.e. we have a base form which has some graphics and title fields and a main panel. This form is the base for numerous dialogs which add controls of their own.  The dialog I was working on was a list selection tool - and the general idea was that I could make a generic one for our class hierarchy - so that the selection parameter actually returned the object instance, and not just some index or similar.
    As outlined by others above, I can still achieve this as long as I move the generic bits to a descendent form who doesn't have a visual form of it's own.

    ReplyDelete

Post a Comment