(300分没人拿?)能否做到在TButton控件基础上增加新属性方法而不用新注册控件或动态创建?(比如在设计时摆放的是父类TButton控件,在运行时全部被子类

  • 主题发起人 主题发起人 guqs
  • 开始时间 开始时间
"同样为你的问题困扰过,我知道你有更深一层的意思"
to cbuiler:
总算有如此理解我的问题的人,我简直是热泪盈眶啊!

Delphi难道真的解决不了吗?
大家继续讨论啊!
 
一点拙荐:做一个虚拟按钮或者说抽象按钮TVirtualButton,继承于TBUTTON,无任何的改动,注册安装,
然后在你的表单中任意添加TVirtualButton,然后改这个TVirtualButton的实现代码,或者可以
继承于你想加的TMYBUTTON,但这个TMYBUTTON不能是注册的,我想这又可能为DELPHI所不许,我想
这可能是可视化的弊端吧,可能DELPHI的一个很大的缺陷就在这里了。
 
cbuiler 的方法可能是最[red]理想[/red]的
 
总算明白你的意思啦。鲁小班的告诉你的方法应该是正解!

你只需要这样,在你的按钮单元中中的初始化Section加入 RegisterClass(TMyButton);
然后你尽管替换 pas 和 DFM中的按钮为你自己的按钮类(最好不要在IDE中做这些事情),
编译就不会抱怨找不到MyButton类啦,当然你必须在项目中使用(Uses)你的MyBtn单元!

unit MyBtn;
...
TMyButton = Class(TButton)
....
end;

....

initialization
RegisterClass(TMyButton);
end;
 
guqs:
非常同感。
我们在扩展标准控件功能时,一般采用这种方法:在一单元中建立一个与原控件名字
相同的类,再实现特殊功能,比如我们为TQuery扩展一些功能,在我的公用单元中是这
样写的:
TQuery=class(DBTables.TQuery)
....
end;
这样我们只要在使用TQuery 组件的单元中 Uses 我的公用单元即可使TQuery具有新的
功能。但是,这种方法所扩展的控件功能只能在运行期起作用,因为没有注册新的组件,
在设计期Delphi并不知道我们扩展了功能呀。
解决该问题的关键应该就是:除了注册新组件外,怎样才能让Delphi的IDE知道我们做
了扩展?
请大家继续讨论
 
我试了一下 蜀子 的方法,非常激动,因为以前我没有想到过可以用同名来扩展新类(我潜
意识中认为不能同名引用)。
代码如下:

TButton=class(StdCtrls.TButton)
public
str:string;
end;

TForm1 = class(TForm)
Button1: TButton;
private
{ Private declarations }
public
{ Public declarations }
end;

这样,甚至在编辑时就可以用Button1.str,在代码提示框中就可以看到我新加的属性。说明
这时程序中引用的已是我的新类了。
但这样只能用已有注册的同名类为名,有着诸多限制,同时易导致代码混淆(新类旧类混淆)。

同意说法:
“解决该问题的关键应该就是:除了注册新组件外,怎样才能让Delphi的IDE知道我们做
了扩展?”
这可以用riceball提出的
initialization
RegisterClass(TMyButton);
end;
做法,结合手工编辑dfm。
看来已经初步解决了我提出的问题。

不知有否更完美的一套解决方案?
感谢大家的讨论,希望大家再深入讨论!




 
结合以上思路,我有一个新的想法:
做这样一个控件:
可以在属性设置其父类控件,可以用属性编辑器输入新类的实现代码,于是此控件在编辑
状态就具有了所有新类的特性(如同现在一些控件可以在编辑期改变外观一样),从而可以
在IDE中直接用此控件。
这个方法可能要用到一些设计期IDE的编程技术,我没有尝试过,不知此路是否行得通,
望有此经验的人指教!
 
很好的思路,可是本人不学无数,继续听课。
 
蜀子的方法的确不错。
我的上述代码可以修改为:
{$IFDEF DEBUG}
TSpeedButton = class(Buttons.TSpeedButton);
{$ELSE}
TSpeedButton = class(Buttons.TSpeedButton)
private
...
protected
...
public
...
published
...
end;

这样我就可以很方便的使用TSpeedButton的新属性。
 
我记得Delphi的类是可以重复注册的,可不可以这样:将我们扩展组件功能的代码放在
一个BPL中,注册、安装...
我正为工作的事发愁,没有心情试了...
 
kkyy提出的办法不行吗?
 
关注!
蜀子的方法的确不错,但是
有一个问题,现在我为这些控件加了一些属性,
是没有通过注册的,如果我要在其他的项目中在
使用,那还要写入代码,这样并没有省事,现在是不是可以
通过继承(不注册)实现,这样在以后的项目中
就不用在写代码?
 
还没找到有效的方法,大家继续呀!
 
用继承实现 应该是没问题的。
 
:wk_knife
看清楚上面讨论的问题了吗?
 
实际上你可以将 DelphiX/Vcl/StdCtrls.pas 拷贝到那个工程的目录下,对其中的TButton类
进行改写就可以了.这样Delphi在编译时会不理睬原来的TButton类而直接用你定义的
TButton类了.这样的后果是在IDE下还是原来的标准Button,而运行时却是你的Button类.
看你的要求,可以对WM_Paint进行拦截使其外观进行改变,不过我还是希望你用TBitBtn类,
那样会更方便一些.
 
看来delphi也有所限制,没人能给出满意的答案。
感谢 蜀子、riceball 给出的 折中方法,但仍觉得不够好。

我现在装了VS.net,界面非常爽,同时在窗体设计及属性框方面类似delphi,语法上也有
相似之处,可以很快从delphi过度到C#上。
VS.net的界面生成语句也是程序的一部分,可以直接在程序中写,而不是如delphi中作为
dfm资源,因此很容易解决上面的问题。

我决定学VS.net了(原来看了一段时间java)。

当然,delphi我不会放弃。
 
多人接受答案了。
 
后退
顶部