两个问题 by tqz(100分)

T

tqz

Unregistered / Unconfirmed
GUEST, unregistred user!
1:如何访问别的Unit里面的class的protected property or Method?
比如TControl中的事件都是protected,有没有后门让我读写之呢?

2:我作的一个控件有个属性是Form,我希望设计时可以在当前project中
的所有form中挑一个。就象ListView的LargeImages属性,如果当前form
有若干个ImageList,那么property Editor中LargeImages就会有一个列表,
列出当前form里面的所有ImageList.
问题是Form跟一般的Component不一样,这个PropertyEditor不知该怎么写?
 
1. 自定义一个控件继承它并publish出来
 
2、可以试试从TApplication.Components[Index]属性取出所有的Form

with Application do
for I:=0 to ComponentCount-1 do
if Components is TCustomForm then
.....
 
对于问题1:protect的保护是只对本单元有效,所以不会被其它单元访问
,可以声明一类继承之。
tmyclass=class(tcontrol)
后用tmyclass界定你所用的属性即可。
问题2:听听别人的吧。
 
1.好象不行
 
1.根本行不通,除非你自己编写一个Turbo Pascal/Delphi.这是该门语言
绝对禁止的。
 
打个比方:(这样做当然危险,但可以访问protected)
type
tmyclass=class(tcontrol)
...


tmyclass(Button1).EraseDragDockImage;

EraseDragDockImage为protected,但可被访问。
 
1.继承后使用Protected属性及方法对于tqz来讲不是问题, 他想越过Delphi的这个
限制让非直接继承的类也能够使用这些Protected东西, 这是不可能的, 否则就失去
了Protect的意义了.
2.欲将Form属性加入到一个类中去在设计阶段使用当然是能够做到的, 但是需要与
Delphi IDE通话才行. Delphi IDE本身是一个DDEServer, 但是如何来接需要试验
才能够得到, 至于在运行期间就比较容易实现了, 通过Screen.CustomFormCount,
Screen.CoustomForms等属性就能够得到.
 
1 menxin方法正确,我从网易上曾收到一封关于该使用
方法的email, 经实验通过
 
1 会长说的对,我是不该侵犯他人隐私,不过我也没办法。我想访问一个WinControl
GraphicControl共有的方法,但是他是TControl的Protected方法,所以想走后门。
menxin 的做法可行,而且似乎没有什么副作用。

2 已经解决!要感谢Holly提供的关键思路,也就是利用ToolServices全局变量。
下面是我为类型为TCustomform的property提供的Property Editor.
TFormProperty = class(TPropertyEditor)
public
function GetAttributes: TPropertyAttributes; override;
function GetEditLimit: Integer; override;
function GetValue: string; override;
procedure GetValues(Proc: TGetStrProc); override;
procedure SetValue(const Value: string); override;
end;
{ TFormProperty }

function TFormProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paValueList, paSortList, paRevertable];
end;

function TFormProperty.GetEditLimit: Integer;
begin
Result:=127;
end;

function TFormProperty.GetValue: string;
begin
if GetOrdValue<>0 then
Result:=TCustomForm(GetOrdValue).Name
else
result:='';
end;

procedure TFormProperty.GetValues(Proc: TGetStrProc);
var
i:Integer;
s:string;
Form: TCustomForm;
begin
if not Assigned(ToolServices) then Exit;
for i:=0 to ToolServices.GetFormCount-1 do
begin
s:=ToolServices.GetFormName(i);
s:=Copy(s,1,Length(s)-3)+'pas';
if Assigned(ToolServices.GetModuleInterface(s)) then
Form:=ToolServices.GetModuleInterface(s).GetFormInterface.
GetFormComponent.GetComponentHandle;
if Assigned(Form) then
Proc(Form.name);
end;
end;

procedure TFormProperty.SetValue(const Value: string);
var
Form: TCustomForm;
s:string;
Found:Boolean;
I:Integer;
begin
if not Assigned(ToolServices) then Exit;
if Value = '' then
begin
Form := nil;
SetOrdValue(0);
Exit;
end
else
begin
Found:=false;
for i:=0 to ToolServices.GetFormCount-1 do
begin
s:=ToolServices.GetFormName(i);
s:=Copy(s,1,Length(s)-3)+'pas';
if Assigned(ToolServices.GetModuleInterface(s)) then
Form:=ToolServices.GetModuleInterface(s).GetFormInterface.
GetFormComponent.GetComponentHandle;
if Assigned(Form) then
if CompareText(Form.name,value)=0 then
begin
Found:=true;
Break;
end;
end;
if not Found then
raise EPropertyError.Create(SInvalidPropertyValue)
else SetOrdValue(Longint(Form));
end;
end;

程序还很粗,请多多指教!
 
据说别的单元的interface部分定义的类的protected部分可以直截访问,是delphi
的bug,我以没试过.
 
是本unit的其他类的protected部分可以直截访问。
 
多人接受答案了。
 
to tqz:对于第一个问题,可以更简便的调用Protected属性、方法。

1。声明一个类继承于你要访问的类,不写任何代码
2。在要用到某个Protected属性时候,先TypeCast成继承的类再使用

例如, 让DBGrid1有两个FixedCols:

TMyDBGrid = Class(TDBGrid);
...

procedure TForm1.FormCreate(sender: tobject);
begin
TMyDBGrid(DBGrid1).FixedCols := 2;
end;

 
顶部