Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.12.18;
Скачать: CL | DM;

Вниз

"свободный" кастинга типов?   Найти похожие ветки 

 
Frozzen   (2005-11-22 09:16) [0]

День добрый! Вопрос:
вот смотрте. есть два класса наследуемые от TWinControl, например, или еще от
какого общего класса.

Объекты классов имеют общее сво-во Text, причем в родительском классе такого
сво-ва нет.
Объекты передаются функции в качестве параметра. описание функции может быть
примерно такое
function BLABLABLA (var O : TObject); или (var O : TComponent);

так вот, как в этой функции сделать так, чтобы можно было менять значение
свойства Text не прибегая к конструкции вида
if O is SomeType then SomeType(O).Text:="blablabla";

дело в том, что в функцию передаются объекты с заведомо существующим
свойством Text, но их "тип" заранее неизвестен (много их может быть, в
общем, и проверка займет кучу строк для всех возможных типов)

и как можно в такой функции определить, есть ли у переданного объекта
такое-то свойство, и если есть то изменить его???


 
Digitman ©   (2005-11-22 09:25) [1]


> причем в родительском классе такого
> сво-ва нет


а почему бы не сделать это св-во у родителя ?

TMyBaseControl = class(TWinControl)
 function GetText: String; virtual; abstract;
 procedure SetText(Value: String); virtual; abstract;
..
 property Text: String read GetText write SetText;
..
end;

TMyBaseControlDescendant1 = class(TMyBaseControl)
..
 function GetText: String; override;
 procedure SetText(Value: String); override;
..
end;

TMyBaseControlDescendant2 = class(TMyBaseControl)
..
 function GetText: String; override;
 procedure SetText(Value: String); override;
..
end;

function BLABLABLA (Obj: TMyBaseControl);
begin
 obj.Text := "blablabla";
end;


 
evvcom ©   (2005-11-22 09:31) [2]

Смотри TypInfo.pas, в нем GetPropInfo, SetStrProp и другие


 
Frozzen   (2005-11-22 10:37) [3]

> почему бы не сделать это св-во у родителя ?

дело в том что они не напрямую идут от TWinControl. Это визуальные
компоненты. проще будет кучу if ... is ... then поставить

функция вызывается по событию именно вида (Sender : TObject)
могу ставить свой класс вместо TObject?


 
Digitman ©   (2005-11-22 10:44) [4]


> дело в том что они не напрямую идут от TWinControl


так ведь и в приведенном мной примере тоже не напрямую, а от общего предка, определившего св-во текст для любых потенциальных его наследников !


> функция вызывается по событию именно вида (Sender : TObject)


ну и что ?

мне непонятно, чем плох традиционный вариант :

if Sender is TMyBaseControl then
 TMyBaseControl(obj).Text := "blablabla";


 
Frozzen   (2005-11-22 10:56) [5]

В эту процедуру посылаются объекты как с наличием свойства текст так и без него, как определить есть ли у объекта это свойство или какого класса объект


 
Ega23 ©   (2005-11-22 10:59) [6]

Унаследуй все классы со свойством Text от одного предка. И потом на as проверяй.
В смысле на is.


 
Digitman ©   (2005-11-22 11:03) [7]


> как определить есть ли у объекта это свойство


для этого св-во должно быть published

при таком условии см. TypInfo.IsPublishedProp(Sender, "Text");


> какого класса объект


см. Sender.ClassName/ClassType


 
jack128 ©   (2005-11-22 11:13) [8]

type
 ITestControl = interface
 ["{61191874-1E23-4333-A3EC-5A87C85B2C86}"]
   function GetText: string;
   procedure SetText(const Value: string);
   property Text: string read GetText write SetText;
 end;


и реализовывать этот интерфейс, где тебе нужно.

Ну и в процедуре соответственно
var
 intf: ITextControl;
begin
 if Sender.GetIterface(ITextControl, intf) then
   intf.Text := "bla-bla-bla";
end;


 
Anatoly Podgoretsky ©   (2005-11-22 11:19) [9]

