Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.12.18;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.013 c
14-1132910088
Александр Иванов
2005-11-25 12:14
2005.12.18
Сверхурочная работа


2-1133349981
st_uzver
2005-11-30 14:26
2005.12.18
winexec


4-1129604342
Idx
2005-10-18 06:59
2005.12.18
Как добавить "LVS_..." style для ListView?


4-1129824721
Эксперт
2005-10-20 20:12
2005.12.18
Вставить и растянуть рисунок на фон ListView


2-1133445304
oleggar
2005-12-01 16:55
2005.12.18
word8





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский