Delphi Programming / Object Pascal
[掲載 2020年11月08日] [更新 2020年11月10日] Delphi サンプルプログラム集 |
974_パッケージ名とコンポーネント名の列挙 |
動作確認等 |
Windows 7 U64(SP1) + Delphi XE5(UP2) Pro VCL-32 |
|
974_PackageCompoList.zip [1.8 MB] 2020年11月10日版 (EXE 同梱) |
Delphi 自身が使用する, つまり Delphi の IDE が使用するパッケージ群の列挙と,それらのパッケージに登録されているコンポーネント名の列挙に関するサンプルです.
本ページでは,最初と最後のサンプル以外は,以下の記事で説明している手順で作成したパッケージを使用しています.それらのパッケージをインストールして,[ツール] メニューに追加した項目からフォームを表示しています.本文中の「IDE から実行」や「IDE から表示」という記述は,そのことを意味しています.
|
01_実行時にロードして使用するモジュール名を列挙 |
EXE 起動時にどのようなモジュールがロードされるのかを確認してみます.現在のプロセスが実行時に読み込んだモジュールは,Windows API の EnumProcessModules 関数で列挙できます.
このサンプルは実行時パッケージを使用していません.したがって,拡張子が .bpl のパッケージファイルはリストされていません.実行時パッケージ使用の有無は,グローバル変数 ModuleIsPackage (SysInit.pas) で確認することができます.
|
|
図1
プロセスが使用するモジュール名を列挙
- 実行時パッケージを使用していないので BPL ファイルはリストにない
|
リスト1
現在のプロセス (EXE) が使用するモジュール名を列挙 |
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
function EnumModules(AMemo: TMemo): Boolean;
var
Form1: TForm1;
implementation
uses
Winapi.PsAPI;
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Lines.Clear;
Memo1.ScrollBars := ssBoth;
Memo1.Font.Size := 11;
Memo1.Font.Name := 'Courier New';
end;
//=============================================================================
// フォーム表示開始時の処理
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
Memo1.Lines.BeginUpdate;
EnumModules(Memo1);
Memo1.Lines.EndUpdate;
end;
//-----------------------------------------------------------------------------
// 現在のプロセスで使用しているモジュールを列挙
//
// uses に Winapi.PsAPI が必要
//-----------------------------------------------------------------------------
function EnumModules(AMemo: TMemo): Boolean;
var
LhProcess : THandle;
LSizeNeeded : Cardinal;
LhModuleArray : array of HMODULE;
LhModule : HMODULE;
LModulePath : string;
LIndex : Integer;
begin
Result := False;
// 現在のプロセスのハンドルを取得
LhProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
False,
GetCurrentProcessId);
if LhProcess = 0 then
RaiseLastOSError;
try
// モジュールハンドルの値格納に必要なメモリのバイト数を取得
LSizeNeeded := 0;
EnumProcessModules(LhProcess, nil, 0, LSizeNeeded);
if LSizeNeeded = 0 then Exit;
// モジュールハンドルの値を格納する配列の要素数ょ設定
SetLength(LhModuleArray, LSizeNeeded div SizeOf(HMODULE));
// モジュールハンドル値を列挙
if EnumProcessModules(LhProcess,
PHMODULE(LhModuleArray),
LSizeNeeded,
LSizeNeeded) then begin
// モジュールがある場所 (フルパス) を取得して表示
for LIndex := 0 to Length(LhModuleArray) - 1 do begin
LhModule := LhModuleArray[LIndex];
// 自分自身 (このプログラム EXE ) は除外
if LhModule <> HInstance then begin
LModulePath := GetModuleName(LhModule);
AMemo.Lines.Add(LModulePath);
end;
end;
AMemo.Lines.Add('モジュール数 : ' + IntToStr(Length(LhModuleArray) - 1));
if ModuleIsPackage then begin
AMemo.Lines.Add('実行時パッケージあり');
end else begin
AMemo.Lines.Add('実行時パッケージなし');
end;
Result := True;
end;
finally
CloseHandle(LhProcess);
end;
end;
end.
前項のコードを IDE から表示すると下図のようになります.現在のプロセスが IDE ということになりますから,実行時にパッケージを読み込んでいるのと同じです.
添付の [IDE_EnumModule] フォルダ内の plEnumModule.dpk をインストールすると,[ツール] に [モジュールの一覧取得] が追加されます.その項目を選択すると,下図の結果を確認できます.
|
|
図2
Delphi が使用するモジュール
- 拡張子が .bpl のパッケージファイルも含まれる
|
03_Tools API を使用したパッケージ名 ( .BPL ) の列挙 |
上のサンプルコードで,TMemo に表示する部分を次のようにすれば,拡張子が .bpl のパッケージ名だけを列挙することができます. |
LModulePath := GetModuleName(LhModule);
LFileExt := ExtractFileExt(LModulePath);
// 指定拡張子のみ処理
if CompareText(LFileExt, '.BPL') = 0 then begin
AMemo.Lines.Add(LModulePath);
Inc(LCount);
end;
ToolsAPI に IOTAPackageServices インターフェイスがあります.これはパッケージの操作用です.このインターフェイスの Package プロパティは,パッケージのオブジェクトである IOTAPackageInfo インタフェイス型です.このプロパティを使用すると,図の下に示すようなコードで,拡張子が .bpl のパッケージ名を列挙できます.
このコードのフォームを IDE から表示すると下図のようになります.
|
|
図3
IDE からパッケージを列挙した結果
- 標準コンポーネントのパッケージ dclstd190.bpl がある
|
最後までスクロールした状態が下図です.テストした筆者の環境では全部で 116 でした.実行時専用パッケージを除外すると 59 になりました.この値は設計時に使用可能なパッケージ数ということになります.この値には,[コンポーネント] [パッケージのインストール] のパッケージのリストで,チェックがないパッケージは含まれていません.
これらは IDE 自身が使用するパッケージを除外した数です.IDE 自身が使用するパッケージと実行時専用パッケージを含めると 195 でした.
下図の最後の 3 つのパッケージは,今回のテストで,IDE からフォームを表示するために作成してインストールしたパッケージです.
|
|
図4
パッケージ数は 116
- IDE 自身が使用するパッケージを除外した数
- IDE 自身が使用するパッケージを含めると 195
|
添付の [IDE_PackageList] フォルダ内の plPackageList.dpk をインストールすると,[ツール] に [パッケージ名の列挙] が追加されます.その項目を選択すると,上の図の結果を確認できます.
|
リスト2
パッケージ名を列挙するために,IDE から表示するフォームのコード |
unit plPackageListForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormShow(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses
ToolsAPI;
{$R *.dfm}
{ TForm1 }
//=============================================================================
// フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Lines.Clear;
Memo1.ScrollBars := ssBoth;
Memo1.Font.Size := 11;
Memo1.Font.Name := 'Courier New';
end;
//=============================================================================
// フォームを表示する時の処理
// パッケージ名 (拡張子は .bpl) を列挙
//
// uses に ToolsAPI が必要
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
var
LPkgeServices : IOTAPackageServices;
LPackage : IOTAPackageInfo;
LIndex : Integer;
begin
Memo1.Lines.BeginUpdate;
// インターフェイスのオブジェクトを取得
LPkgeServices := BorlandIDEServices as IOTAPackageServices;
for LIndex := 0 to LPkgeServices.PackageCount - 1 do begin
LPackage := LPkgeServices.Package[LIndex];
// IDE 自身が使用するパッケージは除外
if LPackage.IDEPackage then Continue;
// 実行時パッケージで使用可能なパッケージだけを列挙する時は以下を追加
// if LPackage.RuntimeOnly then Continue;
// LPackage.FileName にすればフルパス
Memo1.Lines.Add(LPackage.Name);
end;
Memo1.Lines.Add(IntToStr(Memo1.Lines.Count));
Memo1.Lines.EndUpdate;
end;
end.
前項と同じ Package プロパティのインターフェイスである IOTAPackageInfo を使用して,パッケージの各種の情報を取得するサンプルです.
このインターフェイスには,パッケージの Contains,Requires 部のリストを取得するメソッドや,その他の情報を取得するプロパティがあります.それらを使用して,パッケージの情報を TTreeView に表示します.
図の下に示すコードのフォームを IDE から表示すると下図ようになります.
これは,構造ペインに表示される内容と同じです.パッケージの構造ということになります.
|
|
図5
パッケージの構造
- plPackageListInfo.bpl は,このフォームを表示するために作成したパッケージ
|
下図は標準パッケージ dclstd190.bpl の情報 (構造) です.
|
|
図6
標準コンポーネントのパッケージ dclstd190.bpl の構造 |
添付の [IDE_PackageList_Info] フォルダ内の plPackageListInfo.dpk をインストールすると,IDE の [ツール] メニューに [パッケージの情報取得] が追加されます.その項目を選択すると,上の図の結果を確認できます.
|
リスト3
パッケージの情報 (構造) を取得して表示するために,IDE から表示するフォームのコード |
unit plPackageListInfoForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, ToolsAPI,
Vcl.ComCtrls;
type
TForm1 = class(TForm)
TreeView1: TTreeView;
procedure FormShow(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
procedure EachPackageInfo(APackage: IOTAPackageInfo; ATVItems: TTreeNodes);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
//=============================================================================
// フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
TreeView1.Items.Clear;
TreeView1.Font.Size := 11;
TreeView1.Font.Name := 'Courier New';
end;
//=============================================================================
// フォームを表示する時の処理
// インストールされているパッケージ名を列挙
// 列挙した各パッケージの情報を取得してツリー表示
//
// uses に ToolsAPI が必要
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
var
LPkgeServices : IOTAPackageServices;
LPackage : IOTAPackageInfo;
LIndex : Integer;
begin
TreeView1.Items.Clear;
TreeView1.Items.BeginUpdate;
// インターフェイスのオブジェクトを取得
LPkgeServices := BorlandIDEServices as IOTAPackageServices;
for LIndex := 0 to LPkgeServices.PackageCount - 1 do begin
LPackage := LPkgeServices.Package[LIndex];
// IDE 自身が使用するパッケージは除外
if LPackage.IDEPackage then Continue;
// 実行時パッケージで使用可能なパッケージだけにする時は以下を追加
// if LPackage.RuntimeOnly then Continue;
// Loaded が True でないパッケージは Contains 部の情報が取得できない
LPackage.Loaded := True;
EachPackageInfo(LPackage, TreeView1.Items);
end;
TreeView1.Items.EndUpdate;
end;
//-----------------------------------------------------------------------------
// 引数で指定するパッケージの情報を TTreeView に表示
//
// uses に ToolsAPI が必要
//-----------------------------------------------------------------------------
procedure TForm1.EachPackageInfo(APackage: IOTAPackageInfo; ATVItems: TTreeNodes);
var
LStrList : TStringList;
LRootNode : TTreeNode;
LContNode : TTreeNode;
LReqNode : TTreeNode;
LIndex : Integer;
begin
LStrList := TStringList.Create;
try
// ルートノードはパッケージ名
LRootNode := ATVItems.Add(nil, APackage.Name);
// Contains 部のリストを取得して子ノードとして追加
APackage.GetContainsList(LStrList);
LContNode := ATVItems.AddChild(LRootNode, 'Contains');
for LIndex := 0 to LStrList.Count - 1 do begin
ATVItems.AddChild(LContNode, LStrList[LIndex]);
end;
// Requires 部のリストを取得して子ノードとして追加
APackage.GetRequiresList(LStrList);
LReqNode := ATVItems.AddChild(LRootNode, 'Requires');
for LIndex := 0 to LStrList.Count - 1 do begin
ATVItems.AddChild(LReqNode, LStrList[LIndex]);
end;
// その他の情報を追加
if APackage.RuntimeOnly then
ATVItems.AddChild(LRootNode, 'RunTimeOnly');
if APackage.DesigntimeOnly then
ATVItems.AddChild(LRootNode, 'DesigntimeOnly');
// パッケージの説明テキストを追加
ATVItems.AddChild(LRootNode, APackage.Description);
finally
FreeAndNil(LStrList);
end;
end;
end.
パッケージ名を TListBox にリスト表示して,パッケージ名を選択すると,そのパッケージに登録されているコンポーネント名を列挙する例です.
IOTAPackageServices インターフェイスの GetComponentName メソッドを使用すると,指定パッケージに登録されているコンポーネント名が取得できます.パッケージはインデックスで指定します.
本サンプルでは,TListBox の Objects プロパティにパッケージのインデックスの値を代入しておきます.その値を使用してコンポーネント名を取得します.
右の TListBox に表示するのはコンポーネントのクラス名です.例えば TListBox は Listbox ではありません.プリフィックスの T が付いた TListBox です.
|
|
図7
標準コンポーネントのリスト
- 左がパッケージ名
- 右は選択したパッケージに登録されているコンポーネント名のリスト
|
添付の [IDE_PackageListCompo] フォルダ内の plPackageListCompo.dpk をインストールすると,IDE の [ツール] メニューに [パッケージ内のコンポーネント列挙] が追加されます.その項目を選択すると,上の図の結果を確認できます.
|
リスト4
パッケージ内のコンポーネント名を列挙するために,IDE から表示するフォームのコード |
unit plPackageListCompoForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
Vcl.ComCtrls, Vcl.ExtCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Splitter1: TSplitter;
ListBox2: TListBox;
procedure FormShow(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ListBox1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses
ToolsAPI;
{$R *.dfm}
{ TForm1 }
//=============================================================================
// フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Splitter1.ResizeStyle := rsUpdate;
ListBox1.Items.Clear;
ListBox1.Font.Size := 11;
ListBox1.Font.Name := 'Courier New';
ListBox2.Items.Clear;
ListBox2.Font.Size := 11;
ListBox2.Font.Name := 'Courier New';
end;
//=============================================================================
// フォームを表示する時の処理
// インストールされているパッケージ名を TListBox にリスト
//
// uses に ToolsAPI が必要
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
var
LPkgeServices : IOTAPackageServices;
LPackage : IOTAPackageInfo;
LIndex : Integer;
begin
ListBox1.Items.Clear;
ListBox1.Items.BeginUpdate;
// インターフェイスのオブジェクトを取得
LPkgeServices := BorlandIDEServices as IOTAPackageServices;
for LIndex := 0 to LPkgeServices.PackageCount - 1 do begin
LPackage := LPkgeServices.Package[LIndex];
// IDE 自身が使用するパッケージは除外
if LPackage.IDEPackage then Continue;
// 実行時パッケージで使用可能なパッケージだけにする時は以下を追加
// if LPackage.RuntimeOnly then Continue;
// Loaded が True でないパッケージは Contains 部の情報が取得できない
LPackage.Loaded := True;
ListBox1.AddItem(LPackage.Name, TObject(LIndex));
end;
ListBox1.Items.EndUpdate;
end;
//=============================================================================
// ListBox1 の OnClick イベント処理
// クリックしたパッケージ内のコンポーネント名を別の TListBox にリスト
//
// uses に ToolsAPI が必要
//=============================================================================
procedure TForm1.ListBox1Click(Sender: TObject);
var
LIndex : Integer;
LPkgIndex : Integer;
LPkgeServices : IOTAPackageServices;
begin
LIndex := ListBox1.ItemIndex;
if LIndex < 0 then Exit;
LPkgIndex := Integer(ListBox1.Items.Objects[LIndex]);
// インターフェイスのオブジェクトを取得
LPkgeServices := BorlandIDEServices as IOTAPackageServices;
// 指定したインデックスのパッケージ内のコンパーネント名を順番に取得
ListBox2.Items.Clear;
ListBox2.Items.BeginUpdate;
for LIndex := 0 to LPkgeServices.ComponentCount[LPkgIndex] - 1 do begin
ListBox2.Items.Add(LPkgeServices.GetComponentName(LPkgIndex, LIndex));
end;
ListBox2.Items.EndUpdate;
end;
end.
本ページの最初のサンプルで確認したように,拡張子が .bpl のパッケージは,実行時パッケージを使用しない限り EXE 実行時には読み込まれません.Delphi がインストールされていない環境には,基本的に Delphi のパッケージは存在しません.このことから,パッケージの関係の操作は,Tools API を使用して IDE の拡張機能として実装するのが適切と思われます.
単独のパッケージであれば,実行時に現在のプロセスでロードして,GetPackageInfo 手続きを使用して情報を取得することができます.実際のパッケージの情報は,GetPackageInfo 手続きのコールバック関数内で取得します.パッケージは LoadPackage 関数で読み込みます.
|
|
図8
テストで作成してインストールしたパッケージの情報 |
モジュールとして自分自身の EXE の情報を取得した結果です.EXE で使用しているユニットファイル名が確認できます.
|
|
図9
自分自身のモジュールとしての EXE の情報
|
リスト5
実行時にロードしたパッケージの情報 (構造) を取得して表示 |
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
TreeView1: TTreeView;
Button2: TButton;
Button3: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
function EachModuleInfo(ATVItems: TTreeNodes; AhModule: HMODULE;
Data: Pointer): Boolean;
procedure PackageInfoProc(const Name: string; NameType: TNameType;
Flags: Byte; Param: Pointer);
var
Form1: TForm1;
implementation
{$R *.dfm}
var
FContNode : TTreeNode;
FReqNode : TTreeNode;
//=============================================================================
// フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
TreeView1.Items.Clear;
TreeView1.Font.Size := 11;
TreeView1.Font.Name := 'Courier New';
end;
//=============================================================================
// 筆者がインストールしたパッケージの情報を取得
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LPkgPath : string;
LhMODULE : HMODULE;
begin
LPkgPath := 'C:\Users\Public\Documents\RAD Studio\12.0\Bpl\plEnumModule.bpl';
LhMODULE := LoadPackage(LPkgPath);
TreeView1.Items.Clear;
TreeView1.Items.BeginUpdate;
EachModuleInfo(TreeView1.Items, LhMODULE, nil);
TreeView1.Items.EndUpdate;
TreeView1.TopItem.Expand(True);
TreeView1.TopItem := TreeView1.Items[0];
end;
//=============================================================================
// 自分自身 (HInstance) の情報を取得
// 自分自身の EXE をモジュールとしての情報
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
LhMODULE : HMODULE;
begin
LhMODULE := HInstance;
TreeView1.Items.Clear;
TreeView1.Items.BeginUpdate;
EachModuleInfo(TreeView1.Items, LhMODULE, nil);
TreeView1.TopItem := nil;
TreeView1.Items.EndUpdate;
TreeView1.TopItem.Expand(True);
TreeView1.TopItem := TreeView1.Items[0];
end;
//=============================================================================
// dclstd190.bpl (Delphi XE5 標準コンポーネント) パッケージの情報を取得
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
var
LPkgPath : string;
LhMODULE : HMODULE;
begin
LPkgPath := 'C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\bin\dclstd190.bpl';
LhMODULE := LoadPackage(LPkgPath);
TreeView1.Items.Clear;
TreeView1.Items.BeginUpdate;
EachModuleInfo(TreeView1.Items, LhMODULE, nil);
TreeView1.Items.EndUpdate;
TreeView1.TopItem.Expand(True);
TreeView1.TopItem := TreeView1.Items[0];
end;
//-----------------------------------------------------------------------------
// 引数で指定したモジュールの情報を取得して TTreeView に表示
//-----------------------------------------------------------------------------
function EachModuleInfo(ATVItems: TTreeNodes; AhModule: HMODULE;
Data: Pointer): Boolean;
var
LRootNode : TTreeNode;
LModuleName : string;
LModuleDesc : string;
LFlags : Integer;
begin
LModuleName := GetModuleName(AhModule);
LRootNode := ATVItems.Add (nil, LModuleName);
LModuleDesc := GetPackageDescription (PChar (LModuleName));
FContNode := ATVItems.AddChild (LRootNode, 'Contains');
FReqNode := ATVItems.AddChild (LRootNode, 'Requires');
// GetPackageInfo 手続きを実行
// 第 2 引数は手続きに渡す任意の値 (Pointer 型)
// 第 3 引数は手続きからの戻り値
// 第 4 引数はコールバック関数
GetPackageInfo(AhModule, ATVItems, LFlags, PackageInfoProc);
// パッケージの説明テキストがない場合
// IDE 自身が使用するパッケージと見なして除外
if LModuleDesc <> '' then begin
ATVItems.AddChild (LRootNode, 'Description: ' + LModuleDesc);
if LFlags and pfDesignOnly = pfDesignOnly then
ATVItems.AddChild (LRootNode, 'Design Only');
if LFlags and pfRunOnly = pfRunOnly then
ATVItems.AddChild (LRootNode, 'Run Only');
end;
Result := True;
end;
//-----------------------------------------------------------------------------
// GetPackageInfo 手続きのコールバック関数
// TTreeview のノード FContNode, ReqNode (TTreeNode) の階層下に項目を追加
// FContNode, FReqNode はルート直下のノードでグローバル変数
//-----------------------------------------------------------------------------
procedure PackageInfoProc(const Name: string; NameType: TNameType;
Flags: Byte; Param: Pointer);
var
FlagStr : string;
LTVItems : TTreeNodes;
begin
LTVItems := TTreeNodes(Param);
FlagStr := ' ';
if Flags and ufMainUnit <> 0 then
FlagStr := FlagStr + 'Main Unit ';
if Flags and ufPackageUnit <> 0 then
FlagStr := FlagStr + 'Package Unit ';
if Flags and ufWeakUnit <> 0 then
FlagStr := FlagStr + 'Weak Unit ';
if FlagStr <> ' ' then
FlagStr := ' (' + FlagStr + ')';
case NameType of
ntContainsUnit : LTVItems.AddChild (FContNode, Name + FlagStr);
ntRequiresPackage : LTVItems.AddChild (FReqNode, Name);
end;
end;
end.
|