A way to do this without much actual knowledge of the VMT structure, and hence less prone to breaking when the VMT structure changes again, is using the Rtti for this. TRttiInstanceType knows the VmtSize of the associated class.
So using VmtSize and a VMT entry being a Pointer
function GetVirtualMethodCount(AClass: TClass): Integer;
var
AContext: TRttiContext;
AType: TRttiType;
begin
AType := AContext.GetType(AClass);
Result := (AType as TRttiInstanceType).VmtSize div SizeOf(Pointer);
end;
This will however include all entries inherited from the base class(es) too. Including the ones from TObject at negative offsets. But it is possible to subtract all entries from a given base class, e.g. TObject. Here is an approach with a variable base class provided:
function GetVirtualMethodCountMinusBase(AClass: TClass; ABaseClass: TClass): Integer;
var
AContext: TRttiContext;
AType, ABaseType: TRttiType;
begin
AType := AContext.GetType(AClass);
ABaseType := AContext.GetType(ABaseClass);
Result := ((AType as TRttiInstanceType).VmtSize - (ABaseType as TRttiInstanceType).VmtSize) div SizeOf(Pointer);
end;
And: When using Jedi there is a function in JclSysUtils called GetVirtualMethodCount. Although I'm not sure if this is up-to-date and correct.