Frozzen   (22.11.05 09:16)  
Если по твоим утверждениям они наследуются от TWinControl, то дальнейшии утверждения неверны, поскольку данное свойство наследуется еще раньше от TControl.Text и оно опубликовано.


 
Anatoly Podgoretsky ©   (2005-11-22 11:21) [10]

Но если посмотреть внимательнее, то в некоторых местах справки ошибка, по одним сведеньям опубликовано, по другим в секции Protected


 
Frozzen   (2005-11-22 12:35) [11]

Но дело не упирается же в св-во Text! это только лишь как пример штоли.
Другими словами скажу,
JavaScript:

function setValue(Obj,Prp)
{       Obj[Prp]="blablabla";
}

если еще не совсем забыл синтаксис, то выглядит так. а вот как такое сделать на делфи, чтобы не быть привязанным к конкретному типу/классу при условии что породить наследника от класса с переопределенными свойствами нельзя?


 
Ega23 ©   (2005-11-22 12:40) [12]


> если еще не совсем забыл синтаксис, то выглядит так. а вот
> как такое сделать на делфи, чтобы не быть привязанным к
> конкретному типу/классу при условии что породить наследника
> от класса с переопределенными свойствами нельзя?


AFAIK, в java всю информацию о классе можно из RTTI получить.


 
Думкин ©   (2005-11-22 12:42) [13]

> Frozzen   (22.11.05 12:35) [11]

Тебе уже несколько раз сказали, что надо делать для published свойств.
Читать будешь?


 
Digitman ©   (2005-11-22 12:47) [14]


> Frozzen   (22.11.05 12:35) [11]


ты скажи по-русски - что ты хочешь-то ?

получив параметром некий объект обратиться к некоему потенциально ожидаемому св-ву этого объекта безо всяких проверок на класс объекта и на существование у него этого св-ва ?

не выполнять никаких приведений типов и при этом не ожидая от компилятора отлупа ?


 
Leonid Troyanovsky ©   (2005-11-22 12:49) [15]


> Frozzen   (22.11.05 09:16)  

> дело в том, что в функцию передаются объекты с заведомо
> существующим
> свойством Text, но их "тип" заранее неизвестен (много их
> может быть, в
> общем, и проверка займет кучу строк для всех возможных типов)


Если искомое (метод, свойство) заведомо находится в Protected,
например, Text, то:

type
 THackControl = class (TControl);

 if Sender is TControl then
  THackControl(Sender).Text := "New text";


--
Regards, LVT.


 
Ega23 ©   (2005-11-22 12:50) [16]


> Тебе уже несколько раз сказали, что надо делать для published
> свойств.


Не надо, а можно.


 
Frozzen   (2005-11-22 12:55) [17]

> Digitman©  (22.11.05 12:47) [14]

ДА


 
Digitman ©   (2005-11-22 13:04) [18]


> Frozzen   (22.11.05 12:55) [17]


тогда ты не тот огород окучиваешь.

олей-серверы автоматизации тебя спасут.


 
TUser ©   (2005-11-22 13:04) [19]

JavaScript, в отличае от Delphi проверит существование св-ва Text на стадии исполнения. Если такого нет - то вызовется исключение. А на паскале все проверяется заранее, токов язык. Как обойти такое требование уже сказали - используя механиз RTTI.


 
Digitman ©   (2005-11-22 13:11) [20]


> Leonid Troyanovsky ©   (22.11.05 12:49) [15]


да не хочет он никаких лишних телодвижений делать ! в том-то и соль) ..

он хочет, чтобы все по взмаху волшебной палочки само собой делалось, а ля

procedure TMyClass.OnSomeEvent(Sender: TSomeObject; ...) ;
begin
 try
   Sender.Text := "bla-bla-bla";
//все зашибись - я не знаю кто тако Sender, мне это по колено, но он точно имеет св-во Text, раз исключение не возникло
 except
//не все зашибись - Sender скорее всего не имеет св-ва Text, ну да и шут с ним
 end;
end;


 
Frozzen   (2005-11-22 13:13) [21]

:))


 
Digitman ©   (2005-11-22 13:20) [22]


> Frozzen   (22.11.05 13:13) [21]


