user1175743
user1175743

Reputation:

How do I override a method when the compiler says it's "not found in base class"?

I have a custom component I am creating which is derived from TCustomListView.

I need to override a method, specifically the GetImageIndex method, but I cannot seem to access it.

The component I am making needs to behave like a TListView but without a lot of the published properties and methods it has, as I will be creating my own in the component hence I derive it from TCustomListView instead.

In my component I tried accessing the GetImageIndex like so:

TMyListView = class(TCustomListView)
  strict protected
    procedure GetImageIndex(Sender: TObject; Item: TListItem); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
end;

procedure TMyListView.GetImageIndex(Sender: TObject; Item: TListItem);
begin
  inherited;
  // Make my changes
end;

Obviously the above is shortened down for the purpose of the example.

I am met with a compilation error of:

Method GetImageIndex not found in base class

How do I access and override this method from my component? These type of methods will not be published or available at runtime as I will be doing the changes the component needs, so I would like to know how to access and change it?


Solution

Based off the information provided by David Heffernan, I have a working solution. He did provide code to one way of achieving this and information to another way, the code provided still proved troublesome for me so I attempted to do option 1 that he stated.

Here it is:

protected
    procedure GetImageIndex(Sender: TObject; Item: TListItem); // note not to override

and the constructor:

constructor TMyListView.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  OnGetImageIndex := GetImageIndex;
end;

If this is still wrong please let me know but from quick initial tests I see no problem.

Upvotes: 4

Views: 2688

Answers (1)

David Heffernan
David Heffernan

Reputation: 612784

The TCustomListView.GetImageIndex method is a non-virtual method. You cannot override it.

Your options for customisation here are:

  1. Supply an event handler for the OnGetImageIndex event.
  2. Handle the LVN_GETDISPINFOA and LVN_GETDISPINFOW notification codes in a CN_NOTIFY message handler, and supply your own customised behaviour there.

The former option should be obvious. The latter option looks like this:

type
  TMyListView = class(TCustomListView)
  protected
    procedure CNNotify(var Message: TWMNotifyLV); message CN_NOTIFY;
  end;
....
procedure TMyListView.CNNotify(var Message: TWMNotifyLV);
begin
  case Message.NMHdr.code of
  LVN_GETDISPINFOA, LVN_GETDISPINFOW:
    ; // add your customisation here
  else
    inherited;
  end;
end;

Note that you may choose to call inherited in all scenarios, and then apply customisation in addition to that. It all depends on your needs.

Upvotes: 8

Related Questions