unit PackageInfo;
interface
uses Classes;
type
TPackageClassesAndUnits =
class
protected
FModuleName:
string;
FUnitList: TStringList;
FClassList: TList;
procedure MethodGetClass(AClass: TPersistentClass);
public
constructor Create(ModuleHandle: THandle);
Overload;
constructor Create(ModuleName:
String);
Overload;
destructor Destroy;
override;
property ClassList: TList
read FClassList;
property Units: TStringList
read FUnitList;
property ModuleName:
string read FModuleName;
end;
implementation
uses TypInfo, SysUtils, Windows;
procedure PackageInfoMethod(
const Name:
string; NameType: TNameType; Flags: Byte; Param: Pointer);
var
UnitList: TStringList;
begin
// add unit
if NameType = ntContainsUnit
then
begin
UnitList := TStringList(Param);
// should work when Param is FUnitList from TPackageClassesAndUnits
UnitList.Add(
Name);
end;
end;
{ TPackageClassesAndUnits }
constructor TPackageClassesAndUnits.Create(ModuleHandle: THandle);
var
flags: integer;
begin
// create class list
FClassList:= TList.Create;
// create unit list (sorted, ignore duplicates)
FUnitList := TStringList.Create;
FUnitList.Duplicates := dupIgnore;
FUnitList.Sorted := true;
FModuleName := GetModuleName(ModuleHandle);
// build unit list
GetPackageInfo(ModuleHandle, FUnitList, flags, @PackageInfoMethod);
// build class list
with TClassFinder.Create(
nil, false)
do
try
GetClasses(MethodGetClass);
finally
Free;
end;
end;
constructor TPackageClassesAndUnits.Create(ModuleName:
String);
begin
Create(GetModuleHandle(PChar(ModuleName)));
end;
destructor TPackageClassesAndUnits.Destroy;
begin
FClassList.Free;
FUnitList.Free;
inherited;
end;
procedure TPackageClassesAndUnits.MethodGetClass(AClass: TPersistentClass);
var
TypeData: PTypeData;
begin
// get typedata pointer
TypeData := GetTypeData(AClass.ClassInfo);
// add class when unit name of class typedate in unit list and not
// already added
if (FUnitList.IndexOf(TypeData^.UnitName) >= 0)
and
(FClassList.IndexOf(AClass) < 0)
then
FClassList.Add(AClass);
end;
end.