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

Вниз

Как идентифицировать объект по указателю на него ?   Найти похожие ветки 

 
msguns ©   (2005-07-22 15:20) [0]

На простом примере :
Есть процедура, которой передается указатель, куда надо положить некое число. Она должна определить, что "скрывается" под этим указателем. Если, например, это обект винкотрольный, то преобразовать число в строку и положить в св-во Text или Caption (в зависимомти от класса объекта), если строка - то просто положить туда. Если же Integer, то просто записать по этому адресу само число и т.д.

Благодарю всех участников.


 
Джо ©   (2005-07-22 15:21) [1]

В общем случае, имхо, никак.


 
Digitman ©   (2005-07-22 15:35) [2]

procedure (ptr: Pointer; Number: Integer);
begin
 try
   if TObject(ptr) is TSomeControl then
     begin
       TSomeControl(ptr).Text := IntToStr(Number);
       Exit;
     end;
 except
 end;

 try
   if TObject(ptr) is TSomeOtherControl then
     begin
       TSomeOtherControl(ptr).Text := IntToStr(Number);
       Exit;
     end;
 except
 end;

 try
   if строка then
     просто положить туда (черт-те что подразумевается под "строка" и "просто положить туда")
 except
 end;

 PInteger(ptr)^ := Number;
end;


 
Lamer@fools.ua ©   (2005-07-22 15:44) [3]

>Как идентифицировать объект по указателю на него ?

Либо пользоваться Variant"ами либо использовать технологии с поддержкой определения типа в ран-тайм (.NET, Java).


 
Digitman ©   (2005-07-22 15:47) [4]


> Lamer@fools.ua ©   (22.07.05 15:44) [3]


теже фаберже, но вид сбоку


 
msguns ©   (2005-07-22 15:49) [5]

>Digitman ©   (22.07.05 15:35) [2]

Ну, до метода научного тыка я бы и сам догадался ;))


 
Digitman ©   (2005-07-22 15:53) [6]


> msguns ©   (22.07.05 15:49) [5]


а тебя хак-методы интересуют ?)


 
msguns ©   (2005-07-22 16:04) [7]

>Digitman ©   (22.07.05 15:53) [6]
>а тебя хак-методы интересуют ?)

Меня интересует грамотно.
И красиво ;)


 
Digitman ©   (2005-07-22 16:20) [8]


> msguns ©   (22.07.05 16:04) [7]


тогда грамотно же и излагай суть вопроса.


> передается указатель


типизированный ? упоминай тип.
нетипизированный ? см. [1]


 
Джо ©   (2005-07-22 16:21) [9]


> [7] msguns ©   (22.07.05 16:04)
> Меня интересует грамотно.
> И красиво ;)

Для этого лучше всего грамотно подойти к проектированию алгоритма. Тогда и не будет нужды в хаках.


 
evvcom ©   (2005-07-22 16:24) [10]

Посмотри как работают функции New/Dispose с TypInfo.


 
oldman ©   (2005-07-22 16:33) [11]


> Есть процедура, которой передается указатель


А заодно и тип переменной передать?


 
Digitman ©   (2005-07-22 16:34) [12]


> evvcom ©   (22.07.05 16:24) [10]


не катит.
абсолютно.


 
Digitman ©   (2005-07-22 16:37) [13]


> процедура, которой передается указатель


мол, нА тебе, процедура, адрес, по этому адресу что-то там лежит, что конкретно - разбирайся сама, это твои проблемы..


 
Джо ©   (2005-07-22 16:39) [14]

Еще раз о

> Меня интересует грамотно.
> И красиво ;)
Обращение к области памяти, не зная, что в ней лежит (или не лежит) - само по себе так "некрасиво", что о каких уж тут красивых решениях может идти речь?.. Сорри за занудство, но может обрисуешь задачу?


 
evvcom ©   (2005-07-22 16:42) [15]


> не катит.
> абсолютно.

