event property will not create lazarus / 9-Editor ---------------------------------------------------------------------- mangakissa · 2016-10-25 14:51 The last few times a procedure will not put in unit when I dubbleclick on a event item in object inspector. For my application I use a baseform. In that baseform some event properties like Oncreate, OnShow and Onclose are created and filled. If I create a new form the baseform is inherited. Also the filled in procedures are showed in the object inspector. Normally, when I dubbleclick on a event property like OnCreate, the inherited property will be placed to the property of the form itself. Then I have to dubbleclick again on the property for creating a procedure in the unit of the form. Nothings happens and the editor complains he can't jump to the desired procedure and wants to open the baseform for searching the procedure. It's not good. The IDE has to create a new event procedure in the unit of the form like this: 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 procedure TForm1.Oncreate(sender : TObject);begin  inherited;  //own codeend;  Lazarus 1.6 / FPC 3.0 Windows Vista SP2 64 bits ---------------------------------------------------------------------- mangakissa · 2016-10-31 10:58 No one? ---------------------------------------------------------------------- Thaddy · 2016-10-31 11:01 What? The OnCreate is an event, not a constructor. ---------------------------------------------------------------------- rvk · 2016-10-31 12:50 Quote from: mangakissa on October 25, 2016, 04:51:45 pmIn that baseform some event properties like Oncreate, OnShow and Onclose are created and filled. ... It's not good. The IDE has to create a new event procedure in the unit of the form like this: The IDE won't create an event with "inherited;" in it because you can't/don't need to call inherited for an event. The inherited should be called for DoCreate which you should override in your base-form if you want to do something in that. How did you declare the base?? You say you already filled in OnCreate but you shouldn't do that. You should override DoCreate in the baseclass to do what you want and calling inherited DoCreate will again call your FOnCreate in your child-forms. ---------------------------------------------------------------------- totya · 2016-10-31 14:00 Quote from: mangakissa on October 25, 2016, 04:51:45 pmIf I create a new form the baseform is inherited. Also the filled in procedures are showed in the object inspector. How do you create the new form? File/New Form? When you do this, new unit created of the new form, this is different from base form, so the events are differents too. Can you show examples for your problem? (delete own code and insert only "//" etc). Can you show the .lpr file? ---------------------------------------------------------------------- mangakissa · 2016-10-31 16:05 Small example included. In the image you see Tfrmbase.Formshow from the baseform. If I click on property OnShow Tfrmbase.Formshow will be replaced by Formshow. but there's no procedure created. When I click again on the property, the procedure can not be found (se in demo form frmbasedesc). But this must be local. I created a second form to let you show what's happend (or not) ---------------------------------------------------------------------- totya · 2016-10-31 16:25 Hi! Okay, I understand your problem, but to tell the truth, I don't do it similar  in my life. I'm thinking on it. Your problem: you create a form, and you create descendant form from this "base" form, and the forms event (via object inspector) doesn't work how you excepted. 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 type  { TFrmBase }  TFrmBase = class(TForm)    procedure FormShow(Sender: TObject);  private    { private declarations }  public    { public declarations }  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 type  { TFrmBasedesc1 }  TFrmBasedesc1 = class(TFrmBase)  private    { private declarations }  public    { public declarations }  end; edit: FrmBasedesc1 caption is same as FrmBase. ---------------------------------------------------------------------- rvk · 2016-10-31 16:38 In my opinion you should never use user-event-names in your baseform. The IDE looks for a FormShow() in your hierarchy and will find that TFrmBase.ShowForm() and only get confused. What is your purpose? If you want something like this just override DoShow like this: (but NEVER EVER use ShowForm() in the base-class) 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 type  TFrmBase = class(TForm)  protected    procedure DoShow; override;//..procedure TFrmBase.DoShow;begin  // inherited; DO NOT CALL INHERITED if you want to switch to either/either/  if Assigned(OnShow) then    OnShow(Self)  else    ShowMessage(self.name)end; This will call the ShowMessage in the base-class if there is no OnShow assigned in the descendant. Otherwise only the OnShow of the descendant is executed. ---------------------------------------------------------------------- mangakissa · 2016-10-31 19:21 Okay I have to defend myself. Normally the baseform has more components on form. When a new form is created (inherited from the baseform) all the GUI-components will be seen on form. But when code (Oncreate / onForm / onActivate / OnClose) on the baseform is put, the code will be used for all the inherited forms. This is very usefull when you use classes for all inherited forms. The baseform has the object and create / release it in memory. Every form calls the same code in baseform. Everybody knows that (I hope). Now the inherited form does something more than using the objects. It can handle some other values for the form itself. Example. baseform: 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 type TBaseform = class;begin  fFormname : string;end; procedure TBaseform.Formcreate(Sender : TObject)begin  object1 := TObject.create;  object2 := TObject.create;  fFormname := name;end;  inherited form: 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 procedure TInheritedform.Formcreate(Sender : TObject)begin  inherited;  object1.dosomething;  value := 'Hello';end; procedure TInheritedform.showname;begin  //this is just an example of inheritence.  //I know that a formname can called directly  showmessage(fFormname)end;  Now the real problem. Lazarus 1.6 doesn't create a local procedure when dubbleclick on the property in the objectinspector. I tested it in Lazaris 1.4 and that's working. The problem relies on 1.6. It's not a problem of the OS. Tested on Windows 10 gives the same results. ---------------------------------------------------------------------- totya · 2016-10-31 19:32 I think everyone will be much happier, if you tell us, what is your concept. Many similar windows on the screen at once? What are the differents between these? For example you can create form dinamically. Or you can use frames. ---------------------------------------------------------------------- rvk · 2016-10-31 19:46 Quote from: mangakissa on October 31, 2016, 08:21:59 pmOkay I have to defend myself. I do understand what you want now... (so you always want the FormShow of the base-class to execute. But my stand remains... NEVER EVER use/create the OnCreate in the base-class. Use DoCreate for that. For OnCreate, use DoCreate. For OnShow, use DoShow. etc. Then the descendant is free to assign a OnShow if it wants. If you always want to execute the code in FormShow/FormDestroy you would use DoShow/DoDestroy. Like this for you example: 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 type  TBaseform = class;  protected    procedure DoCreate; override;    procedure DoDestroy; override;  public    fFormname : string;  end; procedure TBaseform.DoCreate;begin  object1 := TObject.create; // first create  object2 := TObject.create;  fFormname := name;  inherited; // then call inherited which in turn calls OnCreate for descendantsend; procedure TBaseform.DoDestroy;begin  object1.Free;  object2.Free;  inherited;end; And in the descendant you can use the events: 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 procedure TInheritedform.Formcreate(Sender : TObject)begin  object1.dosomething;  value := 'Hello';end; procedure TInheritedform.showname;begin  //this is just an example of inheritence.  //I know that a formname can called directly  showmessage(fFormname)end; So the basic rule is don't mess with events (or assign them) in the base-class. Only use events in the last part on your form and in the IDE, not in base-classes. For base-classes you override the DoProcedures. ---------------------------------------------------------------------- mangakissa · 2016-10-31 20:59 This discussion will not solve my problem. ---------------------------------------------------------------------- totya · 2016-10-31 21:04 Quote from: mangakissa on October 31, 2016, 09:59:15 pmThis discussion will not solve my problem. and what is your problem? I asked this in reply #9. ---------------------------------------------------------------------- rvk · 2016-10-31 21:46 Quote from: mangakissa on October 31, 2016, 09:59:15 pmThis discussion will not solve my problem. Ok. Solution: None (if you keep working with assigning events in base- classes). QuoteWhen writing components, you should not use the event handlers to implement custom behaviour. Instead you should override the code calling these event handlers.http://stackoverflow.com/questions/6020534/onclick-event- override ---------------------------------------------------------------------- mangakissa · 2016-11-01 08:06 Quote from: totya on October 31, 2016, 08:32:40 pmI think everyone will be much happier, if you tell us, what is your concept. Many similar windows on the screen at once? What are the differents between these? For example you can create form dinamically. Or you can use frames. My example uploaded just tell my concept. All my forms are inherited from the baseform. Nothing is created dynamically but @designtime. Frames are nice, but doesn't do inheritence of components. But your all mistaking about the OnCreate event. I'm not talking about the constructor of the form, but of the property Oncreate of the object inspector. This is creating TForm1.formCreate(Sender : TObject) which will execute after the constructor. Many people thinks you override the constructor, but that's not true.  Constructor TForm1.Create(TheOwner: TComponent); is something different which I don't use (only with livebindings and objects in Delphi ) Something is broken in version 1.6. Version 1.4x is working fine. I shall create a bug report. ---------------------------------------------------------------------- mangakissa · 2016-11-01 08:31 The problem is not only relayed on the form events, but by all events called by a baseform. another example: On my baseform I have created a toolbar with buttons and an actionlist. Lets say two buttons are created: prior and next. These are connected to an action in the actionlist. In the basecode some like this is put: 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 procedure TFrmGUIbasis.acNextExecute(Sender: TObject);begin  if datasource1.DataSet <> nil then    datasource1.DataSet.RecordNextend; Every new inherited form uses this code if I push the button. Now I have a new created inherited form with a listbox on it. The next button gets other code to scroll the listbox. So dubbleclick on the event OnExecute of the event should create a new procedure. In the object inspector TFrmGUIbasis.acVerderExecute will changed to acVerderExecute. This should be a local procedure overriden to  TFrmGUIbasis.acNextExecute(Sender: TObject);. Nothing happens. Dubbleclick on the property again comes with this error message: QuoteError Unable to show method. Please fix the error shown in the message window, which is normally below the source editor. But a new procedure should be created in the editor. I hopes this is more clearly. ---------------------------------------------------------------------- rvk · 2016-11-01 08:44 Quote from: mangakissa on November 01, 2016, 09:06:34 amBut your all mistaking about the OnCreate event. I'm not talking about the constructor of the form, but of the property Oncreate of the object inspector. This is creating TForm1.formCreate(Sender : TObject) which will execute after the constructor. Many people thinks you override the constructor, but that's not true.  Constructor TForm1.Create(TheOwner: TComponent); is something different which I don't use (only with livebindings and objects in Delphi ) And I'm also not talking about overriding the constructor Create(). I'm talking about overriding DoCreate(). This is a special procedure which is designed to call OnCreate-event. Events are not meant to be implemented in base-forms. Every form-event has a procedure by which it's called. If you want something done in the base-class for that event you should do it in the override of that calling-procedure. Although I still think events are not meant for base-forms you can do what you want in Delphi. Double-clicking the event in a descendant does create a new FormShow() (although without the inherited). The inherited will never be added (because events are not meant that way) but you can submit a bugfix for the IDE that is doesn't jump to the base-class-event-procedure. I still feel this is bad design and you need to do the things in DoShow if you want to use them in a FormShow-event in descendants and not use a FormShow-event in the base-class for that (same with the other DoCreate, DoDestroy etc). ---------------------------------------------------------------------- totya · 2016-11-01 08:45 Quote from: mangakissa on November 01, 2016, 09:06:34 amMy example uploaded just tell my concept. All my forms are inherited from the baseform. Nothing is created dynamically but @designtime. Frames are nice, but doesn't do inheritence of components. I give up, I think... ---------------------------------------------------------------------- Thaddy · 2016-11-01 08:55 No. see my first answer. It is not clear. But we do want to help.... Maybe you just need ctrl-shift-c? ---------------------------------------------------------------------- offline · 2016-11-30 19:05 Quote from: mangakissa on October 25, 2016, 04:51:45 pmThe last few times a procedure will not put in unit when I dubbleclick on a event item in object inspector. Hello, few times? For me dbl click on events does not work at all on inherited forms. Lazarus 1.6.2 Win10