如何对控件中指针域建立published属性?(100分)

  • 主题发起人 主题发起人 Prinse
  • 开始时间 开始时间
P

Prinse

Unregistered / Unconfirmed
GUEST, unregistred user!
我做了个控件,此控件在设计时需要在Object Inspector中通过属性关联其它控件。
所以我加了个指针域。但为了能在设计时访问这个域,我设计了相应的<b>published</b>属性,
当然只能是控件类型的了。但却不能成功。
我把属性改为<b>public</b>在运行时访问就没有问题,不知为什么?
请各位大虾指点指点。

type
PPanel = ^TPanel;

TmyPanel = class(TPanel)
private
FPnl: PPanel;

function GetPnl: TPanel;
procedure SetPnl(var Value: TPanel);
published
property Pnl: TPanel read GetPnl write SetPnl;
end;

implementation

//===========================================================================
//---------------------------------------------------------------------------
function TmyPanel.GetPnl: TPanel;
begin
if (FPnl<>nil) then result := FPnl^ else result := nil;
end;

//---------------------------------------------------------------------------
procedure TmyPanel.SetPnl(var Value: TPanel);
begin
FPnl := @Value;
end;
 
没有人能指点一二吗?
 
这样:
TmyPanel = class(TPanel)
private
FPnl: PPanel;

function GetPnl: TPanel;
procedure SetPnl(Value: TPanel);
published
property Pnl: TPanel read GetPnl write SetPnl;
end;

implementation

function TmyPanel.GetPnl: TPanel;
begin
result := FPnl;
end;

procedure TmyPanel.SetPnl(Value: TPanel);
begin
if FPnl <> Value then FPnl := Value;
end;

设计时对Form上所有控件的非缺省的属性设置,都将被IDE 写入到 DFM 文件中,DFM 文件
实际上是资源文件,链接时被包含到你的可执行文件中。运行时一个Form被创建时,它先完
成自己基本字段、属性的初始化,然后从程序资源中读出自己的设计时属性设置,恢复到
设计时的状态,然后依次创建自己的子控件,初始化这些子控件,并从资源中读出其设计时
属性,将它们恢复到设计时的状态...这基本上是一个递归的过程。
对于控件中指向另一个控件的属性,如 Form 的 ActiveControl、数据敏感控件的 DataSource
属性,IDE 只是把它们所指向的控件的名字(可能包括完整的NamePath,如
'TDataModule1.DataSource1')写入 DFM 文件中,运行时从资源中调出状态时再将该属性
设置指向相应的运行时实际创建的控件。
因此,你设计时保存下来的某个控件假设是 Panel1 的地址到了运行时就变得没有意义
了。那时的 Panel1 是动态被创建的,它的地址与设计时的 Panel1 的地址是不同的。
 
可能我没能把问题描述得够清楚。我的意图是:
新的控件(譬如是MyPanel:TMyPanel)在运行时需要对某类其它控件(譬如是AEdit:TEdit)
进行操作,因此MyPanel需要知道它的操作是施加在谁上面的。
假如把AEdit的Name告诉MyPanel,则MyPanel需要回查AEdit,而且难于限定AEdit的类型,
也就是说,无法利用Delphi的类型检查机制。

To:bbkxjy
谢谢你的解释,我大致清楚我出错的原因。但是,你的作法不能解决我的问题。因为这时
候,属性MyPanel.Pnl记录的是AEdit所指向的区域,而不是AEdit本身,因此当AEdit发生
变化时,MyPanel.Pnl将丢失AEdit。

因为这样的原因,我才考虑将MyPanel.Pnl对应的域MyPanel.FPnl设计成为指针类型,记录
AEdit本身。这样,MyPanel.Pnl总可以访问到AEdit。当MyPanel.Pnl是Public时,对
MyPanel.FPnl的使用是在运行时才开始的,所以,一切正常。但是,当改为Published时,
诚如你所说的,在Object Inspector中,IDE将一个不合适的地址赋给MyPanel.FPnl,所以
出错。

问题是,我现在如何解决这个矛盾呢?
 
"...因此当AEdit发生变化时,MyPanel.Pnl将丢失AEdit。"?
你的发生变化是什么意思?比如?
通过这种属性,完全可以访问对应组件的属性啊!
如 已经有一个 TPanel 对象 Panel1(不管是设计时就在 Form 上或动态创建的),
设计时你可以在 Object Inspector 中设置 MyPanel 的 Pnl 属性为 Panel1,或是运行时
这样赋值:
MyPanel.Pnl := Panel1;
然后你要访问 Panel1 的属性可以这样(比如修改 Caption):
MyPanel.Pnl.Caption := 'hello';
这样就把 Panel1 的 Caption 改为了 'hello'。
至于 TEdit 也是一样的道理啊。我不太明白你的目的。希望你真的试过了再说。
我是在 Delphi5 下试过的,设计时可以在 Object Inspector 中对 MyPanel 的 Pnl 属性
赋值,会出现一个下拉框,让你选择 Form 上已有的 TPanel 对象。
 
To bbkxjy
谢谢你的指点。就上例而言,确实可行。也许是我的思路偏差了。我将会在我的控件中再
试一试。如能解决问题,分数归你。:-)
 
To bbkxjy
再次谢谢你的帮助,我的问题已经基本解决。
 

Similar threads

后退
顶部