Ну так если вместе с указателем еще TypInfo передавать, должно ж прокатить? Хотя с тем же успехом можно и свой какой идентификатор передавать.
А вообще, конечно, задачи народ выдумывает странные. Я передал указатель, а ты попробуй угадай, что это?


 
Digitman ©   (2005-07-22 16:45) [16]


> evvcom ©   (22.07.05 16:42) [15]



> если вместе с указателем еще TypInfo передавать, должно
> ж прокатить?


да мало ли чего должно !

автор, как я понял, не желает передавать ничего иного, кроме как нетип.указатель


 
msguns ©   (2005-07-22 16:45) [17]

>oldman ©   (22.07.05 16:33) [11]
>А заодно и тип переменной передать?

Поясняю предмет.

procedure CalcAggregate(DataSet: TSQLDataSet; FieldList: TList; TargetValues: TList);

Процедура по переданному датасету строит запрос на вычисление агрегатов по полям, указанным в переданному же списку. Выполняет его и полученный результат должна положить по адресам, указанным в списке указателей, которые также передается. А вызывающая может дать ссылку на TEdit, TLabel, переменные типа Integer, double, string и т.д.


 
Digitman ©   (2005-07-22 16:50) [18]


> А вызывающая может дать ссылку на


а вызывающая ДОЛЖНА дать список ВАРИАНТОВ, а не список абстрактных указателей !

вот тогда и вопрос сам собой рассосется)


 
evvcom ©   (2005-07-22 16:52) [19]


> А вызывающая может дать ссылку на TEdit, TLabel, переменные
> типа Integer, double, string и т.д.

Ну так дай ссылку на record где присутствует информация о типе переменной.


 
msguns ©   (2005-07-22 16:53) [20]

>Digitman ©   (22.07.05 16:50) [18]
>а вызывающая ДОЛЖНА дать список ВАРИАНТОВ, а не список абстрактных указателей !

Можно примерчик. Как вызывающая сможет получить четыре числа:
одно в Эдите, второе в лабеле, третье как строку, а четвертое - как флоат. И как вызываемая со всех этой фигней разберется


 
msguns ©   (2005-07-22 16:55) [21]

>evvcom ©   (22.07.05 16:52) [19]
>Ну так дай ссылку на record где присутствует информация о типе переменной.

Ну какой же рекорд ? Процедура универсальная. К ней могут обращаться за получением как рдного агрегата, так и 100. И в абсолютно разные контролы или переменные.


 
DiamondShark ©   (2005-07-22 16:55) [22]

Не. Это фантастика.
Допустим, указатель на TEdit от TLabel отличить можно (хотя при выполнении кода, подобного [2] надо усиленно молиться). Но указатель на Integer отличить от указателя на Double -- унреально.


 
DiamondShark ©   (2005-07-22 16:58) [23]

Передавать массив обёрток, унаследованных от абстрактного класса -- и будет щасье.


 
Digitman ©   (2005-07-22 17:02) [24]


> Как вызывающая сможет получить четыре числа:
> одно в Эдите, второе в лабеле,


да нет там, ни в Эдите ни в лабеле, никаких "чисел" !)

и вообще это проблемы вызывающего кода - где, как и какими средствами он изобразит рез-т работы вызываемого кода

вызываемый же код в данном случае может (и, вероятно, должен) вернуть вариантный массив, с которым вызывающий код уже волен делать все что угодно - хоть в лабеле хоть не в лабеле рисовать результаты ..


 
reonid ©   (2005-07-22 17:02) [25]

Можно сделать что-нибудь типа этого:
(Подобной техникой я пользовался, когда мне надо было реализовать обобщённые алгоритмы)

type
 TAdapter = record
   SetValue: procedure(Value: Integer) of object;
 end;

implementation

{----}
procedure __SetInt(P: Pointer; Value: Integer);
begin
 PInteger(P)^ := Value;
end;

procedure __SetStr(P: Pointer; Value: Integer);
begin
 PString(P)^ := IntToStr(Value);
end;

