お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"指定クラスのpublishedなメソッド名を列挙"

この発言に対し以下のコメントが寄せられています
#00948 Satobe さん RE:指定クラスのpublishedなメソッド名を列

◆解説 指定のクラスの published なメソッド名を列挙します。 ◆動作確認 Delphi3.1, Delphi4 (Delphi5 は未確認です) ◆実際のコード Form1に Button1, Memo1 を置いて、以下のコードをお試し下さい ----- ここから ----- implementation {$R *.DFM} //テスト用のクラス定義-- ここから -------------------------- type TTest1 = class(TObject) public No: Integer; published procedure TTest1Method(s: String); end; TTest2 = class(TTest1) published procedure TTest2Method(s: String); end; TTest3 = class(TTest2) published procedure TTest3Method(s: String); end; procedure TTest1.TTest1Method(s: String); begin ShowMessage(Format('[No=%d]%s', [No, s])); end; procedure TTest2.TTest2Method(s: String); begin ShowMessage(Format('[No=%d]%s', [No, s])); end; procedure TTest3.TTest3Method(s: String); begin ShowMessage(Format('[No=%d]%s', [No, s])); end; //テスト用のクラス定義-- ここまで -------------------------- //========================================================== //クラス内の publishedなメソッド名を列挙する // //「クラス名.メソッド名」という形式にしているが、 //「メソッド名」のみで良いなら *行の ClassNameの処理は不要 //========================================================== procedure EnumMethodNames(const AClass: TClass; S: TStrings); type PPointer = ^Pointer; var vmt: Pointer; pMethodTable: PChar; MethodCount, MethodNameLen: Integer; ClassName, MethodName: String[255]; //* begin S.Clear; vmt := AClass; while True do begin ClassName := TClass(vmt).ClassName; //* pMethodTable := PPointer(PChar(vmt) + vmtMethodTable)^; if pMethodTable <> nil then begin MethodCount := PWORD(pMethodTable)^; inc(pMethodTable, 2); while MethodCount > 0 do begin MethodNameLen := PBYTE(pMethodTable + 6)^; Move((pMethodTable + 6)^, MethodName, MethodNameLen+1); S.Add(ClassName + '.' + MethodName); //* //Next Method inc(pMethodTable, PWORD(pMethodTable)^); Dec(MethodCount); end; end; //Parentへ vmt := PPointer(PChar(vmt) + vmtParent)^; if vmt = nil then Break; vmt := PPointer(vmt)^; end; end; //動作テスト procedure TForm1.Button1Click(Sender: TObject); var j, p: Integer; s: String[255]; Method: procedure(s: String) of object; T3: TTest3; begin //TTest3クラスのpublishedなメソッド名をMemo1に列挙 EnumMethodNames(TTest3, Memo1.Lines); //試しに呼び出してみる T3 := TTest3.Create; try TMethod(Method).Data := T3; for j:=0 to Memo1.Lines.Count-1 do begin s := Memo1.Lines[j]; p := Pos('.', s); if p > 0 then Delete(s, 1, p); TMethod(Method).Code := TTest3.MethodAddress(s); if Assigned(TMethod(Method).Code) then begin T3.No := j; Method(Memo1.Lines[j]); end; end; finally T3.Free; end; end; ----- ここまで ----- 処理の内容、および VMT(仮想メソッドテーブル)等については、 Delphiヘルプや TObject.MethodAddress等のソース(アセンブラ ですが(^^;)コードを参照してください。 けっこう怪しいルーチンです。(^_^;; 私自身も、これが正しいコードなのかどうか、よくわかってませ ん。#やってみたら、とりあえず動いたってだけ... 99/09/28(火) 23:12 Satobe(JCG00336) Original document by Satobe 氏 ID:(JCG00336)



ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum