inheriting a standard component lazarus / 31-LCL ---------------------------------------------------------------------- codifies · 2021-08-12 16:16 is there away to inherit a standard component, so I can override just one procedure ? ideally I'd like something like a unit in a project, rather than having to make a new component and recompile the whole IDE ---------------------------------------------------------------------- Remy Lebeau · 2021-08-12 17:03 Quote from: codifies on August 12, 2021, 06:16:25 pmis there away to inherit a standard component, so I can override just one procedure ? ideally I'd like something like a unit in a project, rather than having to make a new component and recompile the whole IDE Have you tried using an interposer class?  Not sure if this works in FreePascal, but in Delphi, you can do the following: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit MyForm; interface uses  ..., StdCtrls; type  TButton = class(StdCtrls.TButton)    ...  end;   TForm1 = class(TForm)    Button1: TButton;    ...  end; implementation ... end.  Alternatively: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit MyButton; interface uses  ..., StdCtrls; type  TButton = class(StdCtrls.TButton)    ...  end; implementation ... end. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit MyForm; interface uses  ..., StdCtrls, MyButton; // <-- make sure MyButton is AFTER StdCtrls! type  TForm1 = class(TForm)    Button1: TButton;    ...  end; implementation ... end.  Either way, every TButton on the Form would then be your derived class. ---------------------------------------------------------------------- lucamar · 2021-08-12 17:25 Quote from: Remy Lebeau on August 12, 2021, 07:03:07 pmHave you tried using an interposer class?  Not sure if this works in FreePascal, but in Delphi, you can do the following: [... etc ...] It works in Free Pascal exactly as in Delphi (from the programmer's p.o.v.). The issue at hand here (IMHO, and also for the interposer which is, after all, just a "normal" derived class) is rather whether the "new" method is an override (possible if the method in the base class is virtual), an overload (same name but different signature, almost always possible though not usually recommended) or a sustitution (same signature, non-virtual base method). In this last case the new method must almost always (re)implement at least part(s) of the base method, e.g. those dealing with interfacing with the widgetset or the IDE, if any, and similar. These kind of things can be easily dealt with in the other two cases (in the first by using inherited and in the second by calling the base one) but in the last one the base is thoroughly hidden (and the compiler warns about this fact) so parts of it have usually to be copied over and adapted. Not that it can't be done, but it's definitively not something for the faint of heart ---------------------------------------------------------------------- codifies · 2021-08-12 17:32 I tried making a new component and somehow hosed lazarus so that option is out for now, just too easy to mess things up... Not sure I follow interposer classes, what would happen on the designer? To be honest I think I'll just leave Lazarus for another few years, redesigning data controls to show actual database text fields as text not (MEMO) just shouldn't be required... ---------------------------------------------------------------------- Remy Lebeau · 2021-08-12 21:24 Quote from: codifies on August 12, 2021, 07:32:59 pmNot sure I follow interposer classes https://zarko-gajic.iz.hr/delphi-interceptor-classes-tbutton- classtbutton/ http://caryjensen.blogspot.com/2014/01/two-approaches-to-sub- classing.html Quote from: codifies on August 12, 2021, 07:32:59 pmwhat would happen on the designer? It should treat them just as you would expect it to. ---------------------------------------------------------------------- lucamar · 2021-08-12 21:50 Quote from: codifies on August 12, 2021, 07:32:59 pmNot sure I follow interposer classes, what would happen on the designer? You can use the standard control in the designer; only you will not have access in the object inspector to any new published properties you might have. For example, in one of my own programs I use an interposed TMemo (which now resides in its own unit) and the mainform contains just a TMemo declaration. Only, my MemoEx unit is added after StdCtrls (where the standard TMemo resides), so whenever there is a "TMemo" declaration in the source it refers to my TMemo, not the one in StdCtrls. However, the IDE knows nothing at all about this, since my unit doesn't register nor exposes my TMemo to the IDE in any way, other than as any other normal source, so for design purposes the IDE creates and uses a normal, standard TMemo ---------------------------------------------------------------------- codifies · 2021-08-13 02:00 thanks for those links made it much clearer! especially the complete example... certainly a lot less risky than potentially hosing the ide! why on earth the whole IDE needs to be recompiled just for a component is beyond me, components should be in their own little libraries - with a standard api all nice and plugin like ! ---------------------------------------------------------------------- lucamar · 2021-08-13 05:32 Quote from: codifies on August 13, 2021, 04:00:51 amwhy on earth the whole IDE needs to be recompiled just for a component is beyond me, components should be in their own little libraries - with a standard api all nice and plugin like ! Very, very basically the IDE needs to be able to create controls/components on-the-fly and for that it has to have their code accessible at run-time. Of course, that can be done by having packages be akin to a DLL which can be loaded when needed, as does Delphi. Problem is that Lazarus needs a homogeneous cross-platform way to do it, which is not as easy as it sounds, so instead it recompiles itself to include the needed code inside its own. However, work on dynamic packages has been (slowly) in progress for quite some time now and one of this days we'll have them, just as Delphi users have from day one and we'll be able to forget about recompiling the IDE each time we want a new design-time package installed ---------------------------------------------------------------------- PascalDragon · 2021-08-13 06:59 Quote from: codifies on August 13, 2021, 04:00:51 amwhy on earth the whole IDE needs to be recompiled just for a component is beyond me, components should be in their own little libraries - with a standard api all nice and plugin like ! You simply can't just use libraries as each library would have their own "instance" of the RTL and other shared classes and those would be considered incompatible then. As lucamar said the solution for this is dynamic packages (essentially libraries plus a whole load of compiler magic), but it's a work in progress as it's complex to get right especially with multi platform support. ---------------------------------------------------------------------- egsuh · 2021-08-13 07:11 If you need to change only one procedure, think helpers. I'm trying a few Interposers --- they are fine as well. ---------------------------------------------------------------------- lucamar · 2021-08-13 11:32 Quote from: egsuh on August 13, 2021, 09:11:54 amIf you need to change only one procedure, think helpers. I'm trying a few Interposers --- they are fine as well. Yeah, for relatively "simple" things a helper should be preferred and not just for the "coolness" factor (which, let's be honest, it is there ) but because they're lighter-weighted compared to a child (not by much, mind, but enough) and you code it as an extension of the base class. Which is all class helpers really are, after all. But as soon as you start doing even mildly "heavy" modifications to the behaviour of the base class (like, say, adding a new field) a child class (whether interposed or not) is the way to go. Of course, it need not be instalable from a package, registable with the IDE and requiring recompilation of this last. Only when your new class is a component/control which must be insertable and modifiable at design-time (i.e. appearing in the O.I. and writable/readable to/from the form resource) it needs be so; otherwise just creating a package, opening it in the IDE and compiling it is enough for the IDE to remember where it is and you can add the package to a project's requisites, declare and use instances of the class, etc. If anyone is interested I can make a write-up explaining the process through which I went to end up with my TMemo interposer. It's mildly interesting and entertaining and would allow anyone to understand how and why one decides between helper functions, full helpers or (interposed) child classes. Not that I'm a guru or anything like that, though ... just a little experience ---------------------------------------------------------------------- codifies · 2021-08-14 07:26 Quote from: PascalDragon on August 13, 2021, 08:59:07 am... each library would have their own "instance" of the RTL and other shared classes and those would be considered incompatible Can you expand on this? in what way would they be "incompatible" I'm guessing pascal and C at this level must be working in quite a different way! ---------------------------------------------------------------------- jamie · 2021-08-14 13:01 Please detail the method you wish to intercept and what you would like to do with this said method? I am sure if you could reveal that little tidbit someone here could offer up a solution, most likely a simple one.