сама собой только манна небесная на голову сваливается)... и то если только очень попросить известно кого)


 
Leonid Troyanovsky ©   (2005-11-22 13:24) [23]


> Digitman ©   (22.11.05 13:20) [22]

> сама собой только манна небесная на голову сваливается).
> .. и то если только очень попросить известно кого)


Для этого, IMHO, еще требуется быть известно кем.

--
Regards, LVT.


 
Frozzen   (2005-11-22 13:42) [24]

ну так бы сразу и сказали - НЕЗЯ батенька :) и все ок


 
evvcom ©   (2005-11-22 14:43) [25]


> ну так бы сразу и сказали - НЕЗЯ батенька :) и все ок

МОНА! Чукча не читатель, чукча писатель! См. [2] и [7] и делай выводы.


 
Экспериментатор   (2005-11-22 15:14) [26]

Давайте покажем лучше пример, чем столько спорить
сделать надо так:

procedure SetStringProperty(AComp: TComponent; APropName: String;
 AValue: String);
var
 PropInfo: PPropInfo;
 TK: TTypeKind;
begin
 PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
 if PropInfo <> nil then
 begin
   TK := PropInfo^.PropType^.Kind;
   if (TK = tkString) or (TK = tkLString) or (TK = tkWString) then
     SetStrProp(AComp, PropInfo, AValue);
 end;
end;

вызывай
SetStringProperty(MyWinCustomComponent, "Text", "Какой-то текст!!!");
и если свойство такое есть, оно установиться
Учите RTTI, батенька!  RTTI - это сила.


 
Экспериментатор   (2005-11-22 15:17) [27]

До кучи уж тогда:

procedure SetIntegerProperty(AComp: TComponent; APropName: String;
 AValue: Integer);
var
 PropInfo: PPropInfo;
begin
 PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
 if PropInfo <> nil then
 begin
   if PropInfo^.PropType^.Kind = tkInteger then
     SetOrdProp(AComp, PropInfo, AValue);
 end;
end;

procedure SetEnumProperty(AComp: TComponent; APropName: String;
 AValue: Integer);
var
 PropInfo: PPropInfo;
begin
 PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
 if PropInfo <> nil then
 begin
   if PropInfo^.PropType^.Kind = tkEnumeration then
     SetOrdProp(AComp, PropInfo, AValue);
 end;
end;

procedure SetObjectProperty(AComponent: TComponent; APropName: String;
 AValue: TObject);
var
 PropInfo: PPropInfo;
begin
 PropInfo := GetPropInfo(AComponent.ClassInfo, APropName);
 if PropInfo <> nil then
 begin
   if PropInfo^.PropType^.Kind = tkClass then
     SetObjectProp(AComponent, PropInfo, AValue);
 end;
end;

procedure SetBooleanProperty(AComp: TComponent; APropName: String;
 AValue: Boolean);
var
 PropInfo: PPropInfo;
begin
 PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
 if PropInfo <> nil then
 begin
   if PropInfo^.PropType^.Kind = tkEnumeration then
     SetOrdProp(AComp, PropInfo, Integer(AValue));
 end;
end;

procedure SetStringProperty(AComp: TComponent; APropName: String;
 AValue: String);
var
 PropInfo: PPropInfo;
 TK: TTypeKind;
begin
 PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
 if PropInfo <> nil then
 begin
   TK := PropInfo^.PropType^.Kind;
   if (TK = tkString) or (TK = tkLString) or (TK = tkWString) then
     SetStrProp(AComp, PropInfo, AValue);
 end;
end;

procedure SetMethodProperty(AComp: TComponent; APropName: String;
 AMethod: TMethod);
var
 PropInfo: PPropInfo;
begin
 PropInfo := GetPropInfo(AComp.ClassInfo, APropName);
 if PropInfo <> nil then
 begin
   if PropInfo^.PropType^.Kind = tkMethod then
     SetMethodProp(AComp, PropInfo, AMethod);
 end;
end;


Не забудьте TypInfo в uses добавить


 
Digitman ©   (2005-11-22 15:21) [28]


> Экспериментатор   (22.11.05 15:14) [26]


