Creating descendants of TComponent lazarus / 31-LCL ---------------------------------------------------------------------- egsuh · 2021-01-19 01:44 I'd like to create my custom treeview like following, adding some pre- defined actions so that I do not have to write the same codes (like DragDrop event handlers, etc.) multiple times.  Following codes compiles well, but I haven't applied yet (not executed yet). Please comment on the following approach, and better ways, if any.  Can I use TCustomTreeView instead? 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    { TaqTreeView }    TaqTreeView = class(TTreeView)      procedure DragDrop(Sender, Source: TObject; X, Y: Integer);      procedure DragOver(Sender, Source: TObject; X, Y: Integer;          State: TDragState; var Accept: Boolean);   private      function MoveTreeNode(SNode: TTreeNode; TTV: TTreeView): TTreeNode;   public    constructor Create(AnOwner:TComponent);   end; implementation procedure TaqTreeView.DragOver(Sender, Source: TObject; X, Y: Integer;  State: TDragState; var Accept: Boolean);begin     // .....        Accept := True;end; procedure TaqTreeView.DragDrop(Sender, Source: TObject; X, Y: Integer);begin     //......end; constructor TaqTreeView.Create(AnOwner: TComponent);begin   inherited Create(AnOwner);    OnDragDrop:= DragDrop;   OnDragOver:= DragOver;end; ---------------------------------------------------------------------- Blaazen · 2021-01-19 02:12 The way you do it is wrong. Ancestors already have (virtual) methods DragDrop and DragOver. You implement them again and assign them to events. You'd better override those methods (mark them override;) and call inherited; in their bodies. Also, mark constructor with override; because it's virtual too. Side note: Assigning events in code should be (in {$mode objfpc}):    OnDragDrop:=@DragDrop;    OnDragOver:=@DragOver; but do not use it here. ---------------------------------------------------------------------- egsuh · 2021-01-19 03:01 @Blaazen Thank you Blaazen, I wanted this kind of comments. But it says that it should be controlled by OnDragOver handler. QuoteWhen an OnDragOver handler is installed, Accept is set to True and can be changed by the handler. at https://lazarus- ccr.sourceforge.io/docs//lcl/controls/tcontrol.dragover.html Anyway I might have to override DragOver method. Regarding @ before function name, I'm using {$mode Delphi} so I do not need @. ---------------------------------------------------------------------- Blaazen · 2021-01-19 06:24 Some drag method of LCL calls DragOver and DragOver calls OnDragOver (if there's any). 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 TControl.DragOver(Source: TObject; X,Y : Integer; State: TDragState;  var Accept:Boolean);begin  {$IFDEF VerboseDrag}  DebugLn('TControl.DragOver ',Name,':',ClassName,' XY=',IntToStr(X),',',IntToStr(Y));  {$ENDIF}  Accept := Assigned(FOnDragOver);  if Accept then    FOnDragOver(Self,Source,X,Y,State,Accept);end; So you declare 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 DragOver(Sender, Source: TObject; X, Y: Integer;          State: TDragState; var Accept: Boolean); override; and now it's up to you. You probably don't need to call inherited. You can manage calling of OnDragOver yourself or do not use it at all etc. 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 TaqTreeView.DragOver(Sender, Source: TObject; X, Y: Integer;  State: TDragState; var Accept: Boolean);begin     // .....       Accept := True;end; ---------------------------------------------------------------------- egsuh · 2021-01-19 07:45 Thank you for sharing these codes. I looks like I don't have to assign anything to OnDragOver handler, as you said. This is good for me for convenience. ---------------------------------------------------------------------- PascalDragon · 2021-01-19 08:00 Quote from: egsuh on January 19, 2021, 02:44:07 amCan I use TCustomTreeView instead? The difference between TTreeView and TCustomTreeView is mainly that the former provides various properties as published. So if you want to control which properties are published and which are not (especially if you don't want some published that TTreeView declares as such), you better inherit from TCustomTreeView. ---------------------------------------------------------------------- egsuh · 2021-01-19 08:00 But I cannot override TTreeview.DragOver. It says there are no method to override. There exists TControl.DragOver, but not TTreeview's one is not defined. So, I'll first check writing DragOver without assigning OnDragOver handler, and then will assign the event handler if fail. ---------------------------------------------------------------------- Blaazen · 2021-01-19 10:25 I just test and it works: 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 { TMyTreeView }   TMyTreeView = class(TCustomTreeView)   protected    procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); override;  end;The list of parameters must be the same. Unit ComCtrls must be in uses. It works for TTreeView too.