procedure __SetWin(P: Pointer; Value: Integer);
begin
 if GetPropInfo(TWinControl(P), "Caption") <> nil then
   SetPropValue(TWinControl(P), "Caption", Value)
 else if GetPropInfo(TWinControl(P), "Text") <> nil then
   SetPropValue(TWinControl(P), "Text", Value)
end;

{-----}
function Adapter(var I: Integer): TAdapter; overload;
begin
 TMethod(Result.SetValue).Data := @I;
 TMethod(Result.SetValue).Code := @__SetInt;
end;

function Adapter(var S: string): TAdapter; overload;
begin
 TMethod(Result.SetValue).Data := @S;
 TMethod(Result.SetValue).Code := @__SetStr;
end;

function Adapter(Win: TWinControl): TAdapter; overload;
begin
 TMethod(Result.SetValue).Data := Pointer(Win);
 TMethod(Result.SetValue).Code := @__SetWin;
end;
{-----}

procedure Test(Adapters: array of TAdapter);
var i: Integer;
begin
 for i := 0 to High(Adapters) do
   Adapters[i].SetValue(6);
end;

procedure TForm1.FormCreate(Sender: TObject);
var I: Integer;
   s: string;
begin
 Test([Adapter(Self), Adapter(Panel1), Adapter(s), Adapter(I)]);
end;


 
evvcom ©   (2005-07-22 17:03) [26]


> Ну какой же рекорд ? Процедура универсальная. К ней могут
> обращаться за получением как рдного агрегата, так и 100.

А что массивы уже отменили? У меня, например, так работают процедуры/классы. И никаких проблем.


 
Digitman ©   (2005-07-22 17:12) [27]


> msguns ©   (22.07.05 16:45) [17]


и вообще - imho, крайне неразумно месить в функц-ти данной процедуры работу с СУБД и работу с виз.контролами

ну состряпай ты, коль приспичило, рекорд вида

TOutputKind = packed record
 Kind: TKind; // 0 - TLabel, 1 - TEdit, 2 - PInteger, 3 - еще чего-то
 ptr: Pointer; // поле Kind проинформирует, как с этим указателем обращаться
end;

и передай TList таких рекордов !


 
Anatoly Podgoretsky ©   (2005-07-22 19:48) [28]

msguns ©   (22.07.05 15:20)  
В указаной постановке забудь, как сказали это фантастика.


 
Mx ©   (2005-07-22 22:16) [29]

Я вот тоже много мудрил с подобными фишками. По нетипизированному указателю ты такого не получишь. Остается либо [27], либо [23]. Для меня последний вариант оказался наиболее удобным. В конце концов от использования объектов ты мало что потеряешь, зато многие механизмы станут доступными.


 
msguns ©   (2005-07-27 09:35) [30]

>Digitman ©   (22.07.05 17:12) [27]
>и вообще - imho, крайне неразумно месить в функц-ти данной процедуры работу с СУБД и работу с виз.контролами

Я ничего и не месю ;) Библиотека, которую я пишу, содержит универсальные модули обработки датасетов, как правило, отображаемых (фильтрации, сортировки, поиски, печати, модификации, агрегаты и т.д. посредством диалогов с пользователем). Как получен датасет (т.е. собственно "работа с СУБД") этим модулям (точнее, процедурам и функциям в этих модулях) фиолетово.

Спасибо за критику и советы.
Отдельное мерси reonid © и Digitman ©



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

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

Наверх




Память: 0.53 MB
Время: 0.011 c
14-1122011840
Kerk
2005-07-22 09:57
2005.08.14
С днем рождения! 22 июля


1-1122461038
chili
2005-07-27 14:43
2005.08.14
Подскажите почему не работает ExtractIcon


9-1113736502
Yegorchic
2005-04-17 15:15
2005.08.14
Поворот камеры


1-1122292466
Trenno
2005-07-25 15:54
2005.08.14
извлечение ZIP


1-1122108612
maximsm
2005-07-23 12:50
2005.08.14
idfrp.onprogress





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский