procedure(P: Pointer; var AObjName, AObjUnitName: string);
  //P可能指向TList, TStringList, TEdit.. 任一种类型的有效的对象
begin
  //如何得到 P 指向的对象的名字,以及这个对象的申明所在的单元?
end;  如果 P 所指向的对象是从 TComponent 继承下来的,并且申明在
Published 部分,则可以很容易得到这个对象的名字:TComponent(P).Name;
  如果P 所指向的对象是从 TPersistent 继承下来的,或者申明在$M+ $M-之间,
要获取这个对象申明所在的单元可以这样:
var
  pti: PTypeInfo;
  ptd: PTypeData;
  sUnitName: string; //P指向的对象所在的单元名字
begin
  pti := PTypeInfo(TObject(P).ClassInfo);
  ptd := GetTypeData(pti);
  sUnitName := ptd.UnitName;
end;
 但是,如果上面的2个条件都不满足,只知道P 是指向一个对象,这个对象可能
是任何类型的,要如何才能得到这个对象的名字,以及所在的单元名字呢?

解决方案 »

  1.   

    对了,ptd.UnitName; 只是得到这个对象的类的申明所在的单元,
    而不能得到这个对象的申明所在的单元,有什么办法可以作到呢?
      

  2.   

    只要是从TObject继承下来的类都
    可以这么来取类名:
    先定义: type pOb = ^TObject;再取:
    var
      pti: PTypeInfo;
      ptd: PTypeData;
      sUnitName: string; //P指向的对象所在的单元名字
      sClassName : strign;
    begin
      sClassName := pOb(p).ClassName;  pti := PTypeInfo(pOb(P).ClassInfo);
      ptd := GetTypeData(pti);
      sUnitName := ptd.UnitName;
    end;
      

  3.   

    我不是要求 P 所指向的对象所属的类的名字以及类所在的单元,我是要求 “P 所指向的对象的名字”,
    以及“申明这个对象的单元的名字”,比如:Unit1.pas
    ...
     private
       FA: TList;
     end;..
     var
       P: Pointer;
     begin
       P := FA; // FA 在其他地方已经创建了,
      //我要得到的是P指向的对象的的名字: 'FA',
      //以及P 的申明所在的单元名: 'Unit1.pas',
         不是P的类型TList所在的单元 Classes.pas
     end;  
      

  4.   

    进行枚举吧:if p is TComponent then
    begin
    end
    else if p is TPersistent then
    begin
    end
    ...反正就是这样的思路
      

  5.   

    只有TPersistent以后的类,如TControl才有Name属性,,如果是你说的那样,估计是不可能直接取出该变量的名称来了。不过应该可以通过指针对程序内存访问来或取变量(对象)的名字。
      

  6.   

    risingsoft(一苇渡江):
      枚举是不可能的,想想VCL有多少类,而且,我们自己也可以定义任意多的类,wenxj:
      即使是TComponent 的后代类,这个对象必须定义在Published 才可以通过
    TComponent(P).name 取到这个对象的名字,如果这个对象是定义在 Private 部分
    或者Public 部分就不能这样得到名字。
      你说的“通过指针对程序内存访问来或取变量(对象)的名字。”应该怎么做?
    可以详细一点吗?我要取这个变量(对象)的名字,以及这个申明这个变量的单元的名字。
      
      

  7.   

    编译后的二进制代码.对于CPU而言,是没有变量名的概念的.呵呵.........所以得到对象的名字好像不太现实.