мессия прямо-таки)

вчитайся в

[14] -> [17]
[20] -> [21]

Автор палец о палец не хочет ударить, ему оно нафиг не надо, он хочет чтобы - хрясь ! - и само по себе произошло ..

а ты - "сделать надо так" да "Учите RTTI, батенька" ...)


 
Экспериментатор   (2005-11-22 15:34) [29]


> Frozzen   (22.11.05 10:56) [5]
> В эту процедуру посылаются объекты как с наличием свойства
> текст так и без него, как определить есть ли у объекта это
> свойство или какого класса объект


С другой стороны:
Каждый постебался как мог, а человек за помощью пришел.
Я ответил +/- километр на его вопрос,
если он ничего не хочет, дальше предложенного не пойдет.
А написаннное мной не поможет ему, так поможет другому.


 
Frozzen   (2005-11-22 18:16) [30]

спасибо Экспериментатор, ща почитаю

А я такое решение нашел:

procedure TMyClass.OnSomeEvent(Sender: TSomeObject; ...) ;
const PropertyName="Text";
begin
 try
   GetPropValue(Sender,PropertyName);

   //все зашибись - я не знаю кто тако Sender, мне это по колено, но
   //он точно имеет св-во Text, раз исключение не возникло
   SetPropValue(sender,ProperyName, "blablabla");
 except
   //не все зашибись - Sender скорее всего не имеет св-ва Text, ну да и шут с ним
   beep;
 end;

end;


 
Джо ©   (2005-11-22 18:19) [31]


> [30] Frozzen   (22.11.05 18:16)
> А я такое решение нашел:

А предварительно GetPropInfo вызвать не судьба?


 
Джо ©   (2005-11-22 18:21) [32]

Или, как уже писали выше, оболочку для нее - IsPublishedProp? Нафига тут какие-то экспепшены провоцировать?!


 
Frozzen   (2005-11-22 18:21) [33]

Ну да у тебя красивше, без эксепшенов работает
еще раз тебе спасибище Экспериментатор


 
Frozzen   (2005-11-22 18:23) [34]

>Или, как уже писали выше, оболочку для нее - IsPublishedProp
Я из написаного выше не понял ни про какую оболочку


 
Джо ©   (2005-11-22 18:25) [35]


>  [34] Frozzen   (22.11.05 18:23)
> >Или, как уже писали выше, оболочку для нее - IsPublishedProp
> Я из написаного выше не понял ни про какую оболочку

IsPublishedProp вызывает GetPropInfo  и сравнивает его с nil.


 
Frozzen   (2005-11-22 18:27) [36]

осознал чего писали
правдо не быстро


 
marbius   (2005-11-22 19:34) [37]

Во люди... Точно как хелп в делфи...Стока символов тока для того, чтобы человек сам нашел функцию через код библиотеки! И такие же как там, тока беглые ссылки на нее...


 
Джо ©   (2005-11-22 19:50) [38]


[37] marbius   (22.11.05 19:34)
> И такие же как там, тока беглые ссылки на нее...

Вы оплатите написание монографии?


 
Джо ©   (2005-11-22 19:52) [39]


> [37] marbius   (22.11.05 19:34)

А автору с самого начала просто ЗАВАЛИЛИ вариантами решения и советами. То, что он не смог их понять - чья вина в том?


 
evvcom ©   (2005-11-23 15:23) [40]


> То, что он не смог их понять - чья вина в том?

Не "не смог", а "не захотел". Это большая разница.



Страницы: 1 2 вся ветка

Текущий архив: 2005.12.18;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.031 c
11-1114235176
BelchonokH
2005-04-23 09:46
2005.12.18
Создание МСК компонентов из чисто КОЛовских


14-1132826938
ANB
2005-11-24 13:08
2005.12.18
Кому нужна программа автоматизированного тестирования ?


4-1129262049
Wood
2005-10-14 07:54
2005.12.18
звук модема на звуковую карту


14-1132723017
Джо
2005-11-23 08:16
2005.12.18
Google Base


2-1133341792
kizam
2005-11-30 12:09
2005.12.18
TButton